mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-06 07:20:50 +08:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3764adb7ef | ||
|
|
9160adb1cf | ||
|
|
3ebf4338ab | ||
|
|
2eb4b7b39b | ||
|
|
c241e49b48 | ||
|
|
238c881132 | ||
|
|
49dc733536 | ||
|
|
755bd78f60 | ||
|
|
77f80cd51f | ||
|
|
3df6000635 | ||
|
|
5efee2b40d | ||
|
|
f3c2e59184 | ||
|
|
24ab660e6e | ||
|
|
6c0a418068 | ||
|
|
07a180991e | ||
|
|
4732004b67 | ||
|
|
faa9cd0431 | ||
|
|
e0c3c2394d | ||
|
|
2dec584f54 | ||
|
|
5ab2ccae40 | ||
|
|
1017d08626 | ||
|
|
32b1bbd943 | ||
|
|
1abf31ffa5 | ||
|
|
aec60829d2 | ||
|
|
888c3c38c2 | ||
|
|
e2c4648037 | ||
|
|
f7b98c0530 | ||
|
|
d4bd3faa16 | ||
|
|
c4f3b1cd7b | ||
|
|
74add69a83 | ||
|
|
a490b19d24 | ||
|
|
44cfa2c1a2 | ||
|
|
6dd9522b3f | ||
|
|
5e352cb8e4 | ||
|
|
2fad7315b8 | ||
|
|
520759dfe8 | ||
|
|
577b44ae11 | ||
|
|
66f742d6c0 |
@@ -25,7 +25,7 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# set the project name
|
||||
project(cifpp VERSION 3.0.1 LANGUAGES CXX)
|
||||
project(cifpp VERSION 3.0.2 LANGUAGES CXX)
|
||||
|
||||
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
@@ -37,17 +37,16 @@ include(CheckIncludeFiles)
|
||||
include(CheckLibraryExists)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(Dart)
|
||||
include(FindFilesystem)
|
||||
include(GenerateExportHeader)
|
||||
|
||||
set(CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# https://stackoverflow.com/questions/63902528/program-crashes-when-filesystempath-is-destroyed
|
||||
find_package(Filesystem REQUIRED)
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
# https://stackoverflow.com/questions/63902528/program-crashes-when-filesystempath-is-destroyed
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
|
||||
elseif(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
@@ -122,22 +121,6 @@ if(MSVC)
|
||||
message(STATUS "The library and auxiliary files will be installed in $ENV{LOCALAPPDATA}/${PROJECT_NAME}")
|
||||
set(CMAKE_INSTALL_PREFIX "$ENV{LOCALAPPDATA}/${PROJECT_NAME}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
# Find out the processor type for the target
|
||||
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
|
||||
set(COFF_TYPE "x64")
|
||||
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386")
|
||||
set(COFF_TYPE "x86")
|
||||
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ARM64")
|
||||
set(COFF_TYPE "arm64")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported or unknown processor type ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
set(COFF_SPEC "--coff=${COFF_TYPE}")
|
||||
|
||||
# for mrc, just in case
|
||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{LOCALAPPDATA}/mrc")
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE AND NOT BUILD_FOR_CCP4 AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
@@ -151,12 +134,12 @@ endif()
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
message("Not using resources when building shared libraries for Windows")
|
||||
else()
|
||||
find_program(MRC mrc)
|
||||
find_package(Mrc)
|
||||
|
||||
if(MRC)
|
||||
option(CIFPP_USE_RSRC "Use mrc to create resources" ON)
|
||||
if(MRC_FOUND)
|
||||
option(USE_RSRC "Use mrc to create resources" ON)
|
||||
else()
|
||||
message("Using resources not possible since mrc was not found")
|
||||
message(WARNING "Not using resources since mrc was not found")
|
||||
endif()
|
||||
|
||||
if(CIFPP_USE_RSRC STREQUAL "ON")
|
||||
@@ -177,25 +160,18 @@ find_package(Boost 1.70.0 REQUIRED COMPONENTS system iostreams regex program_opt
|
||||
|
||||
if(NOT MSVC AND Boost_USE_STATIC_LIBS)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(BZip2 REQUIRED)
|
||||
list(APPEND CIFPP_REQUIRED_LIBRARIES ZLIB::ZLIB)
|
||||
endif()
|
||||
|
||||
include(FindFilesystem)
|
||||
list(APPEND CIFPP_REQUIRED_LIBRARIES ${STDCPPFS_LIBRARY})
|
||||
|
||||
include(FindAtomic)
|
||||
list(APPEND CIFPP_REQUIRED_LIBRARIES ${STDCPPATOMIC_LIBRARY})
|
||||
|
||||
# Create a revision file, containing the current git version info
|
||||
|
||||
include(GetGitRevisionDescription)
|
||||
option(GENERATE_CUSTOM_VERSION "Generate a custom version string" OFF)
|
||||
if(GIT-NOTFOUND OR HEAD-HASH-NOTFOUND OR NOT GENERATE_CUSTOM_VERSION)
|
||||
get_git_head_revision(REFSPEC COMMITHASH)
|
||||
|
||||
# Generate our own version string
|
||||
git_describe_working_tree(BUILD_VERSION_STRING --match=build --dirty)
|
||||
else()
|
||||
SET(BUILD_VERSION_STRING ${PROJECT_VERSION})
|
||||
endif()
|
||||
|
||||
# generate version.h
|
||||
string(TIMESTAMP BUILD_DATE_TIME "%Y-%m-%dT%H:%M:%SZ" UTC)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/src/revision.hpp.in" "${CMAKE_BINARY_DIR}/revision.hpp" @ONLY)
|
||||
include(VersionString)
|
||||
write_version_header("LibCIFPP")
|
||||
|
||||
# SymOp data table
|
||||
if(CIFPP_RECREATE_SYMOP_DATA)
|
||||
@@ -203,7 +179,7 @@ if(CIFPP_RECREATE_SYMOP_DATA)
|
||||
|
||||
add_executable(symop-map-generator "${CMAKE_SOURCE_DIR}/tools/symop-map-generator.cpp")
|
||||
|
||||
target_link_libraries(symop-map-generator Threads::Threads ${Boost_LIBRARIES} std::filesystem ${ZLIB_LIBRARIES} ${BZip2_LIBRARIES})
|
||||
target_link_libraries(symop-map-generator Threads::Threads ${Boost_LIBRARIES} ${CIFPP_REQUIRED_LIBRARIES})
|
||||
if(Boost_INCLUDE_DIR)
|
||||
target_include_directories(symop-map-generator PUBLIC ${Boost_INCLUDE_DIR})
|
||||
endif()
|
||||
@@ -274,7 +250,8 @@ target_include_directories(cifpp
|
||||
${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(cifpp Threads::Threads ${Boost_LIBRARIES} std::filesystem ${ZLIB_LIBRARIES} ${BZip2_LIBRARIES})
|
||||
target_link_libraries(cifpp PUBLIC Threads::Threads Boost::regex Boost::iostreams ${CIFPP_REQUIRED_LIBRARIES})
|
||||
# target_link_libraries(cifpp PRIVATE)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
target_link_options(cifpp PRIVATE -undefined dynamic_lookup)
|
||||
@@ -334,6 +311,13 @@ install(TARGETS cifpp
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
if(MSVC AND BUILD_SHARED_LIBS)
|
||||
install(
|
||||
FILES $<TARGET_PDB_FILE:${PROJECT_NAME}>
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
OPTIONAL)
|
||||
endif()
|
||||
|
||||
install(EXPORT cifppTargets
|
||||
FILE "cifppTargets.cmake"
|
||||
NAMESPACE cifpp::
|
||||
@@ -407,13 +391,6 @@ option(CIFPP_BUILD_TESTS "Build test exectuables" OFF)
|
||||
|
||||
if(CIFPP_BUILD_TESTS)
|
||||
|
||||
if(CIFPP_USE_RSRC)
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cifpp_test_rsrc.obj
|
||||
COMMAND ${MRC} -o ${CMAKE_CURRENT_BINARY_DIR}/cifpp_test_rsrc.obj ${CMAKE_SOURCE_DIR}/rsrc/mmcif_pdbx_v50.dic ${COFF_SPEC}
|
||||
)
|
||||
set(CIFPP_TEST_RESOURCE ${CMAKE_CURRENT_BINARY_DIR}/cifpp_test_rsrc.obj)
|
||||
endif()
|
||||
|
||||
list(APPEND CIFPP_tests
|
||||
# pdb2cif
|
||||
rename-compound
|
||||
@@ -424,15 +401,19 @@ if(CIFPP_BUILD_TESTS)
|
||||
set(CIFPP_TEST "${CIFPP_TEST}-test")
|
||||
set(CIFPP_TEST_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/test/${CIFPP_TEST}.cpp")
|
||||
|
||||
add_executable(${CIFPP_TEST} ${CIFPP_TEST_SOURCE} ${CIFPP_TEST_RESOURCE})
|
||||
add_executable(${CIFPP_TEST} ${CIFPP_TEST_SOURCE})
|
||||
|
||||
target_include_directories(${CIFPP_TEST} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_BINARY_DIR} # for config.h
|
||||
)
|
||||
|
||||
target_link_libraries(${CIFPP_TEST} PRIVATE Threads::Threads cifpp ${Boost_LIBRARIES} std::filesystem ${ZLIB_LIBRARIES} ${BZip2_LIBRARIES})
|
||||
|
||||
target_link_libraries(${CIFPP_TEST} PRIVATE Threads::Threads cifpp )
|
||||
|
||||
if(CIFPP_USE_RSRC)
|
||||
mrc_target_resources(${CIFPP_TEST} ${CMAKE_SOURCE_DIR}/rsrc/mmcif_pdbx_v50.dic)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
# Specify unwind semantics so that MSVC knowns how to handle exceptions
|
||||
target_compile_options(${CIFPP_TEST} PRIVATE /EHsc)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(Boost 1.70.0 REQUIRED COMPONENTS system iostreams regex program_options)
|
||||
find_dependency(Threads)
|
||||
find_dependency(Boost 1.70.0 REQUIRED COMPONENTS system iostreams regex)
|
||||
if(NOT WIN32)
|
||||
find_dependency(ZLIB)
|
||||
find_dependency(BZip2)
|
||||
endif()
|
||||
|
||||
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/cifppTargets.cmake")
|
||||
|
||||
13
changelog
13
changelog
@@ -1,3 +1,16 @@
|
||||
Version 3.0.3
|
||||
- Better configuration checks, for atomic e.g.
|
||||
- Fixed a problem introduced in refactoring mmcif::Atom
|
||||
- Version string creation
|
||||
|
||||
Version 3.0.2
|
||||
- refactored mmcif::Atom for performance reasons
|
||||
|
||||
Version 3.0.1
|
||||
- Fixed processing of proline restraints file from CCP4, proline
|
||||
is a peptide, really.
|
||||
- Added code to facilitate DSSP
|
||||
|
||||
Version 3.0.0
|
||||
- Replaced many strings in the API with string_view for
|
||||
performance reasons.
|
||||
|
||||
64
cmake/FindAtomic.cmake
Normal file
64
cmake/FindAtomic.cmake
Normal file
@@ -0,0 +1,64 @@
|
||||
# Simple check to see if we need a library for std::atomic
|
||||
|
||||
if(TARGET std::atomic)
|
||||
return()
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
include(CMakePushCheckState)
|
||||
include(CheckIncludeFileCXX)
|
||||
include(CheckCXXSourceRuns)
|
||||
|
||||
cmake_push_check_state()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
check_include_file_cxx("atomic" _CXX_ATOMIC_HAVE_HEADER)
|
||||
mark_as_advanced(_CXX_ATOMIC_HAVE_HEADER)
|
||||
|
||||
set(code [[
|
||||
#include <atomic>
|
||||
int main(int argc, char** argv) {
|
||||
std::atomic<long long> s;
|
||||
++s;
|
||||
return 0;
|
||||
}
|
||||
]])
|
||||
|
||||
check_cxx_source_runs("${code}" _CXX_ATOMIC_BUILTIN)
|
||||
|
||||
if(_CXX_ATOMIC_BUILTIN)
|
||||
set(_found 1)
|
||||
else()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES atomic)
|
||||
list(APPEND FOLLY_LINK_LIBRARIES atomic)
|
||||
|
||||
check_cxx_source_runs("${code}" _CXX_ATOMIC_LIB_NEEDED)
|
||||
if (NOT _CXX_ATOMIC_LIB_NEEDED)
|
||||
message(FATAL_ERROR "unable to link C++ std::atomic code: you may need \
|
||||
to install GNU libatomic")
|
||||
else()
|
||||
set(_found 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(_found)
|
||||
add_library(std::atomic INTERFACE IMPORTED)
|
||||
set_property(TARGET std::atomic APPEND PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_14)
|
||||
|
||||
if(_CXX_ATOMIC_BUILTIN)
|
||||
# Nothing to add...
|
||||
elseif(_CXX_ATOMIC_LIB_NEEDED)
|
||||
set_target_properties(std::atomic PROPERTIES IMPORTED_LIBNAME atomic)
|
||||
set(STDCPPATOMIC_LIBRARY atomic)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
cmake_pop_check_state()
|
||||
|
||||
set(Atomic_FOUND ${_found} CACHE BOOL "TRUE if we can run a program using std::atomic" FORCE)
|
||||
|
||||
if(Atomic_FIND_REQUIRED AND NOT Atomic_FOUND)
|
||||
message(FATAL_ERROR "Cannot run simple program using std::atomic")
|
||||
endif()
|
||||
@@ -59,8 +59,10 @@ if(_found)
|
||||
# Nothing to add...
|
||||
elseif(CXX_FILESYSTEM_STDCPPFS_NEEDED)
|
||||
set_target_properties(std::filesystem PROPERTIES IMPORTED_LIBNAME stdc++fs)
|
||||
set(STDCPPFS_LIBRARY stdc++fs)
|
||||
elseif(CXX_FILESYSTEM_CPPFS_NEEDED)
|
||||
set_target_properties(std::filesystem PROPERTIES IMPORTED_LIBNAME c++fs)
|
||||
set(STDCPPFS_LIBRARY c++fs)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
77
cmake/VersionString.cmake
Normal file
77
cmake/VersionString.cmake
Normal file
@@ -0,0 +1,77 @@
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
# Copyright (c) 2021 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.
|
||||
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
# Create a revision file, containing the current git version info, if any
|
||||
function(write_version_header)
|
||||
include(GetGitRevisionDescription)
|
||||
if(NOT(GIT-NOTFOUND OR HEAD-HASH-NOTFOUND))
|
||||
git_describe_working_tree(BUILD_VERSION_STRING --match=build --dirty)
|
||||
|
||||
if(BUILD_VERSION_STRING MATCHES "build-([0-9]+)-g([0-9a-f]+)(-dirty)?")
|
||||
set(BUILD_GIT_TAGREF "${CMAKE_MATCH_2}")
|
||||
if(CMAKE_MATCH_3)
|
||||
set(BUILD_VERSION_STRING "${CMAKE_MATCH_1}*")
|
||||
else()
|
||||
set(BUILD_VERSION_STRING "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
set(BUILD_VERSION_STRING "no git info available")
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR} PRIVATE)
|
||||
string(TIMESTAMP BUILD_DATE_TIME "%Y-%m-%dT%H:%M:%SZ" UTC)
|
||||
|
||||
if(ARGC GREATER 0)
|
||||
set(VAR_PREFIX "${ARGV0}")
|
||||
endif()
|
||||
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/revision.hpp.in" [[// Generated revision file
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
|
||||
const char k@VAR_PREFIX@ProjectName[] = "@PROJECT_NAME@";
|
||||
const char k@VAR_PREFIX@VersionNumber[] = "@PROJECT_VERSION@";
|
||||
const char k@VAR_PREFIX@VersionGitTag[] = "@BUILD_GIT_TAGREF@";
|
||||
const char k@VAR_PREFIX@BuildInfo[] = "@BUILD_VERSION_STRING@";
|
||||
const char k@VAR_PREFIX@BuildDate[] = "@BUILD_DATE_TIME@";
|
||||
|
||||
inline void write_version_string(std::ostream &os, bool verbose)
|
||||
{
|
||||
os << k@VAR_PREFIX@ProjectName << " version " << k@VAR_PREFIX@VersionNumber << std::endl;
|
||||
if (verbose)
|
||||
{
|
||||
os << "build: " << k@VAR_PREFIX@BuildInfo << ' ' << k@VAR_PREFIX@BuildDate << std::endl;
|
||||
if (k@VAR_PREFIX@VersionGitTag[0] != 0)
|
||||
os << "git tag: " << k@VAR_PREFIX@VersionGitTag << std::endl;
|
||||
}
|
||||
}
|
||||
]])
|
||||
configure_file("${CMAKE_BINARY_DIR}/revision.hpp.in" "${CMAKE_BINARY_DIR}/revision.hpp" @ONLY)
|
||||
endfunction()
|
||||
|
||||
@@ -792,7 +792,7 @@ class Row
|
||||
}
|
||||
|
||||
void assign(const std::vector<Item> &values);
|
||||
void assign(std::string_view name, const std::string &value, bool updateLinked);
|
||||
void assign(std::string_view name, const std::string &value, bool updateLinked, bool validate = true);
|
||||
|
||||
bool operator==(const Row &rhs) const
|
||||
{
|
||||
@@ -814,7 +814,7 @@ class Row
|
||||
friend std::ostream &operator<<(std::ostream &os, const Row &row);
|
||||
|
||||
private:
|
||||
void assign(size_t column, const std::string &value, bool updateLinked);
|
||||
void assign(size_t column, const std::string &value, bool updateLinked, bool validate = true);
|
||||
void assign(const Item &i, bool updateLinked);
|
||||
|
||||
static void swap(size_t column, ItemRow *a, ItemRow *b);
|
||||
@@ -2152,6 +2152,7 @@ class Category
|
||||
std::vector<ItemColumn> mColumns;
|
||||
ItemRow *mHead;
|
||||
ItemRow *mTail;
|
||||
size_t mLastUniqueNr = 0;
|
||||
class CatIndex *mIndex;
|
||||
|
||||
std::vector<Linked> mParentLinks, mChildLinks;
|
||||
|
||||
@@ -26,11 +26,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -371,8 +371,7 @@ auto DistancePointToLine(const PointF<F> &l1, const PointF<F> &l2, const PointF<
|
||||
// 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);
|
||||
Point Nudge(Point p, float offset);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// We use quaternions to do rotations in 3d space
|
||||
|
||||
@@ -184,6 +184,15 @@ class DSSP
|
||||
std::tuple<ResidueInfo,double> acceptor(int i) const;
|
||||
std::tuple<ResidueInfo,double> donor(int i) const;
|
||||
|
||||
/// \brief Simple compare equals
|
||||
bool operator==(const ResidueInfo &rhs) const
|
||||
{
|
||||
return mImpl == rhs.mImpl;
|
||||
}
|
||||
|
||||
/// \brief Returns \result true if there is a bond between two residues
|
||||
friend bool TestBond(ResidueInfo const &a, ResidueInfo const &b);
|
||||
|
||||
private:
|
||||
ResidueInfo(Res* res) : mImpl(res) {}
|
||||
|
||||
@@ -193,7 +202,7 @@ class DSSP
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = ResidueInfo;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type*;
|
||||
@@ -214,6 +223,14 @@ class DSSP
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
|
||||
@@ -60,30 +60,108 @@ class File;
|
||||
|
||||
class Atom
|
||||
{
|
||||
private:
|
||||
|
||||
struct AtomImpl : public std::enable_shared_from_this<AtomImpl>
|
||||
{
|
||||
AtomImpl(cif::Datablock &db, const std::string &id, cif::Row row);
|
||||
|
||||
// constructor for a symmetry copy of an atom
|
||||
AtomImpl(const AtomImpl &impl, const Point &loc, const std::string &sym_op);
|
||||
|
||||
AtomImpl(const AtomImpl &i) = default;
|
||||
|
||||
void prefetch();
|
||||
|
||||
int compare(const AtomImpl &b) const;
|
||||
|
||||
bool getAnisoU(float anisou[6]) const;
|
||||
|
||||
void moveTo(const Point &p);
|
||||
|
||||
const Compound &comp() const;
|
||||
|
||||
const std::string get_property(const std::string_view name) const;
|
||||
void set_property(const std::string_view name, const std::string &value);
|
||||
|
||||
const cif::Datablock &mDb;
|
||||
std::string mID;
|
||||
AtomType mType;
|
||||
|
||||
std::string mAtomID;
|
||||
std::string mCompID;
|
||||
std::string mAsymID;
|
||||
int mSeqID;
|
||||
std::string mAltID;
|
||||
std::string mAuthSeqID;
|
||||
|
||||
Point mLocation;
|
||||
int mRefcount;
|
||||
cif::Row mRow;
|
||||
|
||||
mutable std::vector<std::tuple<std::string,cif::detail::ItemReference>> mCachedRefs;
|
||||
|
||||
mutable const Compound *mCompound = nullptr;
|
||||
|
||||
bool mSymmetryCopy = false;
|
||||
bool mClone = false;
|
||||
|
||||
std::string mSymmetryOperator = "1_555";
|
||||
};
|
||||
|
||||
public:
|
||||
Atom();
|
||||
Atom(struct AtomImpl *impl);
|
||||
Atom(const Atom &rhs);
|
||||
|
||||
Atom() {}
|
||||
|
||||
Atom(std::shared_ptr<AtomImpl> impl)
|
||||
: mImpl(impl) {}
|
||||
|
||||
Atom(const Atom &rhs)
|
||||
: mImpl(rhs.mImpl) {}
|
||||
|
||||
Atom(cif::Datablock &db, cif::Row &row);
|
||||
|
||||
// a special constructor to create symmetry copies
|
||||
Atom(const Atom &rhs, const Point &symmmetry_location, const std::string &symmetry_operation);
|
||||
|
||||
~Atom();
|
||||
|
||||
explicit operator bool() const { return mImpl_ != nullptr; }
|
||||
explicit operator bool() const { return (bool)mImpl; }
|
||||
|
||||
// return a copy of this atom, with data copied instead of referenced
|
||||
Atom clone() const;
|
||||
Atom clone() const
|
||||
{
|
||||
auto copy = std::make_shared<AtomImpl>(*mImpl);
|
||||
copy->mClone = true;
|
||||
return Atom(copy);
|
||||
}
|
||||
|
||||
Atom &operator=(const Atom &rhs);
|
||||
Atom &operator=(const Atom &rhs) = default;
|
||||
|
||||
const std::string &id() const;
|
||||
AtomType type() const;
|
||||
template <typename T>
|
||||
T get_property(const std::string_view name) const;
|
||||
|
||||
Point location() const;
|
||||
void location(Point p);
|
||||
void set_property(const std::string_view name, const std::string &value)
|
||||
{
|
||||
if (not mImpl)
|
||||
throw std::logic_error("Error trying to modify an uninitialized atom");
|
||||
mImpl->set_property(name, value);
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
|
||||
void property(const std::string_view name, const T &value)
|
||||
{
|
||||
set_property(name, std::to_string(value));
|
||||
}
|
||||
|
||||
const std::string &id() const { return impl().mID; }
|
||||
AtomType type() const { return impl().mType; }
|
||||
|
||||
Point location() const { return impl().mLocation; }
|
||||
void location(Point p)
|
||||
{
|
||||
if (not mImpl)
|
||||
throw std::logic_error("Error trying to modify an uninitialized atom");
|
||||
mImpl->moveTo(p);
|
||||
}
|
||||
|
||||
/// \brief Translate the position of this atom by \a t
|
||||
void translate(Point t);
|
||||
@@ -91,47 +169,40 @@ class Atom
|
||||
/// \brief Rotate the position of this atom by \a q
|
||||
void rotate(Quaternion q);
|
||||
|
||||
/// \brief Translate and rotate the position of this atom by \a t and \a q
|
||||
void translateAndRotate(Point t, Quaternion q);
|
||||
|
||||
/// \brief Translate, rotate and translate again the coordinates this atom by \a t1 , \a q and \a t2
|
||||
void translateRotateAndTranslate(Point t1, Quaternion q, Point t2);
|
||||
|
||||
// for direct access to underlying data, be careful!
|
||||
const cif::Row getRow() const;
|
||||
const cif::Row getRow() const { return impl().mRow; }
|
||||
const cif::Row getRowAniso() const;
|
||||
|
||||
// Atom symmetryCopy(const Point& d, const clipper::RTop_orth& rt);
|
||||
bool isSymmetryCopy() const;
|
||||
std::string symmetry() const;
|
||||
// const clipper::RTop_orth& symop() const;
|
||||
bool isSymmetryCopy() const { return impl().mSymmetryCopy; }
|
||||
std::string symmetry() const { return impl().mSymmetryOperator; }
|
||||
|
||||
const Compound &comp() const;
|
||||
bool isWater() const;
|
||||
const Compound &comp() const { return impl().comp(); }
|
||||
bool isWater() const { return impl().mCompID == "HOH" or impl().mCompID == "H2O" or impl().mCompID == "WAT"; }
|
||||
int charge() const;
|
||||
|
||||
float uIso() const;
|
||||
bool getAnisoU(float anisou[6]) const;
|
||||
bool getAnisoU(float anisou[6]) const { return impl().getAnisoU(anisou); }
|
||||
float occupancy() const;
|
||||
|
||||
template <typename T>
|
||||
T property(const std::string_view name) const;
|
||||
|
||||
void property(const std::string_view name, const std::string &value);
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
|
||||
void property(const std::string_view name, const T &value)
|
||||
{
|
||||
property(name, std::to_string(value));
|
||||
}
|
||||
|
||||
// specifications
|
||||
std::string labelAtomID() const;
|
||||
std::string labelCompID() const;
|
||||
std::string labelAsymID() const;
|
||||
const std::string& labelAtomID() const { return impl().mAtomID; }
|
||||
const std::string& labelCompID() const { return impl().mCompID; }
|
||||
const std::string& labelAsymID() const { return impl().mAsymID; }
|
||||
std::string labelEntityID() const;
|
||||
int labelSeqID() const;
|
||||
std::string labelAltID() const;
|
||||
bool isAlternate() const;
|
||||
int labelSeqID() const { return impl().mSeqID; }
|
||||
const std::string& labelAltID() const { return impl().mAltID; }
|
||||
bool isAlternate() const { return not impl().mAltID.empty(); }
|
||||
|
||||
std::string authAtomID() const;
|
||||
std::string authCompID() const;
|
||||
std::string authAsymID() const;
|
||||
std::string authSeqID() const;
|
||||
const std::string& authSeqID() const { return impl().mAuthSeqID; }
|
||||
std::string pdbxAuthInsCode() const;
|
||||
std::string pdbxAuthAltID() const;
|
||||
|
||||
@@ -140,13 +211,6 @@ class Atom
|
||||
|
||||
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
|
||||
|
||||
// convenience routine
|
||||
@@ -158,10 +222,10 @@ class Atom
|
||||
|
||||
void swap(Atom &b)
|
||||
{
|
||||
std::swap(mImpl_, b.mImpl_);
|
||||
std::swap(mImpl, b.mImpl);
|
||||
}
|
||||
|
||||
int compare(const Atom &b) const;
|
||||
int compare(const Atom &b) const { return impl().compare(*b.mImpl); }
|
||||
|
||||
bool operator<(const Atom &rhs) const
|
||||
{
|
||||
@@ -172,14 +236,38 @@ class Atom
|
||||
|
||||
private:
|
||||
friend class Structure;
|
||||
|
||||
void setID(int id);
|
||||
|
||||
AtomImpl *impl();
|
||||
const AtomImpl *impl() const;
|
||||
const AtomImpl &impl() const
|
||||
{
|
||||
if (not mImpl)
|
||||
throw std::runtime_error("Uninitialized atom, not found?");
|
||||
return *mImpl;
|
||||
}
|
||||
|
||||
struct AtomImpl *mImpl_;
|
||||
std::shared_ptr<AtomImpl> mImpl;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline std::string Atom::get_property<std::string>(const std::string_view name) const
|
||||
{
|
||||
return impl().get_property(name);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int Atom::get_property<int>(const std::string_view name) const
|
||||
{
|
||||
auto v = impl().get_property(name);
|
||||
return v.empty() ? 0 : stoi(v);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float Atom::get_property<float>(const std::string_view name) const
|
||||
{
|
||||
return stof(impl().get_property(name));
|
||||
}
|
||||
|
||||
inline void swap(mmcif::Atom &a, mmcif::Atom &b)
|
||||
{
|
||||
a.swap(b);
|
||||
@@ -202,19 +290,16 @@ 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
|
||||
// constructor
|
||||
Residue(const Structure &structure, const std::string &compoundID,
|
||||
const std::string &asymID, const std::string &authSeqID);
|
||||
|
||||
// constructor for a residue without a sequence number
|
||||
Residue(const Structure &structure, const std::string &compoundID,
|
||||
const std::string &asymID);
|
||||
|
||||
// constructor for a residue with a sequence number
|
||||
Residue(const Structure &structure, const std::string &compoundID,
|
||||
const std::string &asymID, int seqID, const std::string &authSeqID);
|
||||
const std::string &asymID, int seqID = 0, const std::string &authSeqID = {})
|
||||
: mStructure(&structure)
|
||||
, mCompoundID(compoundID)
|
||||
, mAsymID(asymID)
|
||||
, mSeqID(seqID)
|
||||
, mAuthSeqID(authSeqID)
|
||||
{
|
||||
}
|
||||
|
||||
Residue(const Residue &rhs) = delete;
|
||||
Residue &operator=(const Residue &rhs) = delete;
|
||||
@@ -227,6 +312,11 @@ class Residue
|
||||
const Compound &compound() const;
|
||||
const AtomView &atoms() const;
|
||||
|
||||
void addAtom(const Atom &atom)
|
||||
{
|
||||
mAtoms.push_back(atom);
|
||||
}
|
||||
|
||||
/// \brief Unique atoms returns only the atoms without alternates and the first of each alternate atom id.
|
||||
AtomView unique_atoms() const;
|
||||
|
||||
@@ -277,6 +367,8 @@ class Residue
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Residue &res);
|
||||
|
||||
friend Structure;
|
||||
|
||||
protected:
|
||||
Residue() {}
|
||||
|
||||
@@ -481,6 +573,12 @@ class Structure
|
||||
/// \brief Get a the single residue for an asym with id \a asymID
|
||||
Residue &getResidue(const std::string &asymID);
|
||||
|
||||
/// \brief Get a the residue for atom \a atom
|
||||
Residue &getResidue(const mmcif::Atom &atom);
|
||||
|
||||
/// \brief Get a the residue for atom \a atom
|
||||
const Residue &getResidue(const mmcif::Atom &atom) const;
|
||||
|
||||
// map between auth and label locations
|
||||
|
||||
std::tuple<std::string, int, std::string> MapAuthToLabel(const std::string &asymID,
|
||||
@@ -521,6 +619,14 @@ class Structure
|
||||
/// \return The newly create asym ID
|
||||
std::string createNonpoly(const std::string &entity_id, const std::vector<mmcif::Atom> &atoms);
|
||||
|
||||
/// \brief Create a new NonPolymer struct_asym with atoms constructed from info in \a atom_info, returns asym_id.
|
||||
/// This method creates new atom records filled with info from the info.
|
||||
///
|
||||
/// \param entity_id The entity ID of the new nonpoly
|
||||
/// \param atoms The array of sets of cif::item data containing the data for the atoms.
|
||||
/// \return The newly create asym ID
|
||||
std::string createNonpoly(const std::string &entity_id, std::vector<std::vector<cif::Item>> &atom_info);
|
||||
|
||||
/// \brief 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();
|
||||
@@ -531,6 +637,12 @@ class Structure
|
||||
/// \brief Rotate the coordinates of all atoms in the structure by \a q
|
||||
void rotate(Quaternion t);
|
||||
|
||||
/// \brief Translate and rotate the coordinates of all atoms in the structure by \a t and \a q
|
||||
void translateAndRotate(Point t, Quaternion q);
|
||||
|
||||
/// \brief Translate, rotate and translate again the coordinates of all atoms in the structure by \a t1 , \a q and \a t2
|
||||
void translateRotateAndTranslate(Point t1, Quaternion q, Point t2);
|
||||
|
||||
const std::vector<Residue> &getNonPolymers() const { return mNonPolymers; }
|
||||
const std::vector<Residue> &getBranchResidues() const { return mBranchResidues; }
|
||||
|
||||
|
||||
@@ -180,7 +180,10 @@ bool CompoundBondMap::bonded(const std::string &compoundID, const std::string &a
|
||||
|
||||
auto compound = mmcif::CompoundFactory::instance().create(compoundID);
|
||||
if (not compound)
|
||||
std::cerr << "Missing compound bond info for " << compoundID << std::endl;
|
||||
{
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Missing compound bond info for " << compoundID << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto &atom : compound->bonds())
|
||||
@@ -308,7 +311,7 @@ BondMap::BondMap(const Structure &p)
|
||||
{
|
||||
if (c == "HOH" or c == "H2O" or c == "WAT")
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "skipping water in bond map calculation" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
285
src/Cif++.cpp
285
src/Cif++.cpp
@@ -1,17 +1,17 @@
|
||||
/*-
|
||||
* 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
|
||||
@@ -30,10 +30,10 @@
|
||||
#include <numeric>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <shared_mutex>
|
||||
#include <stack>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
@@ -570,36 +570,6 @@ void Datablock::write(std::ostream &os, const std::vector<std::string> &order)
|
||||
|
||||
cat.write(os);
|
||||
}
|
||||
|
||||
// // mmcif support, sort of. First write the 'entry' Category
|
||||
// // and if it exists, _AND_ we have a Validator, write out the
|
||||
// // auditConform record.
|
||||
//
|
||||
// for (auto& cat: mCategories)
|
||||
// {
|
||||
// if (cat.name() == "entry")
|
||||
// {
|
||||
// cat.write(os);
|
||||
//
|
||||
// if (mValidator != nullptr)
|
||||
// {
|
||||
// Category auditConform(*this, "audit_conform", nullptr);
|
||||
// auditConform.emplace({
|
||||
// { "dict_name", mValidator->dictName() },
|
||||
// { "dict_version", mValidator->dictVersion() }
|
||||
// });
|
||||
// auditConform.write(os);
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (auto& cat: mCategories)
|
||||
// {
|
||||
// if (cat.name() != "entry" and cat.name() != "audit_conform")
|
||||
// cat.write(os);
|
||||
// }
|
||||
}
|
||||
|
||||
bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
|
||||
@@ -636,15 +606,15 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
|
||||
{
|
||||
std::string nA = *catA_i;
|
||||
ba::to_lower(nA);
|
||||
|
||||
|
||||
std::string nB = *catB_i;
|
||||
ba::to_lower(nB);
|
||||
|
||||
|
||||
int d = nA.compare(nB);
|
||||
if (d > 0)
|
||||
{
|
||||
auto cat = dbB.get(*catB_i);
|
||||
|
||||
|
||||
if (cat == nullptr)
|
||||
missingA.push_back(*catB_i);
|
||||
|
||||
@@ -653,7 +623,7 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
|
||||
else if (d < 0)
|
||||
{
|
||||
auto cat = dbA.get(*catA_i);
|
||||
|
||||
|
||||
if (cat == nullptr)
|
||||
missingB.push_back(*catA_i);
|
||||
|
||||
@@ -662,25 +632,25 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
|
||||
else
|
||||
++catA_i, ++catB_i;
|
||||
}
|
||||
|
||||
|
||||
while (catA_i != catA.end())
|
||||
missingB.push_back(*catA_i++);
|
||||
|
||||
while (catB_i != catB.end())
|
||||
missingA.push_back(*catB_i++);
|
||||
|
||||
if (not (missingA.empty() and missingB.empty()))
|
||||
if (not(missingA.empty() and missingB.empty()))
|
||||
{
|
||||
if (cif::VERBOSE > 1)
|
||||
{
|
||||
std::cerr << "compare of datablocks failed" << std::endl;
|
||||
if (not missingA.empty())
|
||||
std::cerr << "Categories missing in A: " << ba::join(missingA, ", ") << std::endl
|
||||
<< std::endl;
|
||||
|
||||
<< std::endl;
|
||||
|
||||
if (not missingB.empty())
|
||||
std::cerr << "Categories missing in B: " << ba::join(missingB, ", ") << std::endl
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
|
||||
result = false;
|
||||
}
|
||||
@@ -706,7 +676,7 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
|
||||
++catA_i;
|
||||
else
|
||||
{
|
||||
if (not (*dbA.get(*catA_i) == *dbB.get(*catB_i)))
|
||||
if (not(*dbA.get(*catA_i) == *dbB.get(*catB_i)))
|
||||
{
|
||||
if (cif::VERBOSE > 1)
|
||||
{
|
||||
@@ -724,10 +694,10 @@ bool operator==(const cif::Datablock &dbA, const cif::Datablock &dbB)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream &os, const Datablock &data)
|
||||
std::ostream &operator<<(std::ostream &os, const Datablock &data)
|
||||
{
|
||||
// whoohoo... this sucks!
|
||||
const_cast<Datablock&>(data).write(os);
|
||||
const_cast<Datablock &>(data).write(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
@@ -1162,7 +1132,7 @@ void CatIndex::reconstruct()
|
||||
insert(r.mData);
|
||||
|
||||
// maybe reconstruction can be done quicker by using the following commented code.
|
||||
// however, I've not had the time to think of a way to std::set the red/black flag correctly in that case.
|
||||
// however, I've not had the time to think of a way to set the red/black flag correctly in that case.
|
||||
|
||||
// std::vector<ItemRow*> rows;
|
||||
// transform(mCat.begin(), mCat.end(), backInserter(rows),
|
||||
@@ -1254,82 +1224,15 @@ size_t CatIndex::size() const
|
||||
return result;
|
||||
}
|
||||
|
||||
//bool CatIndex::isValid() const
|
||||
//{
|
||||
// bool result = true;
|
||||
//
|
||||
// if (mRoot != nullptr)
|
||||
// {
|
||||
// uint32_t minBlack = numeric_limits<uint32_t>::max();
|
||||
// uint32_t maxBlack = 0;
|
||||
//
|
||||
// assert(not mRoot->mRed);
|
||||
//
|
||||
// result = isValid(mRoot, false, 0, minBlack, maxBlack);
|
||||
// assert(minBlack == maxBlack);
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
//}
|
||||
//
|
||||
//bool CatIndex::validate(entry* h, bool isParentRed, uint32_t blackDepth, uint32_t& minBlack, uint32_t& maxBlack) const
|
||||
//{
|
||||
// bool result = true;
|
||||
//
|
||||
// if (h->mRed)
|
||||
// assert(not isParentRed);
|
||||
// else
|
||||
// ++blackDepth;
|
||||
//
|
||||
// if (isParentRed)
|
||||
// assert(not h->mRed);
|
||||
//
|
||||
// if (h->mLeft != nullptr and h->mRight != nullptr)
|
||||
// {
|
||||
// if (isRed(h->mLeft))
|
||||
// assert(not isRed(h->mRight));
|
||||
// if (isRed(h->mRight))
|
||||
// assert(not isRed(h->mLeft));
|
||||
// }
|
||||
//
|
||||
// if (h->mLeft != nullptr)
|
||||
// {
|
||||
// assert(mComp(h->mLeft->mRow, h->mRow) < 0);
|
||||
// validate(h->mLeft, h->mRed, blackDepth, minBlack, maxBlack);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (minBlack > blackDepth)
|
||||
// minBlack = blackDepth;
|
||||
// if (maxBlack < blackDepth)
|
||||
// maxBlack = blackDepth;
|
||||
// }
|
||||
//
|
||||
// if (h->mRight != nullptr)
|
||||
// {
|
||||
// assert(mComp(h->mRight->mRow, h->mRow) > 0);
|
||||
// validate(h->mRight, h->mRight, blackDepth, minBlack, maxBlack);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (minBlack > blackDepth)
|
||||
// minBlack = blackDepth;
|
||||
// if (maxBlack < blackDepth)
|
||||
// maxBlack = blackDepth;
|
||||
// }
|
||||
//}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
RowSet::RowSet(Category &cat)
|
||||
: mCat(&cat)
|
||||
// , mCond(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
RowSet::RowSet(Category &cat, Condition &&cond)
|
||||
: mCat(&cat)
|
||||
// , mCond(new Condition(std::forward<Condition>(cond)))
|
||||
{
|
||||
cond.prepare(cat);
|
||||
|
||||
@@ -1343,21 +1246,17 @@ RowSet::RowSet(Category &cat, Condition &&cond)
|
||||
RowSet::RowSet(const RowSet &rhs)
|
||||
: mCat(rhs.mCat)
|
||||
, mItems(rhs.mItems)
|
||||
// , mCond(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
RowSet::RowSet(RowSet &&rhs)
|
||||
: mCat(rhs.mCat)
|
||||
, mItems(std::move(rhs.mItems))
|
||||
// , mCond(rhs.mCond)
|
||||
{
|
||||
// rhs.mCond = nullptr;
|
||||
}
|
||||
|
||||
RowSet::~RowSet()
|
||||
{
|
||||
// delete mCond;
|
||||
}
|
||||
|
||||
RowSet &RowSet::operator=(const RowSet &rhs)
|
||||
@@ -1469,7 +1368,7 @@ void Category::updateLinks()
|
||||
auto childCat = mDb.get(link->mChildCategory);
|
||||
if (childCat == nullptr)
|
||||
continue;
|
||||
mChildLinks.push_back({ childCat, link });
|
||||
mChildLinks.push_back({childCat, link});
|
||||
}
|
||||
|
||||
for (auto link : mValidator->getLinksForChild(mName))
|
||||
@@ -1477,7 +1376,7 @@ void Category::updateLinks()
|
||||
auto parentCat = mDb.get(link->mParentCategory);
|
||||
if (parentCat == nullptr)
|
||||
continue;
|
||||
mParentLinks.push_back({ parentCat, link });
|
||||
mParentLinks.push_back({parentCat, link});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1497,7 +1396,7 @@ size_t Category::getColumnIndex(std::string_view name) const
|
||||
break;
|
||||
}
|
||||
|
||||
if (VERBOSE and result == mColumns.size() and mCatValidator != nullptr) // validate the name, if it is known at all (since it was not found)
|
||||
if (VERBOSE > 0 and result == mColumns.size() and mCatValidator != nullptr) // validate the name, if it is known at all (since it was not found)
|
||||
{
|
||||
auto iv = mCatValidator->getValidatorForItem(name);
|
||||
if (iv == nullptr)
|
||||
@@ -1543,21 +1442,6 @@ size_t Category::addColumn(std::string_view name)
|
||||
return result;
|
||||
}
|
||||
|
||||
// RowSet Category::find(Condition&& cond)
|
||||
// {
|
||||
// RowSet result(*this);
|
||||
|
||||
// cond.prepare(*this);
|
||||
|
||||
// for (auto r: *this)
|
||||
// {
|
||||
// if (cond(*this, r))
|
||||
// result.push_back(r);
|
||||
// }
|
||||
|
||||
// return result;
|
||||
// }
|
||||
|
||||
void Category::reorderByIndex()
|
||||
{
|
||||
if (mIndex != nullptr)
|
||||
@@ -1601,11 +1485,13 @@ std::string Category::getUniqueID(std::function<std::string(int)> generator)
|
||||
if (mCatValidator != nullptr and mCatValidator->mKeys.size() == 1)
|
||||
key = mCatValidator->mKeys.front();
|
||||
|
||||
size_t nr = size();
|
||||
// calling size() often is a waste of resources
|
||||
if (mLastUniqueNr == 0)
|
||||
mLastUniqueNr = size();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
std::string result = generator(int(nr++));
|
||||
std::string result = generator(static_cast<int>(mLastUniqueNr++));
|
||||
|
||||
if (exists(Key(key) == result))
|
||||
continue;
|
||||
@@ -1665,21 +1551,6 @@ Row Category::operator[](Condition &&cond)
|
||||
return result;
|
||||
}
|
||||
|
||||
// RowSet Category::find(Condition&& cond)
|
||||
// {
|
||||
// // return RowSet(*this, std::forward<Condition>(cond));
|
||||
// RowSet result(*this);
|
||||
|
||||
// cond.prepare(*this);
|
||||
|
||||
// for (auto r: *this)
|
||||
// {
|
||||
// if (cond(*this, r))
|
||||
// result.insert(result.end(), r);
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
bool Category::exists(Condition &&cond) const
|
||||
{
|
||||
bool result = false;
|
||||
@@ -2340,7 +2211,7 @@ void Category::validateLinks() const
|
||||
if (not hasParent(r, *parentCat, *link))
|
||||
++missing;
|
||||
|
||||
if (missing)
|
||||
if (missing and VERBOSE >= 0)
|
||||
{
|
||||
std::cerr << "Links for " << link->mLinkGroupLabel << " are incomplete" << std::endl
|
||||
<< " There are " << missing << " items in " << mName << " that don't have matching parent items in " << parentCat->mName << std::endl;
|
||||
@@ -2408,26 +2279,26 @@ std::set<size_t> Category::keyFieldsByIndex() const
|
||||
|
||||
bool operator==(const Category &a, const Category &b)
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
using namespace std::placeholders;
|
||||
|
||||
bool result = true;
|
||||
|
||||
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
|
||||
//
|
||||
// if (tagsA != tagsB)
|
||||
// std::cout << "Unequal number of fields" << std::endl;
|
||||
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
|
||||
//
|
||||
// if (tagsA != tagsB)
|
||||
// std::cout << "Unequal number of fields" << std::endl;
|
||||
|
||||
auto& validator = a.getValidator();
|
||||
auto &validator = a.getValidator();
|
||||
auto catValidator = validator.getValidatorForCategory(a.name());
|
||||
if (catValidator == nullptr)
|
||||
throw std::runtime_error("missing cat validator");
|
||||
|
||||
typedef std::function<int(const char*,const char*)> compType;
|
||||
std::vector<std::tuple<std::string,compType>> tags;
|
||||
|
||||
typedef std::function<int(const char *, const char *)> compType;
|
||||
std::vector<std::tuple<std::string, compType>> tags;
|
||||
auto keys = catValidator->mKeys;
|
||||
std::vector<size_t> keyIx;
|
||||
|
||||
for (auto& tag: a.fields())
|
||||
|
||||
for (auto &tag : a.fields())
|
||||
{
|
||||
auto iv = catValidator->getValidatorForItem(tag);
|
||||
if (iv == nullptr)
|
||||
@@ -2436,24 +2307,25 @@ bool operator==(const Category &a, const Category &b)
|
||||
if (tv == nullptr)
|
||||
throw std::runtime_error("missing type validator");
|
||||
tags.push_back(std::make_tuple(tag, std::bind(&cif::ValidateType::compare, tv, std::placeholders::_1, std::placeholders::_2)));
|
||||
|
||||
auto pred = [tag](const std::string& s) -> bool { return cif::iequals(tag, s) == 0; };
|
||||
|
||||
auto pred = [tag](const std::string &s) -> bool
|
||||
{ return cif::iequals(tag, s) == 0; };
|
||||
if (find_if(keys.begin(), keys.end(), pred) == keys.end())
|
||||
keyIx.push_back(tags.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
// a.reorderByIndex();
|
||||
// b.reorderByIndex();
|
||||
|
||||
auto rowEqual = [&](const cif::Row& ra, const cif::Row& rb)
|
||||
|
||||
auto rowEqual = [&](const cif::Row &ra, const cif::Row &rb)
|
||||
{
|
||||
int d = 0;
|
||||
|
||||
for (auto kix: keyIx)
|
||||
for (auto kix : keyIx)
|
||||
{
|
||||
std::string tag;
|
||||
compType compare;
|
||||
|
||||
|
||||
std::tie(tag, compare) = tags[kix];
|
||||
|
||||
d = compare(ra[tag].c_str(), rb[tag].c_str());
|
||||
@@ -2465,7 +2337,7 @@ bool operator==(const Category &a, const Category &b)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return d == 0;
|
||||
};
|
||||
|
||||
@@ -2483,9 +2355,9 @@ bool operator==(const Category &a, const Category &b)
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
cif::Row ra = *ai, rb = *bi;
|
||||
|
||||
|
||||
if (not rowEqual(ra, rb))
|
||||
{
|
||||
if (cif::VERBOSE > 1)
|
||||
@@ -2493,21 +2365,25 @@ bool operator==(const Category &a, const Category &b)
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> missingA, missingB, different;
|
||||
|
||||
for (auto& tt: tags)
|
||||
|
||||
for (auto &tt : tags)
|
||||
{
|
||||
std::string tag;
|
||||
compType compare;
|
||||
|
||||
|
||||
std::tie(tag, compare) = tt;
|
||||
|
||||
|
||||
// make it an option to compare unapplicable to empty or something
|
||||
|
||||
const char* ta = ra[tag].c_str(); if (strcmp(ta, ".") == 0 or strcmp(ta, "?") == 0) ta = "";
|
||||
const char* tb = rb[tag].c_str(); if (strcmp(tb, ".") == 0 or strcmp(tb, "?") == 0) tb = "";
|
||||
|
||||
|
||||
const char *ta = ra[tag].c_str();
|
||||
if (strcmp(ta, ".") == 0 or strcmp(ta, "?") == 0)
|
||||
ta = "";
|
||||
const char *tb = rb[tag].c_str();
|
||||
if (strcmp(tb, ".") == 0 or strcmp(tb, "?") == 0)
|
||||
tb = "";
|
||||
|
||||
if (compare(ta, tb) != 0)
|
||||
{
|
||||
if (cif::VERBOSE > 1)
|
||||
@@ -2519,7 +2395,7 @@ bool operator==(const Category &a, const Category &b)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
++ai;
|
||||
++bi;
|
||||
}
|
||||
@@ -2527,18 +2403,6 @@ bool operator==(const Category &a, const Category &b)
|
||||
return result;
|
||||
}
|
||||
|
||||
// auto Category::iterator::operator++() -> iterator&
|
||||
// {
|
||||
// mCurrent = Row(mCurrent.data()->mNext);
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
// auto Category::const_iterator::operator++() -> const_iterator&
|
||||
// {
|
||||
// mCurrent = Row(mCurrent.data()->mNext);
|
||||
// return *this;
|
||||
// }
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@@ -2900,7 +2764,7 @@ void Category::update_value(RowSet &&rows, const std::string &tag, const std::st
|
||||
}
|
||||
|
||||
// cannot update this...
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Cannot update child " << childCat->mName << "." << childTag << " with value " << value << std::endl;
|
||||
}
|
||||
|
||||
@@ -3009,21 +2873,22 @@ void Row::assign(const Item &value, bool skipUpdateLinked)
|
||||
assign(value.name(), value.value(), skipUpdateLinked);
|
||||
}
|
||||
|
||||
void Row::assign(std::string_view name, const std::string &value, bool skipUpdateLinked)
|
||||
void Row::assign(std::string_view name, const std::string &value, bool skipUpdateLinked, bool validate)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto cat = mData->mCategory;
|
||||
assign(cat->addColumn(name), value, skipUpdateLinked);
|
||||
assign(cat->addColumn(name), value, skipUpdateLinked, validate);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::cerr << "Could not assign value '" << value << "' to column _" << mData->mCategory->name() << '.' << name << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Could not assign value '" << value << "' to column _" << mData->mCategory->name() << '.' << name << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void Row::assign(size_t column, const std::string &value, bool skipUpdateLinked)
|
||||
void Row::assign(size_t column, const std::string &value, bool skipUpdateLinked, bool validate)
|
||||
{
|
||||
if (mData == nullptr)
|
||||
throw std::logic_error("invalid Row, no data assigning value '" + value + "' to column with index " + std::to_string(column));
|
||||
@@ -3049,7 +2914,7 @@ void Row::assign(size_t column, const std::string &value, bool skipUpdateLinked)
|
||||
std::string oldStrValue = oldValue ? oldValue : "";
|
||||
|
||||
// check the value
|
||||
if (col.mValidator)
|
||||
if (col.mValidator and validate)
|
||||
(*col.mValidator)(value);
|
||||
|
||||
// If the field is part of the Key for this Category, remove it from the index
|
||||
@@ -3181,7 +3046,7 @@ void Row::assign(size_t column, const std::string &value, bool skipUpdateLinked)
|
||||
auto rows_n = childCat->find(std::move(cond_n));
|
||||
if (not rows_n.empty())
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Will not rename in child category since there are already rows that link to the parent" << std::endl;
|
||||
|
||||
continue;
|
||||
@@ -3387,7 +3252,7 @@ void Row::swap(size_t cix, ItemRow *a, ItemRow *b)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (VERBOSE)
|
||||
if (VERBOSE > 0)
|
||||
std::cerr << "In " << childCat->mName << " changing " << linkChildColName << ": " << r[linkChildColName].as<std::string>() << " => " << (i ? i->mText : "") << std::endl;
|
||||
r[linkChildColName] = i ? i->mText : "";
|
||||
}
|
||||
@@ -3496,7 +3361,8 @@ File::File(const std::filesystem::path &path, bool validate)
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::cerr << "Error while loading file " << path << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Error while loading file " << path << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -3564,7 +3430,8 @@ void File::load(const std::filesystem::path &p)
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::cerr << "Error loading file " << path << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Error loading file " << path << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -3660,7 +3527,7 @@ bool File::isValid()
|
||||
{
|
||||
if (mValidator == nullptr)
|
||||
{
|
||||
if (VERBOSE)
|
||||
if (VERBOSE > 0)
|
||||
std::cerr << "No dictionary loaded explicitly, loading default" << std::endl;
|
||||
|
||||
loadDictionary();
|
||||
|
||||
@@ -753,7 +753,8 @@ class Ff : public FBase
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::cerr << "Failed to write '" << s << "' as a double, this indicates an error in the code for writing PDB files" << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Failed to write '" << s << "' as a double, this indicates an error in the code for writing PDB files" << std::endl;
|
||||
os << s;
|
||||
}
|
||||
}
|
||||
@@ -2329,7 +2330,8 @@ void WriteRemark200(std::ostream& pdbFile, Datablock& db)
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::cerr << ex.what() << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2390,7 +2392,8 @@ void WriteRemark280(std::ostream& pdbFile, Datablock& db)
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::cerr << ex.what() << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ SacParser::CIFToken SacParser::getNextToken()
|
||||
mState = eStateTextField + 1;
|
||||
else if (ch == kEOF)
|
||||
error("unterminated textfield");
|
||||
else if (not isAnyPrint(ch))
|
||||
else if (not isAnyPrint(ch) and cif::VERBOSE >= 0)
|
||||
// error("invalid character in text field '" + string({ static_cast<char>(ch) }) + "' (" + to_string((int)ch) + ")");
|
||||
std::cerr << "invalid character in text field '" << std::string({static_cast<char>(ch)}) << "' (" << ch << ") line: " << mLineNr << std::endl;
|
||||
break;
|
||||
@@ -1220,7 +1220,7 @@ void DictParser::linkItems()
|
||||
{
|
||||
for (auto &iv : cv.mItemValidators)
|
||||
{
|
||||
if (iv.mType == nullptr)
|
||||
if (iv.mType == nullptr and cif::VERBOSE >= 0)
|
||||
std::cerr << "Missing item_type for " << iv.mTag << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -1255,7 +1255,8 @@ void DictParser::loadDictionary()
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
std::cerr << "Error parsing dictionary" << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Error parsing dictionary" << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,19 +25,14 @@
|
||||
*/
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define TERM_WIDTH 80
|
||||
@@ -50,6 +45,8 @@
|
||||
|
||||
#include "cif++/CifUtils.hpp"
|
||||
|
||||
#include "revision.hpp"
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -64,39 +61,9 @@ extern int VERBOSE;
|
||||
|
||||
std::string get_version_nr()
|
||||
{
|
||||
const std::regex
|
||||
rxVersionNr1(R"(build-(\d+)-g[0-9a-f]{7}(-dirty)?)"),
|
||||
rxVersionNr2(R"(libcifpp-version: (\d+\.\d+\.\d+))");
|
||||
|
||||
#include "revision.hpp"
|
||||
|
||||
struct membuf : public std::streambuf
|
||||
{
|
||||
membuf(char *data, size_t length) { this->setg(data, data, data + length); }
|
||||
} buffer(const_cast<char *>(kRevision), sizeof(kRevision));
|
||||
|
||||
std::istream is(&buffer);
|
||||
|
||||
std::string line, result;
|
||||
|
||||
while (getline(is, line))
|
||||
{
|
||||
std::smatch m;
|
||||
|
||||
if (std::regex_match(line, m, rxVersionNr1))
|
||||
{
|
||||
result = m[1];
|
||||
if (m[2].matched)
|
||||
result += '*';
|
||||
break;
|
||||
}
|
||||
|
||||
// always the first, replace with more specific if followed by the other info
|
||||
if (std::regex_match(line, m, rxVersionNr2))
|
||||
result = m[1];
|
||||
}
|
||||
|
||||
return result;
|
||||
std::ostringstream s;
|
||||
write_version_string(s, false);
|
||||
return s.str();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -1237,7 +1204,7 @@ std::filesystem::path gDataDir;
|
||||
|
||||
void addDataDirectory(std::filesystem::path dataDir)
|
||||
{
|
||||
if (VERBOSE and not fs::exists(dataDir))
|
||||
if (VERBOSE > 0 and not fs::exists(dataDir))
|
||||
std::cerr << "The specified data directory " << dataDir << " does not exist" << std::endl;
|
||||
gDataDir = dataDir;
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ void Validator::reportError(const std::string &msg, bool fatal) const
|
||||
{
|
||||
if (mStrict or fatal)
|
||||
throw ValidationError(msg);
|
||||
else if (VERBOSE)
|
||||
else if (VERBOSE > 0)
|
||||
std::cerr << msg << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ Compound::Compound(cif::Datablock &db, const std::string &id, const std::string
|
||||
bond.type = BondType::delo;
|
||||
else
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Unimplemented chem_comp_bond.type " << btype << " in " << id << std::endl;
|
||||
bond.type = BondType::sing;
|
||||
}
|
||||
@@ -403,7 +403,7 @@ CompoundFactoryImpl::CompoundFactoryImpl(const std::filesystem::path &file, std:
|
||||
|
||||
if (cif::iequals(id, "gly"))
|
||||
type = "peptide linking";
|
||||
else if (cif::iequals(group, "l-peptide") or cif::iequals(group, "L-peptide linking") or cif::iequals(group, "peptide"))
|
||||
else if (cif::iequals(group, "l-peptide") or cif::iequals(group, "L-peptide linking") or cif::iequals(group, "peptide") or cif::iequals(group, "p-peptide"))
|
||||
type = "L-peptide linking";
|
||||
else if (cif::iequals(group, "DNA"))
|
||||
type = "DNA linking";
|
||||
@@ -520,7 +520,7 @@ Compound *CCDCompoundFactoryImpl::create(const std::string &id)
|
||||
}
|
||||
}
|
||||
|
||||
if (result == nullptr and cif::VERBOSE)
|
||||
if (result == nullptr and cif::VERBOSE > 0)
|
||||
std::cerr << "Could not locate compound " << id << " in the CCD components file" << std::endl;
|
||||
|
||||
return result;
|
||||
@@ -611,7 +611,7 @@ Compound *CCP4CompoundFactoryImpl::create(const std::string &id)
|
||||
|
||||
if (cif::iequals(id, "gly"))
|
||||
type = "peptide linking";
|
||||
else if (cif::iequals(group, "l-peptide") or cif::iequals(group, "L-peptide linking") or cif::iequals(group, "peptide"))
|
||||
else if (cif::iequals(group, "l-peptide") or cif::iequals(group, "L-peptide linking") or cif::iequals(group, "peptide") or cif::iequals(group, "p-peptide"))
|
||||
type = "L-peptide linking";
|
||||
else if (cif::iequals(group, "DNA"))
|
||||
type = "DNA linking";
|
||||
@@ -645,13 +645,13 @@ CompoundFactory::CompoundFactory()
|
||||
auto ccd = cif::loadResource("components.cif");
|
||||
if (ccd)
|
||||
mImpl.reset(new CCDCompoundFactoryImpl(mImpl));
|
||||
else if (cif::VERBOSE)
|
||||
else if (cif::VERBOSE > 0)
|
||||
std::cerr << "CCD components.cif file was not found" << std::endl;
|
||||
|
||||
const char *clibd_mon = getenv("CLIBD_MON");
|
||||
if (clibd_mon != nullptr and fs::is_directory(clibd_mon))
|
||||
mImpl.reset(new CCP4CompoundFactoryImpl(clibd_mon));
|
||||
else if (cif::VERBOSE)
|
||||
else if (cif::VERBOSE > 0)
|
||||
std::cerr << "CCP4 monomers library not found, CLIBD_MON is not defined" << std::endl;
|
||||
|
||||
}
|
||||
@@ -695,7 +695,8 @@ void CompoundFactory::setDefaultDictionary(const std::filesystem::path &inDictFi
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
std::cerr << "Error loading dictionary " << inDictFile << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Error loading dictionary " << inDictFile << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -715,7 +716,8 @@ void CompoundFactory::pushDictionary(const std::filesystem::path &inDictFile)
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
std::cerr << "Error loading dictionary " << inDictFile << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Error loading dictionary " << inDictFile << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
114
src/PDB2Cif.cpp
114
src/PDB2Cif.cpp
@@ -268,7 +268,8 @@ int PDBRecord::vI(int columnFirst, int columnLast)
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::cerr << "Trying to parse '" << std::string(mValue + columnFirst - 7, mValue + columnLast - 7) << '\'' << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Trying to parse '" << std::string(mValue + columnFirst - 7, mValue + columnLast - 7) << '\'' << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
@@ -337,7 +338,7 @@ std::tuple<std::string, std::string> SpecificationListParser::GetNextSpecificati
|
||||
}
|
||||
else if (not isspace(ch))
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "skipping invalid character in SOURCE ID: " << ch << std::endl;
|
||||
}
|
||||
break;
|
||||
@@ -354,7 +355,7 @@ std::tuple<std::string, std::string> SpecificationListParser::GetNextSpecificati
|
||||
case eColon:
|
||||
if (ch == ';')
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Empty value for SOURCE: " << id << std::endl;
|
||||
state = eStart;
|
||||
}
|
||||
@@ -418,7 +419,7 @@ std::tuple<std::string, std::string> SpecificationListParser::GetNextSpecificati
|
||||
case eError:
|
||||
if (ch == ';')
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Skipping invalid header line: '" << std::string(start, mP) << std::endl;
|
||||
state = eStart;
|
||||
}
|
||||
@@ -656,7 +657,7 @@ class PDBFileParser
|
||||
int mSeqNum;
|
||||
char mIcode;
|
||||
|
||||
int mDbSeqNum;
|
||||
int mDbSeqNum = 0;
|
||||
bool mSeen = false;
|
||||
std::set<std::string> mAlts;
|
||||
|
||||
@@ -832,7 +833,7 @@ class PDBFileParser
|
||||
if (not mChainSeq2AsymSeq.count(key))
|
||||
{
|
||||
ec = error::make_error_code(error::pdbErrors::residueNotFound);
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Residue " << chainID << resSeq << iCode << " could not be mapped" << std::endl;
|
||||
}
|
||||
else
|
||||
@@ -929,7 +930,7 @@ class PDBFileParser
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << ex.what() << std::endl;
|
||||
ec = error::make_error_code(error::pdbErrors::invalidDate);
|
||||
}
|
||||
@@ -940,7 +941,10 @@ class PDBFileParser
|
||||
std::string pdb2cifDate(std::string s)
|
||||
{
|
||||
std::error_code ec;
|
||||
return pdb2cifDate(s, ec);
|
||||
auto result = pdb2cifDate(s, ec);
|
||||
if (ec and cif::VERBOSE > 0)
|
||||
std::cerr << "Invalid date(" << s << "): " << ec.message() << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string pdb2cifAuth(std::string author)
|
||||
@@ -1160,7 +1164,8 @@ void PDBFileParser::PreParseInput(std::istream &is)
|
||||
if (is.eof())
|
||||
break;
|
||||
|
||||
std::cerr << "Line number " << lineNr << " is empty!" << std::endl;
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Line number " << lineNr << " is empty!" << std::endl;
|
||||
|
||||
getline(is, lookahead);
|
||||
++lineNr;
|
||||
@@ -1278,7 +1283,8 @@ void PDBFileParser::PreParseInput(std::istream &is)
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::cerr << "Dropping FORMUL line (" << (lineNr - 1) << ") with invalid component number '" << value.substr(1, 3) << '\'' << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Dropping FORMUL line (" << (lineNr - 1) << ") with invalid component number '" << value.substr(1, 3) << '\'' << std::endl;
|
||||
continue;
|
||||
// throw_with_nested(std::runtime_error("Invalid component number '" + value.substr(1, 3) + '\''));
|
||||
}
|
||||
@@ -1305,7 +1311,8 @@ void PDBFileParser::PreParseInput(std::istream &is)
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::cerr << "Error parsing FORMUL at line " << lineNr << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Error parsing FORMUL at line " << lineNr << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -1412,7 +1419,8 @@ void PDBFileParser::PreParseInput(std::istream &is)
|
||||
|
||||
if (not dropped.empty())
|
||||
{
|
||||
std::cerr << "Dropped unsupported records: " << ba::join(dropped, ", ") << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Dropped unsupported records: " << ba::join(dropped, ", ") << std::endl;
|
||||
}
|
||||
|
||||
if (mData == nullptr)
|
||||
@@ -1440,7 +1448,7 @@ void PDBFileParser::Match(const std::string &expected, bool throwIfMissing)
|
||||
{
|
||||
if (throwIfMissing)
|
||||
throw std::runtime_error("Expected record " + expected + " but found " + mRec->mName);
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Expected record " + expected + " but found " + mRec->mName << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -1575,7 +1583,8 @@ void PDBFileParser::ParseTitle()
|
||||
|
||||
if (not iequals(key, "MOL_ID") and mCompounds.empty())
|
||||
{
|
||||
std::cerr << "Ignoring invalid COMPND record" << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Ignoring invalid COMPND record" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1625,7 +1634,7 @@ void PDBFileParser::ParseTitle()
|
||||
// auto colon = s.find(": ");
|
||||
// if (colon == std::string::npos)
|
||||
// {
|
||||
// if (cif::VERBOSE)
|
||||
// if (cif::VERBOSE > 0)
|
||||
// std::cerr << "invalid source field, missing colon (" << s << ')' << std::endl;
|
||||
// continue;
|
||||
// }
|
||||
@@ -1713,7 +1722,7 @@ void PDBFileParser::ParseTitle()
|
||||
// NUMMDL
|
||||
if (mRec->is("NUMMDL"))
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "skipping unimplemented NUMMDL record" << std::endl;
|
||||
GetNextRecord();
|
||||
}
|
||||
@@ -1816,7 +1825,7 @@ void PDBFileParser::ParseTitle()
|
||||
// SPRSDE
|
||||
if (mRec->is("SPRSDE"))
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "skipping unimplemented SPRSDE record" << std::endl;
|
||||
GetNextRecord();
|
||||
}
|
||||
@@ -2265,7 +2274,7 @@ void PDBFileParser::ParseRemarks()
|
||||
state = eMCP;
|
||||
else if (subtopic == "CHIRAL CENTERS")
|
||||
state = eChC;
|
||||
else if (cif::VERBOSE)
|
||||
else if (cif::VERBOSE > 0)
|
||||
throw std::runtime_error("Unknown subtopic in REMARK 500: " + subtopic);
|
||||
|
||||
headerSeen = false;
|
||||
@@ -2342,7 +2351,7 @@ void PDBFileParser::ParseRemarks()
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Dropping REMARK 500 at line " << mRec->mLineNr << " due to invalid symmetry operation" << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -2675,7 +2684,7 @@ void PDBFileParser::ParseRemarks()
|
||||
case sStart:
|
||||
if (s == "SITE")
|
||||
state = sID;
|
||||
else if (cif::VERBOSE)
|
||||
else if (cif::VERBOSE > 0)
|
||||
throw std::runtime_error("Invalid REMARK 800 record, expected SITE");
|
||||
break;
|
||||
|
||||
@@ -2685,7 +2694,7 @@ void PDBFileParser::ParseRemarks()
|
||||
id = m[1].str();
|
||||
state = sEvidence;
|
||||
}
|
||||
else if (cif::VERBOSE)
|
||||
else if (cif::VERBOSE > 0)
|
||||
throw std::runtime_error("Invalid REMARK 800 record, expected SITE_IDENTIFIER");
|
||||
break;
|
||||
|
||||
@@ -2695,7 +2704,7 @@ void PDBFileParser::ParseRemarks()
|
||||
evidence = m[1].str();
|
||||
state = sDesc;
|
||||
}
|
||||
else if (cif::VERBOSE)
|
||||
else if (cif::VERBOSE > 0)
|
||||
throw std::runtime_error("Invalid REMARK 800 record, expected SITE_IDENTIFIER");
|
||||
break;
|
||||
|
||||
@@ -2906,7 +2915,7 @@ void PDBFileParser::ParseRemark200()
|
||||
collectionDate = pdb2cifDate(rm200("DATE OF DATA COLLECTION", diffrnNr), ec);
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << ec.message() << " for pdbx_collection_date" << std::endl;
|
||||
|
||||
// The date field can become truncated when multiple values are available
|
||||
@@ -3025,7 +3034,7 @@ void PDBFileParser::ParseRemark200()
|
||||
else if (inRM200({"HIGHEST RESOLUTION SHELL, RANGE LOW (A)", "COMPLETENESS FOR SHELL (%)",
|
||||
"R MERGE FOR SHELL (I)", "R SYM FOR SHELL (I)", "<I/SIGMA(I)> FOR SHELL", "DATA REDUNDANCY IN SHELL"}))
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Not writing reflns_shell record since d_res_high is missing" << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -3595,7 +3604,7 @@ void PDBFileParser::ConstructEntities()
|
||||
{
|
||||
auto &r = chain.mResiduesSeen[lastResidueIndex + 1];
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cerr << "Detected residues that cannot be aligned to SEQRES" << std::endl
|
||||
<< "First residue is " << chain.mDbref.chainID << ':' << r.mSeqNum << r.mIcode << std::endl;
|
||||
@@ -4005,7 +4014,7 @@ void PDBFileParser::ConstructEntities()
|
||||
tie(asym, labelSeq, std::ignore) = MapResidue(seqadv.chainID, seqadv.seqNum, seqadv.iCode, ec);
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "dropping unmatched SEQADV record" << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -4319,7 +4328,7 @@ void PDBFileParser::ConstructEntities()
|
||||
tie(asymID, seq, std::ignore) = MapResidue(chainID, seqNum, iCode, ec);
|
||||
if (ec) // no need to write a modres if it could not be found
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "dropping unmapped MODRES record" << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -4415,7 +4424,7 @@ void PDBFileParser::ConstructEntities()
|
||||
tie(asymID, seqNr, isPolymer) = MapResidue(unobs.chain, unobs.seq, unobs.iCode, ec);
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "error mapping unobserved residue" << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -4676,7 +4685,7 @@ void PDBFileParser::ParseSecondaryStructure()
|
||||
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Could not map residue for HELIX " << vI(8, 10) << std::endl;
|
||||
}
|
||||
else
|
||||
@@ -4791,7 +4800,7 @@ void PDBFileParser::ParseSecondaryStructure()
|
||||
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Dropping SHEET record " << vI(8, 10) << std::endl;
|
||||
}
|
||||
else
|
||||
@@ -4827,7 +4836,7 @@ void PDBFileParser::ParseSecondaryStructure()
|
||||
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "skipping unmatched pdbx_struct_sheet_hbond record" << std::endl;
|
||||
}
|
||||
else
|
||||
@@ -4927,7 +4936,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
|
||||
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Dropping SSBOND " << vI(8, 10) << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -4948,7 +4957,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Dropping SSBOND " << vI(8, 10) << " due to invalid symmetry operation" << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -4993,7 +5002,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
|
||||
|
||||
if (mRec->is("LINK ") or mRec->is("LINKR "))
|
||||
{
|
||||
if (cif::VERBOSE and mRec->is("LINKR "))
|
||||
if (cif::VERBOSE > 0 and mRec->is("LINKR "))
|
||||
std::cerr << "Accepting non-standard LINKR record, but ignoring extra information" << std::endl;
|
||||
|
||||
// 1 - 6 Record name "LINK "
|
||||
@@ -5046,7 +5055,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
|
||||
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Dropping LINK record at line " << mRec->mLineNr << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -5062,7 +5071,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
|
||||
}
|
||||
catch (const std::invalid_argument &)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Distance value '" << distance << "' is not a valid float in LINK record" << std::endl;
|
||||
swap(ccp4LinkID, distance); // assume this is a ccp4_link_id... oh really?
|
||||
}
|
||||
@@ -5078,7 +5087,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Dropping LINK record at line " << mRec->mLineNr << " due to invalid symmetry operation" << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -5149,7 +5158,7 @@ void PDBFileParser::ParseConnectivtyAnnotation()
|
||||
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Dropping CISPEP record at line " << mRec->mLineNr << std::endl;
|
||||
continue;
|
||||
}
|
||||
@@ -5215,7 +5224,7 @@ void PDBFileParser::ParseMiscellaneousFeatures()
|
||||
|
||||
if (ec)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "skipping struct_site_gen record" << std::endl;
|
||||
}
|
||||
else
|
||||
@@ -5518,7 +5527,7 @@ void PDBFileParser::ParseCoordinate(int modelNr)
|
||||
{
|
||||
if (groupPDB == "HETATM")
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Changing atom from HETATM to ATOM at line " << mRec->mLineNr << std::endl;
|
||||
groupPDB = "ATOM";
|
||||
}
|
||||
@@ -5527,7 +5536,7 @@ void PDBFileParser::ParseCoordinate(int modelNr)
|
||||
{
|
||||
if (groupPDB == "ATOM")
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Changing atom from ATOM to HETATM at line " << mRec->mLineNr << std::endl;
|
||||
groupPDB = "HETATM";
|
||||
}
|
||||
@@ -5698,7 +5707,8 @@ void PDBFileParser::Parse(std::istream &is, cif::File &result)
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::cerr << "Error parsing REMARK 3" << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Error parsing REMARK 3" << std::endl;
|
||||
throw;
|
||||
}
|
||||
//
|
||||
@@ -5750,12 +5760,12 @@ void PDBFileParser::Parse(std::istream &is, cif::File &result)
|
||||
|
||||
if ((symm1.empty() or symm1 == "1_555") and (symm2.empty() or symm2 == "1_555"))
|
||||
distance = static_cast<float>(mmcif::Distance(mmcif::Point{x1, y1, z1}, mmcif::Point{x2, y2, z2}));
|
||||
else if (cif::VERBOSE)
|
||||
else if (cif::VERBOSE > 0)
|
||||
std::cerr << "Cannot calculate distance for link since one of the atoms is in another dimension" << std::endl;
|
||||
}
|
||||
catch (std::exception &ex)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Error finding atom for LINK distance calculation: " << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
@@ -5764,10 +5774,13 @@ void PDBFileParser::Parse(std::istream &is, cif::File &result)
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
std::cerr << "Error parsing PDB";
|
||||
if (mRec != nullptr)
|
||||
std::cerr << " at line " << mRec->mLineNr;
|
||||
std::cerr << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
{
|
||||
std::cerr << "Error parsing PDB";
|
||||
if (mRec != nullptr)
|
||||
std::cerr << " at line " << mRec->mLineNr;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -5947,7 +5960,7 @@ int PDBFileParser::PDBChain::AlignResToSeqRes()
|
||||
switch (tb(x, y))
|
||||
{
|
||||
case -1:
|
||||
// if (cif::VERBOSE)
|
||||
// if (cif::VERBOSE > 0)
|
||||
// std::cerr << "A residue found in the ATOM records "
|
||||
// << "(" << ry[y].mMonID << " @ " << mDbref.chainID << ":" << ry[y].mSeqNum
|
||||
// << ((ry[y].mIcode == ' ' or ry[y].mIcode == 0) ? "" : std::string{ ry[y].mIcode }) << ")"
|
||||
@@ -6034,7 +6047,6 @@ void ReadPDBFile(std::istream &pdbFile, cif::File &cifFile)
|
||||
|
||||
p.Parse(pdbFile, cifFile);
|
||||
|
||||
if (not cifFile.isValid())
|
||||
// throw std::runtime_error("Resulting mmCIF file is invalid");
|
||||
if (not cifFile.isValid() and cif::VERBOSE >= 0)
|
||||
std::cerr << "Resulting mmCIF file is not valid!" << std::endl;
|
||||
}
|
||||
|
||||
@@ -1320,7 +1320,7 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
|
||||
|
||||
if (line != "REFINEMENT.")
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Unexpected data in REMARK 3" << std::endl;
|
||||
return false;
|
||||
}
|
||||
@@ -1332,7 +1332,7 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
|
||||
|
||||
if (not std::regex_match(line, m, rxp))
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Expected valid PROGRAM line in REMARK 3" << std::endl;
|
||||
return false;
|
||||
}
|
||||
@@ -1367,8 +1367,9 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
std::cerr << "Error parsing REMARK 3 with " << parser->program() << std::endl
|
||||
<< e.what() << '\n';
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Error parsing REMARK 3 with " << parser->program() << std::endl
|
||||
<< e.what() << '\n';
|
||||
score = 0;
|
||||
}
|
||||
|
||||
@@ -1411,7 +1412,7 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
|
||||
tryParser(new TNT_Remark3Parser(program, expMethod, r, db));
|
||||
else if (ba::starts_with(program, "X-PLOR"))
|
||||
tryParser(new XPLOR_Remark3Parser(program, expMethod, r, db));
|
||||
else if (cif::VERBOSE)
|
||||
else if (cif::VERBOSE > 0)
|
||||
std::cerr << "Skipping unknown program (" << program << ") in REMARK 3" << std::endl;
|
||||
}
|
||||
|
||||
@@ -1420,7 +1421,8 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
|
||||
bool guessProgram = scores.empty() or scores.front().score < 0.9f;;
|
||||
if (guessProgram)
|
||||
{
|
||||
std::cerr << "Unknown or untrusted program in REMARK 3, trying all parsers to see if there is a match" << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "Unknown or untrusted program in REMARK 3, trying all parsers to see if there is a match" << std::endl;
|
||||
|
||||
tryParser(new BUSTER_TNT_Remark3Parser("BUSTER-TNT", expMethod, r, db));
|
||||
tryParser(new CNS_Remark3Parser("CNS", expMethod, r, db));
|
||||
@@ -1444,7 +1446,7 @@ bool Remark3Parser::parse(const std::string& expMethod, PDBRecord* r, cif::Datab
|
||||
|
||||
auto& best = scores.front();
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Choosing " << best.parser->program() << " version '" << best.parser->version() << "' as refinement program. Score = " << best.score << std::endl;
|
||||
|
||||
auto& software = db["software"];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1167
src/Structure.cpp
1167
src/Structure.cpp
File diff suppressed because it is too large
Load Diff
@@ -248,7 +248,7 @@ struct TLSSelectionNot : public TLSSelection
|
||||
for (auto& r: residues)
|
||||
r.selected = not r.selected;
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "NOT" << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -267,7 +267,7 @@ struct TLSSelectionAll : public TLSSelection
|
||||
for (auto& r: residues)
|
||||
r.selected = true;
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "ALL" << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -287,7 +287,7 @@ struct TLSSelectionChain : public TLSSelectionAll
|
||||
for (auto& r: residues)
|
||||
r.selected = allChains or r.chainID == m_chain;
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "CHAIN " << m_chain << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -307,7 +307,7 @@ struct TLSSelectionResID : public TLSSelectionAll
|
||||
for (auto& r: residues)
|
||||
r.selected = r.seqNr == m_seq_nr and r.iCode == m_icode;
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "ResID " << m_seq_nr << (m_icode ? std::string { m_icode} : "") << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -331,7 +331,7 @@ struct TLSSelectionRangeSeq : public TLSSelectionAll
|
||||
(r.seqNr <= m_last or m_last == kResidueNrWildcard));
|
||||
}
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "Range " << m_first << ':' << m_last << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -374,7 +374,7 @@ struct TLSSelectionRangeID : public TLSSelectionAll
|
||||
}
|
||||
}
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "Through " << m_first << ':' << m_last << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -407,7 +407,7 @@ struct TLSSelectionUnion : public TLSSelection
|
||||
for (auto ai = a.begin(), bi = b.begin(), ri = residues.begin(); ri != residues.end(); ++ai, ++bi, ++ri)
|
||||
ri->selected = ai->selected or bi->selected;
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "Union" << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -440,7 +440,7 @@ struct TLSSelectionIntersection : public TLSSelection
|
||||
for (auto ai = a.begin(), bi = b.begin(), ri = residues.begin(); ri != residues.end(); ++ai, ++bi, ++ri)
|
||||
ri->selected = ai->selected and bi->selected;
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "Intersection" << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -462,7 +462,7 @@ struct TLSSelectionByName : public TLSSelectionAll
|
||||
for (auto& r: residues)
|
||||
r.selected = r.name == m_name;
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "Name " << m_name << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -488,7 +488,7 @@ struct TLSSelectionByElement : public TLSSelectionAll
|
||||
for (auto& r: residues)
|
||||
r.selected = iequals(r.name, m_element);
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
{
|
||||
std::cout << std::string(indentLevel * 2, ' ') << "Element " << m_element << std::endl;
|
||||
DumpSelection(residues, indentLevel);
|
||||
@@ -890,7 +890,7 @@ TLSSelectionPtr TLSSelectionParserImplPhenix::Parse()
|
||||
|
||||
Match(pt_EOLN);
|
||||
|
||||
if (extraParenthesis)
|
||||
if (extraParenthesis and cif::VERBOSE > 0)
|
||||
std::cerr << "WARNING: too many closing parenthesis in TLS selection statement" << std::endl;
|
||||
|
||||
return result;
|
||||
@@ -931,7 +931,7 @@ TLSSelectionPtr TLSSelectionParserImplPhenix::ParseFactor()
|
||||
case '(':
|
||||
Match('(');
|
||||
result = ParseAtomSelection();
|
||||
if (m_lookahead == pt_EOLN)
|
||||
if (m_lookahead == pt_EOLN and cif::VERBOSE > 0)
|
||||
std::cerr << "WARNING: missing closing parenthesis in TLS selection statement" << std::endl;
|
||||
else
|
||||
Match(')');
|
||||
@@ -1033,7 +1033,7 @@ TLSSelectionPtr TLSSelectionParserImplPhenix::ParseFactor()
|
||||
result.reset(new TLSSelectionRangeID(from, to, icode_from, icode_to));
|
||||
else
|
||||
{
|
||||
if (cif::VERBOSE and (icode_from or icode_to))
|
||||
if (cif::VERBOSE > 0 and (icode_from or icode_to))
|
||||
std::cerr << "Warning, ignoring insertion codes" << std::endl;
|
||||
|
||||
result.reset(new TLSSelectionRangeSeq(from, to));
|
||||
@@ -1231,7 +1231,8 @@ TLSSelectionPtr TLSSelectionParserImplBuster::ParseGroup()
|
||||
std::tie(chain2, seqNr2) = ParseAtom();
|
||||
if (chain1 != chain2)
|
||||
{
|
||||
std::cerr << "Warning, ranges over multiple chains detected" << std::endl;
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Warning, ranges over multiple chains detected" << std::endl;
|
||||
|
||||
TLSSelectionPtr sc1(new TLSSelectionChain(chain1));
|
||||
TLSSelectionPtr sr1(new TLSSelectionRangeSeq(seqNr1, kResidueNrWildcard));
|
||||
@@ -1289,7 +1290,7 @@ std::tuple<std::string,int> TLSSelectionParserImplBuster::ParseAtom()
|
||||
Match(':');
|
||||
std::string atom = m_value_s;
|
||||
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Warning: ignoring atom ID '" << atom << "' in TLS selection" << std::endl;
|
||||
|
||||
Match(bt_IDENT);
|
||||
@@ -1810,7 +1811,8 @@ class TLSSelectionParser
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::cerr << "ParseError: " << ex.what() << std::endl;
|
||||
if (cif::VERBOSE >= 0)
|
||||
std::cerr << "ParseError: " << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1834,14 +1836,14 @@ TLSSelectionPtr ParseSelectionDetails(const std::string& program, const std::str
|
||||
|
||||
if (not result)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Falling back to old BUSTER" << std::endl;
|
||||
result = busterOld.Parse(selection);
|
||||
}
|
||||
|
||||
if (not result)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Falling back to PHENIX" << std::endl;
|
||||
result = phenix.Parse(selection);
|
||||
}
|
||||
@@ -1852,35 +1854,35 @@ TLSSelectionPtr ParseSelectionDetails(const std::string& program, const std::str
|
||||
|
||||
if (not result)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Falling back to BUSTER" << std::endl;
|
||||
result = buster.Parse(selection);
|
||||
}
|
||||
|
||||
if (not result)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Falling back to old BUSTER" << std::endl;
|
||||
result = busterOld.Parse(selection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "No known program specified, trying PHENIX" << std::endl;
|
||||
|
||||
result = phenix.Parse(selection);
|
||||
|
||||
if (not result)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Falling back to BUSTER" << std::endl;
|
||||
result = buster.Parse(selection);
|
||||
}
|
||||
|
||||
if (not result)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
if (cif::VERBOSE > 0)
|
||||
std::cerr << "Falling back to old BUSTER" << std::endl;
|
||||
result = busterOld.Parse(selection);
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
const char kRevision[] = R"(
|
||||
lib@PROJECT_NAME@-version: @PROJECT_VERSION@
|
||||
@BUILD_VERSION_STRING@
|
||||
Date: @BUILD_DATE_TIME@
|
||||
)";
|
||||
@@ -179,3 +179,23 @@ _struct_asym.details ?
|
||||
<< structure.getFile().data() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// // --------------------------------------------------------------------
|
||||
|
||||
// BOOST_AUTO_TEST_CASE(test_load_1)
|
||||
// {
|
||||
// mmcif::File cf(gTestDir / "5v3g.cif.gz");
|
||||
// mmcif::Structure s(cf);
|
||||
|
||||
// for (auto &poly : s.polymers())
|
||||
// {
|
||||
// std::cout << std::string(80, '=') << std::endl;
|
||||
// for (auto &res : poly)
|
||||
// {
|
||||
// std::cout << res << std::endl;
|
||||
|
||||
// for (auto &atom : res.atoms())
|
||||
// std::cout << " " << atom << std::endl;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1735,12 +1735,12 @@ BOOST_AUTO_TEST_CASE(t1)
|
||||
|
||||
auto p2 = p1;
|
||||
|
||||
Point c1 = CenterPoints(p1);
|
||||
CenterPoints(p1);
|
||||
|
||||
for (auto &p : p2)
|
||||
p.rotate(q);
|
||||
|
||||
Point c2 = CenterPoints(p2);
|
||||
CenterPoints(p2);
|
||||
|
||||
auto q2 = AlignPoints(p1, p2);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user