mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-05 14:34:21 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
288b2bb720 | ||
|
|
fb3b7bda68 | ||
|
|
6d5efe1cbd | ||
|
|
1ceec22184 | ||
|
|
951ff9b953 | ||
|
|
641f06a7e7 | ||
|
|
915ba4ac21 | ||
|
|
824637d83f | ||
|
|
0871406fe3 |
@@ -25,7 +25,7 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# set the project name
|
||||
project(libcifpp VERSION 5.2.1 LANGUAGES CXX)
|
||||
project(libcifpp VERSION 5.2.2 LANGUAGES CXX)
|
||||
|
||||
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
@@ -37,6 +37,7 @@ include(CMakePackageConfigHelpers)
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(GenerateExportHeader)
|
||||
include(CTest)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
set(CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
@@ -50,9 +51,6 @@ elseif(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
endif()
|
||||
|
||||
# Building shared libraries?
|
||||
option(BUILD_SHARED_LIBS "Build a shared library instead of a static one" OFF)
|
||||
|
||||
# Build documentation?
|
||||
option(BUILD_DOCUMENTATION "Build the documentation" OFF)
|
||||
|
||||
@@ -62,6 +60,10 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
# Optionally build a version to be installed inside CCP4
|
||||
option(BUILD_FOR_CCP4 "Build a version to be installed in CCP4" OFF)
|
||||
|
||||
# Building shared libraries?
|
||||
cmake_policy(SET CMP0127 NEW)
|
||||
cmake_dependent_option(BUILD_SHARED_LIBS "Build a shared library instead of a static one" OFF "NOT (BUILD_FOR_CCP4 AND WIN32)" ON)
|
||||
|
||||
# Lots of code depend on the availability of the components.cif file
|
||||
option(CIFPP_DOWNLOAD_CCD "Download the CCD file components.cif during installation" ON)
|
||||
|
||||
@@ -295,7 +297,7 @@ target_include_directories(cifpp
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
|
||||
target_link_libraries(cifpp PUBLIC Threads::Threads ZLIB::ZLIB Eigen3::Eigen ${CIFPP_REQUIRED_LIBRARIES})
|
||||
target_link_libraries(cifpp PUBLIC Threads::Threads ZLIB::ZLIB ${CIFPP_REQUIRED_LIBRARIES})
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
target_link_options(cifpp PRIVATE -undefined dynamic_lookup)
|
||||
@@ -317,11 +319,12 @@ if(CIFPP_DOWNLOAD_CCD)
|
||||
endif()
|
||||
|
||||
# Installation directories
|
||||
set(CIFPP_DATA_DIR "${CMAKE_INSTALL_FULL_DATADIR}/libcifpp")
|
||||
set(CIFPP_DATA_DIR "${CMAKE_INSTALL_FULL_DATADIR}/libcifpp" CACHE PATH "The directory where dictionary files are stored")
|
||||
target_compile_definitions(cifpp PUBLIC DATA_DIR="${CIFPP_DATA_DIR}")
|
||||
|
||||
if(UNIX)
|
||||
set(CIFPP_CACHE_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/cache/libcifpp")
|
||||
set(CIFPP_CACHE_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/cache/libcifpp"
|
||||
CACHE PATH "The directory where the update script stores new dictionary files")
|
||||
target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}")
|
||||
|
||||
set(CIFPP_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
This library contains code to work with mmCIF and legacy PDB files.
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation can be found at https://www.hekkelman.com/libcifpp-doc/
|
||||
|
||||
## Synopsis
|
||||
|
||||
```c++
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
Version 5.2.2
|
||||
- Remove dependency on Eigen3 for users of libcifpp
|
||||
- Fix typos in documentation
|
||||
- Do not build latex files in documentation
|
||||
- Fixed conversion from string to integer, would fail on +2 e.g.
|
||||
- sqrt is not constexpr, thus kGoldenRatio should be const, not constexpr
|
||||
|
||||
Version 5.2.1
|
||||
- New versionstring module
|
||||
- small fixes for generating documentation
|
||||
|
||||
@@ -11,7 +11,6 @@ include(CMakeFindDependencyMacro)
|
||||
find_dependency(Threads)
|
||||
|
||||
find_dependency(ZLIB REQUIRED)
|
||||
find_dependency(Eigen3 REQUIRED)
|
||||
|
||||
if(MSVC)
|
||||
find_dependency(zeep REQUIRED)
|
||||
|
||||
@@ -42,4 +42,7 @@ add_custom_target("Sphinx-${PROJECT_NAME}" ALL
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Generating documentation with Sphinx")
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/sphinx/ DESTINATION ${CMAKE_INSTALL_DOCDIR} PATTERN .doctrees EXCLUDE)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/sphinx/
|
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||
PATTERN .doctrees EXCLUDE
|
||||
PATTERN .buildinfo EXCLUDE)
|
||||
|
||||
@@ -3,6 +3,7 @@ FILE_PATTERNS = *.hpp
|
||||
STRIP_FROM_PATH = @DOXYGEN_INPUT_DIR@
|
||||
RECURSIVE = YES
|
||||
GENERATE_XML = YES
|
||||
GENERATE_LATEX = NO
|
||||
PREDEFINED += and=&& or=|| not=! CIFPP_EXPORT= HAVE_LIBCLIPPER=1
|
||||
GENERATE_HTML = NO
|
||||
GENERATE_TODOLIST = NO
|
||||
|
||||
@@ -26,7 +26,7 @@ Writing is equally easy:
|
||||
file << "Hello, world!";
|
||||
file.close();
|
||||
|
||||
You can also use the :cpp:class:`cif::gzio:istream` and feed it a *std::streambuf* object that may or may not contain compressed data. In that case the first bytes of the input are sniffed and if it is gzip compressed data, decompression will be done.
|
||||
You can also use the :cpp:class:`cif::gzio::istream` and feed it a *std::streambuf* object that may or may not contain compressed data. In that case the first bytes of the input are sniffed and if it is gzip compressed data, decompression will be done.
|
||||
|
||||
A progress bar
|
||||
--------------
|
||||
|
||||
@@ -9,4 +9,25 @@ Information about compounds is captured in the :cpp:class:`cif::compound`. An in
|
||||
|
||||
If the compound you want to use is not available in the CCD or in CCP4, you can add that information yourself. For this you can use the method :cpp:func:`cif::compound_factory::push_dictionary`.
|
||||
|
||||
So, given that we have CCD, CCP4 monomer library and used defined compound definitions, what will you get when you try to retrieve such a compound by ID? The answer is, the factory has a stack of compound generators. The first thrown on the stack is the one for a CCD file (*components.cif*) if it can be found. Then, if the *CLIBD_MON* environmental variable is defined, a generator for monomer library files is added to the stack. And then all generators for files you added using *push_dictionary* are added in order. The generators are searched in the reverse order in which they were added to see if it creates a compound object for the ID. If no compound was created at all, nullptr is returned.
|
||||
So, given that we have CCD, CCP4 monomer library and used defined compound definitions, what will you get when you try to retrieve such a compound by ID? The answer is, the factory has a stack of compound generators. The first thrown on the stack is the one for a CCD file (*components.cif*) if it can be found. Then, if the *CLIBD_MON* environmental variable is defined, a generator for monomer library files is added to the stack. And then all generators for files you added using *push_dictionary* are added in order. The generators are searched in the reverse order in which they were added to see if it creates a compound object for the ID. If no compound was created at all, nullptr is returned.
|
||||
|
||||
Updating CCD
|
||||
------------
|
||||
|
||||
The CCD data is stored in a single file called *components.cif* and can be downloaded from `CCD <https://www.wwpdb.org/data/ccd>`_.
|
||||
|
||||
As can be read in the section on resources (:doc:`/resources`) files in libcifpp are loaded in a specific order. If the CCD datafile was downloaded during installation, a copy can be found in the directory */usr/share/libcifpp/* (if you installed in */usr*). This is a static file and will not be updated until the next installation of libcifpp.
|
||||
|
||||
When configuring libcifpp, you can specify the *CIFPP_INSTALL_UPDATE_SCRIPT* option, as in:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cmake -S . -B build -DCIFPP_INSTALL_UPDATE_SCRIPT=ON # ... more options?
|
||||
|
||||
This will install a script named *update-libcifpp-data* in */etc/cron.weekly* or */etc/periodic/weekly*. This file uses a config file named */etc/libcifpp.conf* which you then need to edit. In this config file the following line needs to be uncommented:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# update=true
|
||||
|
||||
After that, the update script will weekly download the latest components.cif file to */var/cache/libcifpp*.
|
||||
|
||||
@@ -459,9 +459,14 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
|
||||
{
|
||||
auto txt = ref.text();
|
||||
|
||||
std::from_chars_result r = selected_charconv<value_type>::from_chars(txt.data(), txt.data() + txt.size(), result);
|
||||
auto b = txt.data();
|
||||
auto e = txt.data() + txt.size();
|
||||
|
||||
if (r.ec != std::errc())
|
||||
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ?
|
||||
selected_charconv<value_type>::from_chars(b + 1, e, result) :
|
||||
selected_charconv<value_type>::from_chars(b, e, result);
|
||||
|
||||
if (r.ec != std::errc() or r.ptr != e)
|
||||
{
|
||||
result = {};
|
||||
if (cif::VERBOSE)
|
||||
@@ -470,6 +475,8 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
|
||||
std::cerr << "Attempt to convert " << std::quoted(txt) << " into a number\n";
|
||||
else if (r.ec == std::errc::result_out_of_range)
|
||||
std::cerr << "Conversion of " << std::quoted(txt) << " into a type that is too small\n";
|
||||
else
|
||||
std::cerr << "Not a valid number " << std::quoted(txt) << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -489,9 +496,14 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
|
||||
{
|
||||
value_type v = {};
|
||||
|
||||
std::from_chars_result r = selected_charconv<value_type>::from_chars(txt.data(), txt.data() + txt.size(), v);
|
||||
auto b = txt.data();
|
||||
auto e = txt.data() + txt.size();
|
||||
|
||||
if (r.ec != std::errc())
|
||||
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ?
|
||||
selected_charconv<value_type>::from_chars(b + 1, e, v) :
|
||||
selected_charconv<value_type>::from_chars(b, e, v);
|
||||
|
||||
if (r.ec != std::errc() or r.ptr != e)
|
||||
{
|
||||
if (cif::VERBOSE)
|
||||
{
|
||||
@@ -499,6 +511,8 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
|
||||
std::cerr << "Attempt to convert " << std::quoted(txt) << " into a number\n";
|
||||
else if (r.ec == std::errc::result_out_of_range)
|
||||
std::cerr << "Conversion of " << std::quoted(txt) << " into a type that is too small\n";
|
||||
else
|
||||
std::cerr << "Not a valid number " << std::quoted(txt) << '\n';
|
||||
}
|
||||
result = 1;
|
||||
}
|
||||
|
||||
@@ -882,7 +882,7 @@ class spherical_dots
|
||||
|
||||
spherical_dots()
|
||||
{
|
||||
constexpr double
|
||||
const double
|
||||
kGoldenRatio = (1 + std::sqrt(5.0)) / 2;
|
||||
|
||||
auto p = m_points.begin();
|
||||
|
||||
10
src/file.cpp
10
src/file.cpp
@@ -182,17 +182,17 @@ std::tuple<file::iterator, bool> file::emplace(std::string_view name)
|
||||
|
||||
void file::load(const std::filesystem::path &p)
|
||||
{
|
||||
gzio::ifstream in(p);
|
||||
if (not in.is_open())
|
||||
throw std::runtime_error("Could not open file '" + p.string() + '\'');
|
||||
|
||||
try
|
||||
{
|
||||
gzio::ifstream in(p);
|
||||
if (not in.is_open())
|
||||
throw std::runtime_error("Could not open file " + p.string());
|
||||
|
||||
load(in);
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
throw_with_nested(std::runtime_error("Error reading file " + p.string()));
|
||||
throw_with_nested(std::runtime_error("Error reading file '" + p.string() + '\''));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,6 +150,31 @@ BOOST_AUTO_TEST_CASE(cc_2)
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cc_3)
|
||||
{
|
||||
cif::category c("foo");
|
||||
c.emplace({
|
||||
{ "f-1", 1 },
|
||||
{ "f-2", "-1" },
|
||||
{ "f-3", "+1" },
|
||||
{ "f-4", " 1" },
|
||||
{ "f-5", " +1" },
|
||||
{ "f-6", "1 " },
|
||||
});
|
||||
|
||||
auto row = c.front();
|
||||
BOOST_CHECK_EQUAL(row["f-1"].as<int>(), 1);
|
||||
BOOST_CHECK_EQUAL(row["f-2"].as<int>(), -1);
|
||||
BOOST_CHECK_EQUAL(row["f-3"].as<int>(), 1);
|
||||
|
||||
// BOOST_CHECK_THROW(row["f-4"].as<int>(), std::exception);
|
||||
// BOOST_CHECK_THROW(row["f-5"].as<int>(), std::exception);
|
||||
// BOOST_CHECK_THROW(row["f-6"].as<int>(), std::exception);
|
||||
BOOST_CHECK_EQUAL(row["f-4"].as<int>(), 0);
|
||||
BOOST_CHECK_EQUAL(row["f-5"].as<int>(), 0);
|
||||
BOOST_CHECK_EQUAL(row["f-6"].as<int>(), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(item_1)
|
||||
{
|
||||
using namespace cif;
|
||||
|
||||
Reference in New Issue
Block a user