Commit 93375a50 by Maarten L. Hekkelman Committed by GitHub

Develop (#54)

* - renamed exists to contains
- fix compare for ints where item is empty

* - checking and optionally dropping ndb_poly_seq_scheme
- fix in iterator_proxy

* formatting data in reconstruction

* Version bump

* Attempt to get code compiling on macOS

* attempt 2 to build on macOS

* Added remove column

* Added rename_column
Added item_alias
Rename columns in reconstruct

* macOS...

* Fixed serious bug in emplace of both datablock and file.

* renaming field and column to item

* replace tag with item or item_name

* Fix validate pdbx

* version bump

* atom_site_anisotrop check

* - changed compound::is_known_peptide/is_know_base
- Add audit_conform only if file is really valid
- Added reconstruction code for PDBx

* pdb2cif work

* gcc diagnostics and clipper

* Fixing pdb2cif, and sequence checking

* work around bug in old gcc

* fix reconstruct sequence

* formatting

* some small optimisations

* Fix url in compound message

* Fix operator= for item_handle

* Fix operator= for item_handle

* new update_value in category

* test builds faster now

* Use Catch2 version 3 if installed

* catch22
parent 22537c0e
......@@ -11,4 +11,5 @@ Testing/
include/cif++/exports.hpp
docs/api
docs/conf.py
build_ci/
\ No newline at end of file
build_ci/
data/components.cif
......@@ -27,7 +27,7 @@ cmake_minimum_required(VERSION 3.16)
# set the project name
project(
libcifpp
VERSION 6.1.0
VERSION 7.0.0
LANGUAGES CXX)
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
......@@ -546,55 +546,7 @@ if(NOT PROJECT_IS_TOP_LEVEL)
endif()
if(BUILD_TESTING)
# We're using the older version 2 of Catch2
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.13.9)
FetchContent_MakeAvailable(Catch2)
list(
APPEND
CIFPP_tests
unit-v2
unit-3d
format
model
rename-compound
sugar
spinner
validate-pdbx)
foreach(CIFPP_TEST IN LISTS CIFPP_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}
"${CMAKE_CURRENT_SOURCE_DIR}/test/test-main.cpp")
target_link_libraries(${CIFPP_TEST} PRIVATE Threads::Threads cifpp::cifpp
Catch2::Catch2)
target_include_directories(${CIFPP_TEST} PRIVATE "${EIGEN_INCLUDE_DIR}")
if(MSVC)
# Specify unwind semantics so that MSVC knowns how to handle exceptions
target_compile_options(${CIFPP_TEST} PRIVATE /EHsc)
endif()
add_custom_target(
"run-${CIFPP_TEST}"
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Run${CIFPP_TEST}.touch ${CIFPP_TEST})
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Run${CIFPP_TEST}.touch
COMMAND $<TARGET_FILE:${CIFPP_TEST}> --data-dir
${CMAKE_CURRENT_SOURCE_DIR}/test)
add_test(NAME ${CIFPP_TEST} COMMAND $<TARGET_FILE:${CIFPP_TEST}> --data-dir
${CMAKE_CURRENT_SOURCE_DIR}/test)
endforeach()
add_subdirectory(test)
endif()
# Optionally install the update scripts for CCD and dictionary files
......
Version 7.0.0
- Renaming many methods and parameters to be more
consistent with the mmCIF dictionaries.
(Most notably, item used to be called column or
tag sometimes).
- validation_error is now a std::system_error error
value. The exception is gone.
- Added repairSequenceInfo to repair invalid files
Version 6.1.0
- Add formula weight to entity in pdb2cif
- Change order of categories inside a datablock to match order in file
......
......@@ -31,22 +31,22 @@
#include "cif++/condition.hpp"
#include "cif++/iterator.hpp"
#include "cif++/row.hpp"
#include "cif++/validate.hpp"
#include "cif++/text.hpp"
#include "cif++/validate.hpp"
#include <array>
/** \file category.hpp
* Documentation for the cif::category class
*
* The category class should meet the requirements of Container and
* SequenceContainer.
*
* TODO: implement all of:
* https://en.cppreference.com/w/cpp/named_req/Container
* https://en.cppreference.com/w/cpp/named_req/SequenceContainer
* and more?
*/
* Documentation for the cif::category class
*
* The category class should meet the requirements of Container and
* SequenceContainer.
*
* TODO: implement all of:
* https://en.cppreference.com/w/cpp/named_req/Container
* https://en.cppreference.com/w/cpp/named_req/SequenceContainer
* and more?
*/
namespace cif
{
......@@ -61,23 +61,43 @@ namespace cif
class duplicate_key_error : public std::runtime_error
{
public:
/**
* @brief Construct a new duplicate key error object
*/
/**
* @brief Construct a new duplicate key error object
*/
duplicate_key_error(const std::string &msg)
: std::runtime_error(msg)
{
}
};
/// @brief A missing_key_error is thrown when an attempt is made
/// to create an index when one of the key items is missing.
class missing_key_error : public std::runtime_error
{
public:
/**
* @brief Construct a new duplicate key error object
*/
missing_key_error(const std::string &msg, const std::string &key)
: std::runtime_error(msg)
, m_key(key)
{
}
const std::string &get_key() const noexcept { return m_key; }
private:
std::string m_key;
};
/// @brief A multiple_results_error is throw when you request a single
/// row using a query but the query contains more than exactly one row.
class multiple_results_error : public std::runtime_error
{
public:
/**
* @brief Construct a new multiple results error object
*/
/**
* @brief Construct a new multiple results error object
*/
multiple_results_error()
: std::runtime_error("query should have returned exactly one row")
{
......@@ -136,8 +156,16 @@ class category
// --------------------------------------------------------------------
const std::string &name() const { return m_name; } ///< Returns the name of the category
iset key_fields() const; ///< Returns the cif::iset of key field names. Retrieved from the @ref category_validator for this category
std::set<uint16_t> key_field_indices() const; ///< Returns a set of indices for the key fields.
[[deprecated("use key_items instead")]]
iset key_fields() const; ///< Returns the cif::iset of key item names. Retrieved from the @ref category_validator for this category
iset key_items() const; ///< Returns the cif::iset of key item names. Retrieved from the @ref category_validator for this category
[[deprecated("use key_item_indices instead")]]
std::set<uint16_t> key_field_indices() const; ///< Returns a set of indices for the key items.
std::set<uint16_t> key_item_indices() const; ///< Returns a set of indices for the key items.
/// @brief Set the validator for this category to @a v
/// @param v The category_validator to assign. A nullptr value is allowed.
......@@ -162,7 +190,7 @@ class category
/// @brief Validate links, that means, values in this category should have an
/// accompanying value in parent categories.
///
///
/// @note
/// The code makes one exception when validating missing links and that's between
/// *atom_site* and a parent *pdbx_poly_seq_scheme* or *entity_poly_seq*.
......@@ -265,7 +293,7 @@ class category
/// Return the theoretical maximum number or rows that can be stored
size_t max_size() const
{
return std::numeric_limits<size_t>::max(); // this is a bit optimistic, I guess
return std::numeric_limits<size_t>::max(); // this is a bit optimistic, I guess
}
/// Return true if the category is empty
......@@ -281,12 +309,12 @@ class category
using key_type = row_initializer;
/// @brief Return a row_handle for the row specified by \a key
/// @param key The value for the key, fields specified in the dictionary should have a value
/// @param key The value for the key, items specified in the dictionary should have a value
/// @return The row found in the index, or an undefined row_handle
row_handle operator[](const key_type &key);
/// @brief Return a const row_handle for the row specified by \a key
/// @param key The value for the key, fields specified in the dictionary should have a value
/// @param key The value for the key, items specified in the dictionary should have a value
/// @return The row found in the index, or an undefined row_handle
const row_handle operator[](const key_type &key) const
{
......@@ -301,15 +329,15 @@ class category
/// @code{.cpp}
/// for (const auto &[name, value] : cat.rows<std::string,int>("item_name", "item_value"))
/// std::cout << name << ": " << value << '\n';
/// @endcode
/// @endcode
///
/// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested
/// @tparam Ts The types for the items requested
/// @param names The names for the items requested
template <typename... Ts, typename... Ns>
iterator_proxy<const category, Ts...> rows(Ns... names) const
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of item names should be equal to the number of types to return");
return iterator_proxy<const category, Ts...>(*this, begin(), { names... });
}
......@@ -320,19 +348,19 @@ class category
/// for (const auto &[name, value] : cat.rows<std::string,int>("item_name", "item_value"))
/// std::cout << name << ": " << value << '\n';
///
/// // or in case we only need one column:
/// // or in case we only need one item:
///
/// for (int id : cat.rows<int>("id"))
/// std::cout << id << '\n';
/// @endcode
/// @endcode
///
/// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested
/// @tparam Ts The types for the items requested
/// @param names The names for the items requested
template <typename... Ts, typename... Ns>
iterator_proxy<category, Ts...> rows(Ns... names)
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of item names should be equal to the number of types to return");
return iterator_proxy<category, Ts...>(*this, begin(), { names... });
}
......@@ -343,7 +371,7 @@ class category
/// @code{.cpp}
/// for (row_handle rh : cat.find(cif::key("first_name") == "John" and cif::key("last_name") == "Doe"))
/// .. // do something with rh
/// @endcode
/// @endcode
///
/// @param cond The condition for the query
/// @return A special iterator that loops over all elements that match. The iterator can be dereferenced
......@@ -397,17 +425,17 @@ class category
/// @code{.cpp}
/// for (const auto &[name, value] : cat.find<std::string,int>(cif::key("item_value") > 10, "item_name", "item_value"))
/// std::cout << name << ": " << value << '\n';
/// @endcode
/// @endcode
///
/// @param cond The condition for the query
/// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested
/// @tparam Ts The types for the items requested
/// @param names The names for the items requested
/// @return A special iterator that loops over all elements that match.
template <typename... Ts, typename... Ns>
conditional_iterator_proxy<category, Ts...> find(condition &&cond, Ns... names)
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of item names should be equal to the number of types to return");
return find<Ts...>(cbegin(), std::move(cond), std::forward<Ns>(names)...);
}
......@@ -415,14 +443,14 @@ class category
/// iterator can be used in a structured binding context.
///
/// @param cond The condition for the query
/// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested
/// @tparam Ts The types for the items requested
/// @param names The names for the items requested
/// @return A special iterator that loops over all elements that match.
template <typename... Ts, typename... Ns>
conditional_iterator_proxy<const category, Ts...> find(condition &&cond, Ns... names) const
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of item names should be equal to the number of types to return");
return find<Ts...>(cbegin(), std::move(cond), std::forward<Ns>(names)...);
}
......@@ -431,14 +459,14 @@ class category
///
/// @param pos Iterator pointing to the location where to start
/// @param cond The condition for the query
/// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested
/// @tparam Ts The types for the items requested
/// @param names The names for the items requested
/// @return A special iterator that loops over all elements that match.
template <typename... Ts, typename... Ns>
conditional_iterator_proxy<category, Ts...> find(const_iterator pos, condition &&cond, Ns... names)
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of item names should be equal to the number of types to return");
return { *this, pos, std::move(cond), std::forward<Ns>(names)... };
}
......@@ -447,14 +475,14 @@ class category
///
/// @param pos Iterator pointing to the location where to start
/// @param cond The condition for the query
/// @tparam Ts The types for the columns requested
/// @param names The names for the columns requested
/// @tparam Ts The types for the items requested
/// @param names The names for the items requested
/// @return A special iterator that loops over all elements that match.
template <typename... Ts, typename... Ns>
conditional_iterator_proxy<const category, Ts...> find(const_iterator pos, condition &&cond, Ns... names) const
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of column titles should be equal to the number of types to return");
static_assert(sizeof...(Ts) == sizeof...(Ns), "The number of item names should be equal to the number of types to return");
return { *this, pos, std::move(cond), std::forward<Ns>(names)... };
}
......@@ -509,30 +537,30 @@ class category
return *h.begin();
}
/// @brief Return value for the column named @a column for the single row that
/// @brief Return value for the item named @a item for the single row that
/// matches @a cond. Throws @a multiple_results_error if there are is not exactly one row
/// @tparam The type to use for the result
/// @param cond The condition to search for
/// @param column The name of the column to return the value for
/// @param item The name of the item to return the value for
/// @return The value found
template <typename T>
T find1(condition &&cond, const char *column) const
T find1(condition &&cond, std::string_view item) const
{
return find1<T>(cbegin(), std::move(cond), column);
return find1<T>(cbegin(), std::move(cond), item);
}
/// @brief Return value for the column named @a column for the single row that
/// @brief Return value for the item named @a item for the single row that
/// matches @a cond when starting to search at @a pos.
/// Throws @a multiple_results_error if there are is not exactly one row
/// @tparam The type to use for the result
/// @param pos The location to start the search
/// @param cond The condition to search for
/// @param column The name of the column to return the value for
/// @param item The name of the item to return the value for
/// @return The value found
template <typename T, std::enable_if_t<not is_optional_v<T>, int> = 0>
T find1(const_iterator pos, condition &&cond, const char *column) const
T find1(const_iterator pos, condition &&cond, std::string_view item) const
{
auto h = find<T>(pos, std::move(cond), column);
auto h = find<T>(pos, std::move(cond), item);
if (h.size() != 1)
throw multiple_results_error();
......@@ -540,18 +568,18 @@ class category
return *h.begin();
}
/// @brief Return a value of type std::optional<T> for the column named @a column for the single row that
/// @brief Return a value of type std::optional<T> for the item named @a item for the single row that
/// matches @a cond when starting to search at @a pos.
/// If the row was not found, an empty value is returned.
/// @tparam The type to use for the result
/// @param pos The location to start the search
/// @param cond The condition to search for
/// @param column The name of the column to return the value for
/// @param item The name of the item to return the value for
/// @return The value found, can be empty if no row matches the condition
template <typename T, std::enable_if_t<is_optional_v<T>, int> = 0>
T find1(const_iterator pos, condition &&cond, const char *column) const
T find1(const_iterator pos, condition &&cond, std::string_view item) const
{
auto h = find<typename T::value_type>(pos, std::move(cond), column);
auto h = find<typename T::value_type>(pos, std::move(cond), item);
if (h.size() > 1)
throw multiple_results_error();
......@@ -562,34 +590,34 @@ class category
return *h.begin();
}
/// @brief Return a std::tuple for the values for the columns named in @a columns
/// @brief Return a std::tuple for the values for the items named in @a items
/// for the single row that matches @a cond
/// Throws @a multiple_results_error if there are is not exactly one row
/// @tparam The types to use for the resulting tuple
/// @param cond The condition to search for
/// @param columns The names of the columns to return the value for
/// @param items The names of the items to return the value for
/// @return The values found as a single tuple of type std::tuple<Ts...>
template <typename... Ts, typename... Cs, typename U = std::enable_if_t<sizeof...(Ts) != 1>>
std::tuple<Ts...> find1(condition &&cond, Cs... columns) const
std::tuple<Ts...> find1(condition &&cond, Cs... items) const
{
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of column titles should be equal to the number of types to return");
// static_assert(std::is_same_v<Cs, const char*>..., "The column names should be const char");
return find1<Ts...>(cbegin(), std::move(cond), std::forward<Cs>(columns)...);
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of item names should be equal to the number of types to return");
// static_assert(std::is_same_v<Cs, const char*>..., "The item names should be const char");
return find1<Ts...>(cbegin(), std::move(cond), std::forward<Cs>(items)...);
}
/// @brief Return a std::tuple for the values for the columns named in @a columns
/// @brief Return a std::tuple for the values for the items named in @a items
/// for the single row that matches @a cond when starting to search at @a pos
/// Throws @a multiple_results_error if there are is not exactly one row
/// @tparam The types to use for the resulting tuple
/// @param pos The location to start the search
/// @param cond The condition to search for
/// @param columns The names of the columns to return the value for
/// @param items The names of the items to return the value for
/// @return The values found as a single tuple of type std::tuple<Ts...>
template <typename... Ts, typename... Cs, typename U = std::enable_if_t<sizeof...(Ts) != 1>>
std::tuple<Ts...> find1(const_iterator pos, condition &&cond, Cs... columns) const
std::tuple<Ts...> find1(const_iterator pos, condition &&cond, Cs... items) const
{
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of column titles should be equal to the number of types to return");
auto h = find<Ts...>(pos, std::move(cond), std::forward<Cs>(columns)...);
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of item names should be equal to the number of types to return");
auto h = find<Ts...>(pos, std::move(cond), std::forward<Cs>(items)...);
if (h.size() != 1)
throw multiple_results_error();
......@@ -638,74 +666,74 @@ class category
return h.empty() ? row_handle{} : *h.begin();
}
/// @brief Return the value for column @a column for the first row that matches condition @a cond
/// @brief Return the value for item @a item for the first row that matches condition @a cond
/// @tparam The type of the value to return
/// @param cond The condition to search for
/// @param column The column for which the value should be returned
/// @param item The item for which the value should be returned
/// @return The value found or a default constructed value if not found
template <typename T>
T find_first(condition &&cond, const char *column) const
T find_first(condition &&cond, std::string_view item) const
{
return find_first<T>(cbegin(), std::move(cond), column);
return find_first<T>(cbegin(), std::move(cond), item);
}
/// @brief Return the value for column @a column for the first row that matches condition @a cond
/// @brief Return the value for item @a item for the first row that matches condition @a cond
/// when starting the search at @a pos
/// @tparam The type of the value to return
/// @param pos The location to start searching
/// @param cond The condition to search for
/// @param column The column for which the value should be returned
/// @param item The item for which the value should be returned
/// @return The value found or a default constructed value if not found
template <typename T>
T find_first(const_iterator pos, condition &&cond, const char *column) const
T find_first(const_iterator pos, condition &&cond, std::string_view item) const
{
auto h = find<T>(pos, std::move(cond), column);
auto h = find<T>(pos, std::move(cond), item);
return h.empty() ? T{} : *h.begin();
}
/// @brief Return a tuple containing the values for the columns @a columns for the first row that matches condition @a cond
/// @brief Return a tuple containing the values for the items @a items for the first row that matches condition @a cond
/// @tparam The types of the values to return
/// @param cond The condition to search for
/// @param columns The columns for which the values should be returned
/// @param items The items for which the values should be returned
/// @return The values found or default constructed values if not found
template <typename... Ts, typename... Cs, typename U = std::enable_if_t<sizeof...(Ts) != 1>>
std::tuple<Ts...> find_first(condition &&cond, Cs... columns) const
std::tuple<Ts...> find_first(condition &&cond, Cs... items) const
{
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of column titles should be equal to the number of types to return");
// static_assert(std::is_same_v<Cs, const char*>..., "The column names should be const char");
return find_first<Ts...>(cbegin(), std::move(cond), std::forward<Cs>(columns)...);
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of item names should be equal to the number of types to return");
// static_assert(std::is_same_v<Cs, const char*>..., "The item names should be const char");
return find_first<Ts...>(cbegin(), std::move(cond), std::forward<Cs>(items)...);
}
/// @brief Return a tuple containing the values for the columns @a columns for the first row that matches condition @a cond
/// @brief Return a tuple containing the values for the items @a items for the first row that matches condition @a cond
/// when starting the search at @a pos
/// @tparam The types of the values to return
/// @param pos The location to start searching
/// @param cond The condition to search for
/// @param columns The columns for which the values should be returned
/// @param items The items for which the values should be returned
/// @return The values found or default constructed values if not found
template <typename... Ts, typename... Cs, typename U = std::enable_if_t<sizeof...(Ts) != 1>>
std::tuple<Ts...> find_first(const_iterator pos, condition &&cond, Cs... columns) const
std::tuple<Ts...> find_first(const_iterator pos, condition &&cond, Cs... items) const
{
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of column titles should be equal to the number of types to return");
auto h = find<Ts...>(pos, std::move(cond), std::forward<Cs>(columns)...);
static_assert(sizeof...(Ts) == sizeof...(Cs), "The number of item names should be equal to the number of types to return");
auto h = find<Ts...>(pos, std::move(cond), std::forward<Cs>(items)...);
return h.empty() ? std::tuple<Ts...>{} : *h.begin();
}
// --------------------------------------------------------------------
/// @brief Return the maximum value for column @a column for all rows that match condition @a cond
/// @brief Return the maximum value for item @a item for all rows that match condition @a cond
/// @tparam The type of the value to return
/// @param column The column to use for the value
/// @param item The item to use for the value
/// @param cond The condition to search for
/// @return The value found or the minimal value for the type
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
T find_max(const char *column, condition &&cond) const
T find_max(std::string_view item, condition &&cond) const
{
T result = std::numeric_limits<T>::min();
for (auto v : find<T>(std::move(cond), column))
for (auto v : find<T>(std::move(cond), item))
{
if (result < v)
result = v;
......@@ -714,27 +742,27 @@ class category
return result;
}
/// @brief Return the maximum value for column @a column for all rows
/// @brief Return the maximum value for item @a item for all rows
/// @tparam The type of the value to return
/// @param column The column to use for the value
/// @param item The item to use for the value
/// @return The value found or the minimal value for the type
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
T find_max(const char *column) const
T find_max(std::string_view item) const
{
return find_max<T>(column, all());
return find_max<T>(item, all());
}
/// @brief Return the minimum value for column @a column for all rows that match condition @a cond
/// @brief Return the minimum value for item @a item for all rows that match condition @a cond
/// @tparam The type of the value to return
/// @param column The column to use for the value
/// @param item The item to use for the value
/// @param cond The condition to search for
/// @return The value found or the maximum value for the type
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
T find_min(const char *column, condition &&cond) const
T find_min(std::string_view item, condition &&cond) const
{
T result = std::numeric_limits<T>::max();
for (auto v : find<T>(std::move(cond), column))
for (auto v : find<T>(std::move(cond), item))
{
if (result > v)
result = v;
......@@ -743,20 +771,28 @@ class category
return result;
}
/// @brief Return the maximum value for column @a column for all rows
/// @brief Return the maximum value for item @a item for all rows
/// @tparam The type of the value to return
/// @param column The column to use for the value
/// @param item The item to use for the value
/// @return The value found or the maximum value for the type
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
T find_min(const char *column) const
T find_min(std::string_view item) const
{
return find_min<T>(column, all());
return find_min<T>(item, all());
}
/// @brief Return whether a row exists that matches condition @a cond
/// @param cond The condition to match
/// @return True if a row exists
bool exists(condition &&cond) const
[[deprecated("Use contains instead")]] bool exists(condition &&cond) const
{
return contains(std::move(cond));
}
/// @brief Return whether a row exists that matches condition @a cond
/// @param cond The condition to match
/// @return True if a row exists
bool contains(condition &&cond) const
{
bool result = false;
......@@ -846,7 +882,7 @@ class category
// insert_impl(pos, std::move(row));
// }
/// Erase the row pointed to by @a pos and return the iterator to the
/// Erase the row pointed to by @a pos and return the iterator to the
/// row following pos.
iterator erase(iterator pos);
......@@ -890,7 +926,7 @@ class category
for (auto i = b; i != e; ++i)
{
// item_value *new_item = this->create_item(*i);
r->append(add_column(i->name()), { i->value() });
r->append(add_item(i->name()), { i->value() });
}
}
catch (...)
......@@ -912,7 +948,6 @@ class category
/// result is unique in the context of this category
std::string get_unique_id(std::function<std::string(int)> generator = cif::cif_id_for_number);
/// @brief Generate a new, unique ID based on a string prefix followed by a number
/// @param prefix The string prefix
/// @return a new unique ID
......@@ -922,98 +957,201 @@ class category
{ return prefix + std::to_string(nr + 1); });
}
/// @brief Generate a new, unique value for a item named @a item_name
/// @param item_name The name of the item
/// @return a new unique value
std::string get_unique_value(std::string_view item_name);
// --------------------------------------------------------------------
/// \brief Update a single column named @a tag in the rows that match \a cond to value \a value
using value_provider_type = std::function<std::string_view(std::string_view)>;
/// \brief Update a single item named @a item_name in the rows that match
/// \a cond to values provided by a callback function \a value_provider
/// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split.
void update_value(condition &&cond, std::string_view tag, std::string_view value)
void update_value(condition &&cond, std::string_view item_name,
value_provider_type &&value_provider)
{
auto rs = find(std::move(cond));
std::vector<row_handle> rows;
std::copy(rs.begin(), rs.end(), std::back_inserter(rows));
update_value(rows, tag, value);
update_value(rows, item_name, std::move(value_provider));
}
/// \brief Update a single column named @a tag in @a rows to value \a value
/// \brief Update a single item named @a item_name in the rows \a rows
/// to values provided by a callback function \a value_provider
/// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split.
void update_value(const std::vector<row_handle> &rows, std::string_view tag, std::string_view value);
void update_value(const std::vector<row_handle> &rows, std::string_view item_name,
value_provider_type &&value_provider);
/// \brief Update a single item named @a item_name in the rows that match \a cond to value \a value
/// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split.
void update_value(condition &&cond, std::string_view item_name, std::string_view value)
{
auto rs = find(std::move(cond));
std::vector<row_handle> rows;
std::copy(rs.begin(), rs.end(), std::back_inserter(rows));
update_value(rows, item_name, value);
}
/// \brief Update a single item named @a item_name in @a rows to value \a value
/// making sure the linked categories are updated according to the link.
/// That means, child categories are updated if the links are absolute
/// and unique. If they are not, the child category rows are split.
void update_value(const std::vector<row_handle> &rows, std::string_view item_name, std::string_view value)
{
update_value(rows, item_name, [value](std::string_view) { return value; });
}
// --------------------------------------------------------------------
/// \brief Return the index number for \a column_name
// Naming used to be very inconsistent. For backward compatibility,
// the old function names are here as deprecated variants.
/// \brief Return the index number for \a column_name
[[deprecated("Use get_item_ix instead")]]
uint16_t get_column_ix(std::string_view column_name) const
{
return get_item_ix(column_name);
}
/// @brief Return the name for column with index @a ix
/// @param ix The index number
/// @return The name of the column
[[deprecated("use get_item_name instead")]]
std::string_view get_column_name(uint16_t ix) const
{
return get_item_name(ix);
}
/// @brief Make sure a item with name @a item_name is known and return its index number
/// @param item_name The name of the item
/// @return The index number of the item
[[deprecated("use add_item instead")]]
uint16_t add_column(std::string_view item_name)
{
return add_item(item_name);
}
/** @brief Remove column name @a colum_name
* @param column_name The column to be removed
*/
[[deprecated("use remove_item instead")]]
void remove_column(std::string_view column_name)
{
remove_item(column_name);
}
/** @brief Rename column @a from_name to @a to_name */
[[deprecated("use rename_item instead")]]
void rename_column(std::string_view from_name, std::string_view to_name)
{
rename_item(from_name, to_name);
}
/// @brief Return whether a column with name @a name exists in this category
/// @param name The name of the column
/// @return True if the column exists
[[deprecated("use has_item instead")]]
bool has_column(std::string_view name) const
{
return has_item(name);
}
/// @brief Return the cif::iset of columns in this category
[[deprecated("use get_items instead")]]
iset get_columns() const
{
return get_items();
}
// --------------------------------------------------------------------
/// \brief Return the index number for \a item_name
uint16_t get_item_ix(std::string_view item_name) const
{
uint16_t result;
for (result = 0; result < m_columns.size(); ++result)
for (result = 0; result < m_items.size(); ++result)
{
if (iequals(column_name, m_columns[result].m_name))
if (iequals(item_name, m_items[result].m_name))
break;
}
if (VERBOSE > 0 and result == m_columns.size() and m_cat_validator != nullptr) // validate the name, if it is known at all (since it was not found)
if (VERBOSE > 0 and result == m_items.size() and m_cat_validator != nullptr) // validate the name, if it is known at all (since it was not found)
{
auto iv = m_cat_validator->get_validator_for_item(column_name);
auto iv = m_cat_validator->get_validator_for_item(item_name);
if (iv == nullptr)
std::cerr << "Invalid name used '" << column_name << "' is not a known column in " + m_name << '\n';
std::cerr << "Invalid name used '" << item_name << "' is not a known item in " + m_name << '\n';
}
return result;
}
/// @brief Return the name for column with index @a ix
/// @brief Return the name for item with index @a ix
/// @param ix The index number
/// @return The name of the column
std::string_view get_column_name(uint16_t ix) const
/// @return The name of the item
std::string_view get_item_name(uint16_t ix) const
{
if (ix >= m_columns.size())
throw std::out_of_range("column index is out of range");
if (ix >= m_items.size())
throw std::out_of_range("item index is out of range");
return m_columns[ix].m_name;
return m_items[ix].m_name;
}
/// @brief Make sure a column with name @a column_name is known and return its index number
/// @param column_name The name of the column
/// @return The index number of the column
uint16_t add_column(std::string_view column_name)
/// @brief Make sure a item with name @a item_name is known and return its index number
/// @param item_name The name of the item
/// @return The index number of the item
uint16_t add_item(std::string_view item_name)
{
using namespace std::literals;
uint16_t result = get_column_ix(column_name);
uint16_t result = get_item_ix(item_name);
if (result == m_columns.size())
if (result == m_items.size())
{
const item_validator *item_validator = nullptr;
if (m_cat_validator != nullptr)
{
item_validator = m_cat_validator->get_validator_for_item(column_name);
item_validator = m_cat_validator->get_validator_for_item(item_name);
if (item_validator == nullptr)
m_validator->report_error("tag " + std::string(column_name) + " not allowed in category " + m_name, false);
m_validator->report_error( validation_error::item_not_allowed_in_category, m_name, item_name, false);
}
m_columns.emplace_back(column_name, item_validator);
m_items.emplace_back(item_name, item_validator);
}
return result;
}
/// @brief Return whether a column with name @a name exists in this category
/// @param name The name of the column
/// @return True if the column exists
bool has_column(std::string_view name) const
/** @brief Remove item name @a colum_name
* @param item_name The item to be removed
*/
void remove_item(std::string_view item_name);
/** @brief Rename item @a from_name to @a to_name */
void rename_item(std::string_view from_name, std::string_view to_name);
/// @brief Return whether a item with name @a name exists in this category
/// @param name The name of the item
/// @return True if the item exists
bool has_item(std::string_view name) const
{
return get_column_ix(name) < m_columns.size();
return get_item_ix(name) < m_items.size();
}
/// @brief Return the cif::iset of columns in this category
iset get_columns() const;
/// @brief Return the cif::iset of items in this category
iset get_items() const;
// --------------------------------------------------------------------
......@@ -1029,30 +1167,37 @@ class category
// --------------------------------------------------------------------
/// This function returns effectively the list of fully qualified column
/// names, that is category_name + '.' + column_name for each column
std::vector<std::string> get_tag_order() const;
/// This function returns effectively the list of fully qualified item
/// names, that is category_name + '.' + item_name for each item
[[deprecated("use get_item_order instead")]]
std::vector<std::string> get_tag_order() const
{
return get_item_order();
}
/// This function returns effectively the list of fully qualified item
/// names, that is category_name + '.' + item_name for each item
std::vector<std::string> get_item_order() const;
/// Write the contents of the category to the std::ostream @a os
void write(std::ostream &os) const;
/// @brief Write the contents of the category to the std::ostream @a os and
/// use @a order as the order of the columns. If @a addMissingColumns is
/// false, columns that do not contain any value will be suppressed
/// use @a order as the order of the items. If @a addMissingItems is
/// false, items that do not contain any value will be suppressed
/// @param os The std::ostream to write to
/// @param order The order in which the columns should appear
/// @param addMissingColumns When false, empty columns are suppressed from the output
void write(std::ostream &os, const std::vector<std::string> &order, bool addMissingColumns = true);
/// @param order The order in which the items should appear
/// @param addMissingItems When false, empty items are suppressed from the output
void write(std::ostream &os, const std::vector<std::string> &order, bool addMissingItems = true);
private:
void write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyColumns) const;
void write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyItems) const;
public:
/// friend function to make it possible to do:
/// @code {.cpp}
/// std::cout << my_category;
/// @endcode
/// @endcode
friend std::ostream &operator<<(std::ostream &os, const category &cat)
{
cat.write(os);
......@@ -1060,7 +1205,7 @@ class category
}
private:
void update_value(row *row, uint16_t column, std::string_view value, bool updateLinked, bool validate = true);
void update_value(row *row, uint16_t item, std::string_view value, bool updateLinked, bool validate = true);
void erase_orphans(condition &&cond, category &parent);
......@@ -1097,12 +1242,12 @@ class category
row_handle create_copy(row_handle r);
struct item_column
struct item_entry
{
std::string m_name;
const item_validator *m_validator;
item_column(std::string_view name, const item_validator *validator)
item_entry(std::string_view name, const item_validator *validator)
: m_name(name)
, m_validator(validator)
{
......@@ -1132,12 +1277,12 @@ class category
// --------------------------------------------------------------------
void swap_item(uint16_t column_ix, row_handle &a, row_handle &b);
void swap_item(uint16_t item_ix, row_handle &a, row_handle &b);
// --------------------------------------------------------------------
std::string m_name;
std::vector<item_column> m_columns;
std::vector<item_entry> m_items;
const validator *m_validator = nullptr;
const category_validator *m_cat_validator = nullptr;
std::vector<link> m_parent_links, m_child_links;
......
......@@ -166,6 +166,12 @@ class compound
return m_id == "HOH" or m_id == "H2O" or m_id == "WAT";
}
/** \brief Return whether this compound has a type of either 'peptide linking' or 'L-peptide linking' */
bool is_peptide() const;
/** \brief Return whether this compound has a type of either 'DNA linking' or 'RNA linking' */
bool is_base() const;
char one_letter_code() const { return m_one_letter_code; }; ///< Return the one letter code to use in a canonical sequence. If unknown the value '\0' is returned
std::string parent_id() const { return m_parent_id; }; ///< Return the parent id code in case a parent is specified (e.g. MET for MSE)
......@@ -237,25 +243,53 @@ class compound_factory
void pop_dictionary();
/// Return whether @a res_name is a valid and known peptide
[[deprecated("use is_peptide or is_std_peptide instead)")]]
bool is_known_peptide(const std::string &res_name) const;
/// Return whether @a res_name is a valid and known base
[[deprecated("use is_base or is_std_base instead)")]]
bool is_known_base(const std::string &res_name) const;
/// Return whether @a res_name is a peptide
bool is_peptide(std::string_view res_name) const;
/// Return whether @a res_name is a base
bool is_base(std::string_view res_name) const;
/// Return whether @a res_name is one of the standard peptides
bool is_std_peptide(std::string_view res_name) const;
/// Return whether @a res_name is one of the standard bases
bool is_std_base(std::string_view res_name) const;
/// Return whether @a res_name is a monomer (either base or peptide)
bool is_monomer(std::string_view res_name) const;
/// Return whether @a res_name is one of the standard bases or peptides
bool is_std_monomer(std::string_view res_name) const
{
return is_std_base(res_name) or is_std_peptide(res_name);
}
bool is_water(std::string_view res_name) const
{
return res_name == "HOH" or res_name == "H2O" or res_name == "WAT";
}
/// \brief Create the compound object for \a id
///
/// This will create the compound instance for \a id if it doesn't exist already.
/// The result is owned by this factory and should not be deleted by the user.
/// \param id The compound ID, a three letter code usually
/// \result The compound, or nullptr if it could not be created (missing info)
const compound *create(std::string id);
const compound *create(std::string_view id);
~compound_factory();
CIFPP_EXPORT static const std::map<std::string, char> kAAMap, ///< Globally accessible static list of the default amino acids
kBaseMap; ///< Globally accessible static list of the default bases
void report_missing_compound(const std::string &compound_id);
void report_missing_compound(std::string_view compound_id);
private:
compound_factory();
......
......@@ -39,17 +39,17 @@
* query you can use to find rows in a @ref cif::category
*
* Conditions are created as standard C++ expressions. That means
* you can use the standard comparison operators to compare field
* you can use the standard comparison operators to compare item
* contents with a value and boolean operators to chain everything
* together.
*
* To create a query that simply compares one field with one value:
* To create a query that simply compares one item with one value:
*
* @code {.cpp}
* cif::condition c = cif::key("id") == 1;
* @endcode
*
* That will find rows where the ID field contains the number 1. If
* That will find rows where the ID item contains the number 1. If
* using cif::key is a bit too much typing, you can also write:
*
* @code{.cpp}
......@@ -64,7 +64,7 @@
* auto c3 = "id"_key == 1 or "id"_key == 2;
* @endcode
*
* There are some special values you can use. To find rows with field that
* There are some special values you can use. To find rows with item that
* do not have a value:
*
* @code{.cpp}
......@@ -83,7 +83,7 @@
* auto c6 = cif::all;
* @endcode
*
* And when you want to search for any column containing the value 'foo':
* And when you want to search for any item containing the value 'foo':
*
* @code{.cpp}
* auto c7 = cif::any == "foo";
......@@ -104,31 +104,40 @@ namespace cif
/// we declare a function to access its contents
/**
* @brief Get the fields that can be used as key in conditions for a category
* @brief Get the items that can be used as key in conditions for a category
*
* @param cat The category whose fields to return
* @return iset The set of key field names
* @param cat The category whose items to return
* @return iset The set of key item names
*/
[[deprecated("use get_category_items instead")]]
iset get_category_fields(const category &cat);
/**
* @brief Get the column index for column @a col in category @a cat
* @brief Get the items that can be used as key in conditions for a category
*
* @param cat The category whose items to return
* @return iset The set of key field names
*/
iset get_category_items(const category &cat);
/**
* @brief Get the item index for item @a col in category @a cat
*
* @param cat The category
* @param col The name of the column
* @param col The name of the item
* @return uint16_t The index
*/
uint16_t get_column_ix(const category &cat, std::string_view col);
uint16_t get_item_ix(const category &cat, std::string_view col);
/**
* @brief Return whether the column @a col in category @a cat has a primitive type of *uchar*
* @brief Return whether the item @a col in category @a cat has a primitive type of *uchar*
*
* @param cat The category
* @param col The column name
* @param col The item name
* @return true If the primitive type is of type *uchar*
* @return false If the primitive type is not of type *uchar*
*/
bool is_column_type_uchar(const category &cat, std::string_view col);
bool is_item_type_uchar(const category &cat, std::string_view col);
// --------------------------------------------------------------------
// some more templates to be able to do querying
......@@ -219,7 +228,7 @@ class condition
/**
* @brief Prepare the condition to be used on category @a c. This will
* take care of setting the correct indices for fields e.g.
* take care of setting the correct indices for items e.g.
*
* @param c The category this query should act upon
*/
......@@ -305,14 +314,14 @@ namespace detail
{
struct key_is_empty_condition_impl : public condition_impl
{
key_is_empty_condition_impl(const std::string &item_tag)
: m_item_tag(item_tag)
key_is_empty_condition_impl(const std::string &item_name)
: m_item_name(item_name)
{
}
condition_impl *prepare(const category &c) override
{
m_item_ix = get_column_ix(c, m_item_tag);
m_item_ix = get_item_ix(c, m_item_name);
return this;
}
......@@ -323,23 +332,23 @@ namespace detail
void str(std::ostream &os) const override
{
os << m_item_tag << " IS NULL";
os << m_item_name << " IS NULL";
}
std::string m_item_tag;
std::string m_item_name;
uint16_t m_item_ix = 0;
};
struct key_is_not_empty_condition_impl : public condition_impl
{
key_is_not_empty_condition_impl(const std::string &item_tag)
: m_item_tag(item_tag)
key_is_not_empty_condition_impl(const std::string &item_name)
: m_item_name(item_name)
{
}
condition_impl *prepare(const category &c) override
{
m_item_ix = get_column_ix(c, m_item_tag);
m_item_ix = get_item_ix(c, m_item_name);
return this;
}
......@@ -350,18 +359,18 @@ namespace detail
void str(std::ostream &os) const override
{
os << m_item_tag << " IS NOT NULL";
os << m_item_name << " IS NOT NULL";
}
std::string m_item_tag;
std::string m_item_name;
uint16_t m_item_ix = 0;
};
struct key_equals_condition_impl : public condition_impl
{
key_equals_condition_impl(item &&i)
: m_item_tag(i.name())
, m_value(i.value())
: m_item_name(i.name())
, m_value(std::forward<item>(i).value())
{
}
......@@ -374,7 +383,7 @@ namespace detail
void str(std::ostream &os) const override
{
os << m_item_tag << (m_icase ? "^ " : " ") << " == " << m_value;
os << m_item_name << (m_icase ? "^ " : " ") << " == " << m_value;
}
virtual std::optional<row_handle> single() const override
......@@ -390,13 +399,13 @@ namespace detail
if (m_single_hit.has_value() or ri->m_single_hit.has_value())
return m_single_hit == ri->m_single_hit;
else
// watch out, both m_item_ix might be the same while tags might be diffent (in case they both do not exist in the category)
return m_item_ix == ri->m_item_ix and m_value == ri->m_value and m_item_tag == ri->m_item_tag;
// watch out, both m_item_ix might be the same while item_names might be diffent (in case they both do not exist in the category)
return m_item_ix == ri->m_item_ix and m_value == ri->m_value and m_item_name == ri->m_item_name;
}
return this == rhs;
}
std::string m_item_tag;
std::string m_item_name;
uint16_t m_item_ix = 0;
bool m_icase = false;
std::string m_value;
......@@ -406,7 +415,7 @@ namespace detail
struct key_equals_or_empty_condition_impl : public condition_impl
{
key_equals_or_empty_condition_impl(key_equals_condition_impl *equals)
: m_item_tag(equals->m_item_tag)
: m_item_name(equals->m_item_name)
, m_value(equals->m_value)
, m_icase(equals->m_icase)
, m_single_hit(equals->m_single_hit)
......@@ -415,8 +424,8 @@ namespace detail
condition_impl *prepare(const category &c) override
{
m_item_ix = get_column_ix(c, m_item_tag);
m_icase = is_column_type_uchar(c, m_item_tag);
m_item_ix = get_item_ix(c, m_item_name);
m_icase = is_item_type_uchar(c, m_item_name);
return this;
}
......@@ -432,7 +441,7 @@ namespace detail
void str(std::ostream &os) const override
{
os << '(' << m_item_tag << (m_icase ? "^ " : " ") << " == " << m_value << " OR " << m_item_tag << " IS NULL)";
os << '(' << m_item_name << (m_icase ? "^ " : " ") << " == " << m_value << " OR " << m_item_name << " IS NULL)";
}
virtual std::optional<row_handle> single() const override
......@@ -448,13 +457,13 @@ namespace detail
if (m_single_hit.has_value() or ri->m_single_hit.has_value())
return m_single_hit == ri->m_single_hit;
else
// watch out, both m_item_ix might be the same while tags might be diffent (in case they both do not exist in the category)
return m_item_ix == ri->m_item_ix and m_value == ri->m_value and m_item_tag == ri->m_item_tag;
// watch out, both m_item_ix might be the same while item_names might be diffent (in case they both do not exist in the category)
return m_item_ix == ri->m_item_ix and m_value == ri->m_value and m_item_name == ri->m_item_name;
}
return this == rhs;
}
std::string m_item_tag;
std::string m_item_name;
uint16_t m_item_ix = 0;
std::string m_value;
bool m_icase = false;
......@@ -464,8 +473,8 @@ namespace detail
struct key_compare_condition_impl : public condition_impl
{
template <typename COMP>
key_compare_condition_impl(const std::string &item_tag, COMP &&comp, const std::string &s)
: m_item_tag(item_tag)
key_compare_condition_impl(const std::string &item_name, COMP &&comp, const std::string &s)
: m_item_name(item_name)
, m_compare(std::move(comp))
, m_str(s)
{
......@@ -473,8 +482,8 @@ namespace detail
condition_impl *prepare(const category &c) override
{
m_item_ix = get_column_ix(c, m_item_tag);
m_icase = is_column_type_uchar(c, m_item_tag);
m_item_ix = get_item_ix(c, m_item_name);
m_icase = is_item_type_uchar(c, m_item_name);
return this;
}
......@@ -485,10 +494,10 @@ namespace detail
void str(std::ostream &os) const override
{
os << m_item_tag << (m_icase ? "^ " : " ") << m_str;
os << m_item_name << (m_icase ? "^ " : " ") << m_str;
}
std::string m_item_tag;
std::string m_item_name;
uint16_t m_item_ix = 0;
bool m_icase = false;
std::function<bool(row_handle, bool)> m_compare;
......@@ -497,8 +506,8 @@ namespace detail
struct key_matches_condition_impl : public condition_impl
{
key_matches_condition_impl(const std::string &item_tag, const std::regex &rx)
: m_item_tag(item_tag)
key_matches_condition_impl(const std::string &item_name, const std::regex &rx)
: m_item_name(item_name)
, m_item_ix(0)
, mRx(rx)
{
......@@ -506,7 +515,7 @@ namespace detail
condition_impl *prepare(const category &c) override
{
m_item_ix = get_column_ix(c, m_item_tag);
m_item_ix = get_item_ix(c, m_item_name);
return this;
}
......@@ -518,10 +527,10 @@ namespace detail
void str(std::ostream &os) const override
{
os << m_item_tag << " =~ expression";
os << m_item_name << " =~ expression";
}
std::string m_item_tag;
std::string m_item_name;
uint16_t m_item_ix;
std::regex mRx;
};
......@@ -541,7 +550,7 @@ namespace detail
auto &c = r.get_category();
bool result = false;
for (auto &f : get_category_fields(c))
for (auto &f : get_category_items(c))
{
try
{
......@@ -579,7 +588,7 @@ namespace detail
auto &c = r.get_category();
bool result = false;
for (auto &f : get_category_fields(c))
for (auto &f : get_category_items(c))
{
try
{
......@@ -864,7 +873,7 @@ inline condition operator or(condition &&a, condition &&b)
auto ci = static_cast<detail::key_equals_condition_impl *>(a.m_impl);
auto ce = static_cast<detail::key_is_empty_condition_impl *>(b.m_impl);
if (ci->m_item_tag == ce->m_item_tag)
if (ci->m_item_name == ce->m_item_name)
return condition(new detail::key_equals_or_empty_condition_impl(ci));
}
else if (typeid(*b.m_impl) == typeid(detail::key_equals_condition_impl) and
......@@ -873,7 +882,7 @@ inline condition operator or(condition &&a, condition &&b)
auto ci = static_cast<detail::key_equals_condition_impl *>(b.m_impl);
auto ce = static_cast<detail::key_is_empty_condition_impl *>(a.m_impl);
if (ci->m_item_tag == ce->m_item_tag)
if (ci->m_item_name == ce->m_item_name)
return condition(new detail::key_equals_or_empty_condition_impl(ci));
}
......@@ -887,7 +896,7 @@ inline condition operator or(condition &&a, condition &&b)
}
/**
* @brief A helper class to make it possible to search for empty fields (NULL)
* @brief A helper class to make it possible to search for empty items (NULL)
*
* @code{.cpp}
* "id"_key == cif::empty_type();
......@@ -909,35 +918,45 @@ struct empty_type
inline constexpr empty_type null = empty_type();
/**
* @brief Class to use in creating conditions, creates a reference to a field or column
* @brief Class to use in creating conditions, creates a reference to a item or item
*
*/
struct key
{
/**
* @brief Construct a new key object using @a itemTag as name
* @brief Construct a new key object using @a item_name as name
*
* @param item_name
*/
explicit key(const std::string &item_name)
: m_item_name(item_name)
{
}
/**
* @brief Construct a new key object using @a item_name as name
*
* @param itemTag
* @param item_name
*/
explicit key(const std::string &itemTag)
: m_item_tag(itemTag)
explicit key(const char *item_name)
: m_item_name(item_name)
{
}
/**
* @brief Construct a new key object using @a itemTag as name
* @brief Construct a new key object using @a item_name as name
*
* @param itemTag
* @param item_name
*/
explicit key(const char *itemTag)
: m_item_tag(itemTag)
explicit key(std::string_view item_name)
: m_item_name(item_name)
{
}
key(const key &) = delete;
key &operator=(const key &) = delete;
std::string m_item_tag; ///< The column name
std::string m_item_name; ///< The item name
};
/**
......@@ -946,7 +965,7 @@ struct key
template <typename T>
condition operator==(const key &key, const T &v)
{
return condition(new detail::key_equals_condition_impl({ key.m_item_tag, v }));
return condition(new detail::key_equals_condition_impl({ key.m_item_name, v }));
}
/**
......@@ -955,9 +974,9 @@ condition operator==(const key &key, const T &v)
inline condition operator==(const key &key, std::string_view value)
{
if (not value.empty())
return condition(new detail::key_equals_condition_impl({ key.m_item_tag, value }));
return condition(new detail::key_equals_condition_impl({ key.m_item_name, value }));
else
return condition(new detail::key_is_empty_condition_impl(key.m_item_tag));
return condition(new detail::key_is_empty_condition_impl(key.m_item_name));
}
/**
......@@ -987,8 +1006,8 @@ condition operator>(const key &key, const T &v)
s << " > " << v;
return condition(new detail::key_compare_condition_impl(
key.m_item_tag, [tag = key.m_item_tag, v](row_handle r, bool icase)
{ return r[tag].template compare<T>(v, icase) > 0; },
key.m_item_name, [item_name = key.m_item_name, v](row_handle r, bool icase)
{ return r[item_name].template compare<T>(v, icase) > 0; },
s.str()));
}
......@@ -1002,8 +1021,8 @@ condition operator>=(const key &key, const T &v)
s << " >= " << v;
return condition(new detail::key_compare_condition_impl(
key.m_item_tag, [tag = key.m_item_tag, v](row_handle r, bool icase)
{ return r[tag].template compare<T>(v, icase) >= 0; },
key.m_item_name, [item_name = key.m_item_name, v](row_handle r, bool icase)
{ return r[item_name].template compare<T>(v, icase) >= 0; },
s.str()));
}
......@@ -1017,8 +1036,8 @@ condition operator<(const key &key, const T &v)
s << " < " << v;
return condition(new detail::key_compare_condition_impl(
key.m_item_tag, [tag = key.m_item_tag, v](row_handle r, bool icase)
{ return r[tag].template compare<T>(v, icase) < 0; },
key.m_item_name, [item_name = key.m_item_name, v](row_handle r, bool icase)
{ return r[item_name].template compare<T>(v, icase) < 0; },
s.str()));
}
......@@ -1032,8 +1051,8 @@ condition operator<=(const key &key, const T &v)
s << " <= " << v;
return condition(new detail::key_compare_condition_impl(
key.m_item_tag, [tag = key.m_item_tag, v](row_handle r, bool icase)
{ return r[tag].template compare<T>(v, icase) <= 0; },
key.m_item_name, [item_name = key.m_item_name, v](row_handle r, bool icase)
{ return r[item_name].template compare<T>(v, icase) <= 0; },
s.str()));
}
......@@ -1042,7 +1061,7 @@ condition operator<=(const key &key, const T &v)
*/
inline condition operator==(const key &key, const std::regex &rx)
{
return condition(new detail::key_matches_condition_impl(key.m_item_tag, rx));
return condition(new detail::key_matches_condition_impl(key.m_item_name, rx));
}
/**
......@@ -1050,7 +1069,7 @@ inline condition operator==(const key &key, const std::regex &rx)
*/
inline condition operator==(const key &key, const empty_type &)
{
return condition(new detail::key_is_empty_condition_impl(key.m_item_tag));
return condition(new detail::key_is_empty_condition_impl(key.m_item_name));
}
/**
......@@ -1058,20 +1077,20 @@ inline condition operator==(const key &key, const empty_type &)
*/
inline condition operator!=(const key &key, const empty_type &)
{
return condition(new detail::key_is_not_empty_condition_impl(key.m_item_tag));
return condition(new detail::key_is_not_empty_condition_impl(key.m_item_name));
}
/**
* @brief Create a condition to search any column for a value @a v if @a v contains a value
* @brief Create a condition to search any item for a value @a v if @a v contains a value
* compare to null if not.
*/
template <typename T>
condition operator==(const key &key, const std::optional<T> &v)
{
if (v.has_value())
return condition(new detail::key_equals_condition_impl({ key.m_item_tag, *v }));
return condition(new detail::key_equals_condition_impl({ key.m_item_name, *v }));
else
return condition(new detail::key_is_empty_condition_impl(key.m_item_tag));
return condition(new detail::key_is_empty_condition_impl(key.m_item_name));
}
/**
......@@ -1089,12 +1108,12 @@ struct any_type
/** @endcond */
/**
* @brief A helper for any field constructs
* @brief A helper for any item constructs
*/
inline constexpr any_type any = any_type{};
/**
* @brief Create a condition to search any column for a value @a v
* @brief Create a condition to search any item for a value @a v
*/
template <typename T>
condition operator==(const any_type &, const T &v)
......@@ -1103,7 +1122,7 @@ condition operator==(const any_type &, const T &v)
}
/**
* @brief Create a condition to search any column for a regular expression @a rx
* @brief Create a condition to search any item for a regular expression @a rx
*/
inline condition operator==(const any_type &, const std::regex &rx)
{
......@@ -1121,9 +1140,9 @@ inline condition all()
namespace literals
{
/**
* @brief Return a cif::key for the column name @a text
* @brief Return a cif::key for the item name @a text
*
* @param text The name of the column
* @param text The name of the item
* @param length The length of @a text
* @return key The cif::key created
*/
......
......@@ -107,6 +107,15 @@ class datablock : public std::list<category>
bool is_valid() const;
/**
* @brief Validates the content of this datablock and all its content
* and updates or removes the audit_conform category to match the result.
*
* @return true If the content is valid
* @return false If the content is not valid
*/
bool is_valid();
/**
* @brief Validates all contained data for valid links between parents and children
* as defined in the validator
*
......@@ -169,7 +178,16 @@ class datablock : public std::list<category>
/**
* @brief Get the preferred order of the categories when writing them
*/
std::vector<std::string> get_tag_order() const;
[[deprecated("use get_item_order instead")]]
std::vector<std::string> get_tag_order() const
{
return get_item_order();
}
/**
* @brief Get the preferred order of the categories when writing them
*/
std::vector<std::string> get_item_order() const;
/**
* @brief Write out the contents to @a os
......@@ -177,9 +195,9 @@ class datablock : public std::list<category>
void write(std::ostream &os) const;
/**
* @brief Write out the contents to @a os using the order defined in @a tag_order
* @brief Write out the contents to @a os using the order defined in @a item_name_order
*/
void write(std::ostream &os, const std::vector<std::string> &tag_order);
void write(std::ostream &os, const std::vector<std::string> &item_name_order);
/**
* @brief Friend operator<< to write datablock @a db to std::ostream @a os
......
......@@ -44,7 +44,7 @@
/** \file item.hpp
*
* This file contains the declaration of item but also the item_value and item_handle
* These handle the storage of and access to the data for a single data field.
* These handle the storage of and access to the data for a single data item.
*/
namespace cif
......@@ -120,8 +120,6 @@ class item
if (r.ec != std::errc())
throw std::runtime_error("Could not format number");
assert(r.ptr >= buffer and r.ptr < buffer + sizeof(buffer));
*r.ptr = 0;
m_value.assign(buffer, r.ptr - buffer);
}
......@@ -141,8 +139,6 @@ class item
if (r.ec != std::errc())
throw std::runtime_error("Could not format number");
assert(r.ptr >= buffer and r.ptr < buffer + sizeof(buffer));
*r.ptr = 0;
m_value.assign(buffer, r.ptr - buffer);
}
......@@ -158,8 +154,6 @@ class item
if (r.ec != std::errc())
throw std::runtime_error("Could not format number");
assert(r.ptr >= buffer and r.ptr < buffer + sizeof(buffer));
*r.ptr = 0;
m_value.assign(buffer, r.ptr - buffer);
}
......@@ -174,13 +168,22 @@ class item
/// \brief constructor for an item with name \a name and as
/// content value \a value
item(const std::string_view name, const std::string_view value)
item(const std::string_view name, std::string_view value)
: m_name(name)
, m_value(value)
{
}
/// \brief constructor for an item with name \a name and as
/// content value \a value
template<typename T, std::enable_if_t<std::is_same_v<T, std::string>, int> = 0>
item(const std::string_view name, T &&value)
: m_name(name)
, m_value(std::move(value))
{
}
/// \brief constructor for an item with name \a name and as
/// content the optional value \a value
template <typename T>
item(const std::string_view name, const std::optional<T> &value)
......@@ -219,7 +222,8 @@ class item
/** @endcond */
std::string_view name() const { return m_name; } ///< Return the name of the item
std::string_view value() const { return m_value; } ///< Return the value of the item
std::string_view value() const & { return m_value; } ///< Return the value of the item
std::string value() const && { return std::move(m_value); } ///< Return the value of the item
/// \brief replace the content of the stored value with \a v
void value(std::string_view v) { m_value = v; }
......@@ -227,10 +231,10 @@ class item
/// \brief empty means either null or unknown
bool empty() const { return m_value.empty(); }
/// \brief returns true if the field contains '.'
/// \brief returns true if the item contains '.'
bool is_null() const { return m_value == "."; }
/// \brief returns true if the field contains '?'
/// \brief returns true if the item contains '?'
bool is_unknown() const { return m_value == "?"; }
/// \brief the length of the value string
......@@ -363,8 +367,35 @@ struct item_handle
template <typename T>
item_handle &operator=(const T &value)
{
item v{ "", value };
assign_value(v);
assign_value(item{ "", value }.value());
return *this;
}
/**
* @brief Assign value @a value to the item referenced
*
* @tparam T Type of the value
* @param value The value
* @return reference to this item_handle
*/
template <typename T>
item_handle &operator=(T &&value)
{
assign_value(item{ "", std::move(value) }.value());
return *this;
}
/**
* @brief Assign value @a value to the item referenced
*
* @tparam T Type of the value
* @param value The value
* @return reference to this item_handle
*/
template <size_t N>
item_handle &operator=(const char (&value)[N])
{
assign_value(item{ "", std::move(value) }.value());
return *this;
}
......@@ -464,14 +495,14 @@ struct item_handle
/** Easy way to test for an empty item */
explicit operator bool() const { return not empty(); }
/// is_null return true if the field contains '.'
/// is_null return true if the item contains '.'
bool is_null() const
{
auto txt = text();
return txt.length() == 1 and txt.front() == '.';
}
/// is_unknown returns true if the field contains '?'
/// is_unknown returns true if the item contains '?'
bool is_unknown() const
{
auto txt = text();
......@@ -484,11 +515,11 @@ struct item_handle
/**
* @brief Construct a new item handle object
*
* @param column Column index
* @param item Item index
* @param row Reference to the row
*/
item_handle(uint16_t column, row_handle &row)
: m_column(column)
item_handle(uint16_t item, row_handle &row)
: m_item_ix(item)
, m_row_handle(row)
{
}
......@@ -505,10 +536,10 @@ struct item_handle
private:
item_handle();
uint16_t m_column;
uint16_t m_item_ix;
row_handle &m_row_handle;
void assign_value(const item &value);
void assign_value(std::string_view value);
};
// So sad that older gcc implementations of from_chars did not support floats yet...
......@@ -556,7 +587,7 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
auto txt = ref.text();
if (txt.empty())
if (ref.empty())
result = 1;
else
{
......
......@@ -90,7 +90,7 @@ class iterator_impl
: m_category(rhs.m_category)
, m_current(rhs.m_current)
, m_value(rhs.m_value)
, m_column_ix(rhs.m_column_ix)
, m_item_ix(rhs.m_item_ix)
{
}
......@@ -99,7 +99,7 @@ class iterator_impl
: m_category(rhs.m_category)
, m_current(const_cast<row_type *>(rhs.m_current))
, m_value(rhs.m_value)
, m_column_ix(rhs.m_column_ix)
, m_item_ix(rhs.m_item_ix)
{
m_value = get(std::make_index_sequence<N>());
}
......@@ -108,7 +108,7 @@ class iterator_impl
iterator_impl(const iterator_impl<IRowType> &rhs, const std::array<uint16_t, N> &cix)
: m_category(rhs.m_category)
, m_current(rhs.m_current)
, m_column_ix(cix)
, m_item_ix(cix)
{
m_value = get(std::make_index_sequence<N>());
}
......@@ -117,7 +117,7 @@ class iterator_impl
{
m_category = i.m_category;
m_current = i.m_current;
m_column_ix = i.m_column_ix;
m_item_ix = i.m_item_ix;
m_value = i.m_value;
return *this;
}
......@@ -185,7 +185,7 @@ class iterator_impl
if (m_current != nullptr)
{
row_handle rh{ *m_category, *m_current };
return tuple_type{ rh[m_column_ix[Is]].template as<Ts>()... };
return tuple_type{ rh[m_item_ix[Is]].template as<Ts>()... };
}
return {};
......@@ -194,7 +194,7 @@ class iterator_impl
category_type *m_category = nullptr;
row_type *m_current = nullptr;
value_type m_value;
std::array<uint16_t, N> m_column_ix;
std::array<uint16_t, N> m_item_ix;
};
/**
......@@ -348,7 +348,7 @@ class iterator_impl<Category, T>
: m_category(rhs.m_category)
, m_current(rhs.m_current)
, m_value(rhs.m_value)
, m_column_ix(rhs.m_column_ix)
, m_item_ix(rhs.m_item_ix)
{
}
......@@ -357,7 +357,7 @@ class iterator_impl<Category, T>
: m_category(rhs.m_category)
, m_current(const_cast<row_type *>(rhs.m_current))
, m_value(rhs.m_value)
, m_column_ix(rhs.m_column_ix)
, m_item_ix(rhs.m_item_ix)
{
m_value = get(m_current);
}
......@@ -366,7 +366,7 @@ class iterator_impl<Category, T>
iterator_impl(const iterator_impl<IRowType> &rhs, const std::array<uint16_t, 1> &cix)
: m_category(rhs.m_category)
, m_current(rhs.m_current)
, m_column_ix(cix[0])
, m_item_ix(cix[0])
{
m_value = get();
}
......@@ -375,7 +375,7 @@ class iterator_impl<Category, T>
{
m_category = i.m_category;
m_current = i.m_current;
m_column_ix = i.m_column_ix;
m_item_ix = i.m_item_ix;
m_value = i.m_value;
return *this;
}
......@@ -442,7 +442,7 @@ class iterator_impl<Category, T>
if (m_current != nullptr)
{
row_handle rh{ *m_category, *m_current };
return rh[m_column_ix].template as<T>();
return rh[m_item_ix].template as<T>();
}
return {};
......@@ -451,7 +451,7 @@ class iterator_impl<Category, T>
category_type *m_category = nullptr;
row_type *m_current = nullptr;
value_type m_value;
uint16_t m_column_ix;
uint16_t m_item_ix;
};
// --------------------------------------------------------------------
......@@ -482,8 +482,8 @@ class iterator_proxy
using iterator = iterator_impl<category_type, Ts...>;
using row_iterator = iterator_impl<category_type>;
iterator_proxy(category_type &cat, row_iterator pos, char const *const columns[N]);
iterator_proxy(category_type &cat, row_iterator pos, std::initializer_list<char const *> columns);
iterator_proxy(category_type &cat, row_iterator pos, char const *const items[N]);
iterator_proxy(category_type &cat, row_iterator pos, std::initializer_list<char const *> items);
iterator_proxy(iterator_proxy &&p);
iterator_proxy &operator=(iterator_proxy &&p);
......@@ -492,8 +492,8 @@ class iterator_proxy
iterator_proxy &operator=(const iterator_proxy &) = delete;
/** @endcond */
iterator begin() const { return iterator(m_begin, m_column_ix); } ///< Return the iterator pointing to the first row
iterator end() const { return iterator(m_end, m_column_ix); } ///< Return the iterator pointing past the last row
iterator begin() const { return iterator(m_begin, m_item_ix); } ///< Return the iterator pointing to the first row
iterator end() const { return iterator(m_end, m_item_ix); } ///< Return the iterator pointing past the last row
bool empty() const { return m_begin == m_end; } ///< Return true if the range is empty
explicit operator bool() const { return not empty(); } ///< Easy way to detect if the range is empty
......@@ -510,13 +510,13 @@ class iterator_proxy
std::swap(m_category, rhs.m_category);
std::swap(m_begin, rhs.m_begin);
std::swap(m_end, rhs.m_end);
std::swap(m_column_ix, rhs.m_column_ix);
std::swap(m_item_ix, rhs.m_item_ix);
}
private:
category_type *m_category;
row_iterator m_begin, m_end;
std::array<uint16_t, N> m_column_ix;
std::array<uint16_t, N> m_item_ix;
};
// --------------------------------------------------------------------
......@@ -562,22 +562,23 @@ class conditional_iterator_proxy
reference operator*()
{
return *mBegin;
return *m_begin;
}
pointer operator->()
{
return &*mBegin;
m_current = *m_begin;
return &m_current;
}
conditional_iterator_impl &operator++()
{
while (mBegin != mEnd)
while (m_begin != m_end)
{
if (++mBegin == mEnd)
if (++m_begin == m_end)
break;
if (m_condition->operator()(mBegin))
if (m_condition->operator()(m_begin))
break;
}
......@@ -591,18 +592,22 @@ class conditional_iterator_proxy
return result;
}
bool operator==(const conditional_iterator_impl &rhs) const { return mBegin == rhs.mBegin; }
bool operator!=(const conditional_iterator_impl &rhs) const { return mBegin != rhs.mBegin; }
bool operator==(const conditional_iterator_impl &rhs) const { return m_begin == rhs.m_begin; }
bool operator!=(const conditional_iterator_impl &rhs) const { return m_begin != rhs.m_begin; }
bool operator==(const row_iterator &rhs) const { return m_begin == rhs; }
bool operator!=(const row_iterator &rhs) const { return m_begin != rhs; }
template <typename IRowType, typename... ITs>
bool operator==(const iterator_impl<IRowType, ITs...> &rhs) const { return mBegin == rhs; }
bool operator==(const iterator_impl<IRowType, ITs...> &rhs) const { return m_begin == rhs; }
template <typename IRowType, typename... ITs>
bool operator!=(const iterator_impl<IRowType, ITs...> &rhs) const { return mBegin != rhs; }
bool operator!=(const iterator_impl<IRowType, ITs...> &rhs) const { return m_begin != rhs; }
private:
CategoryType *mCat;
base_iterator mBegin, mEnd;
CategoryType *m_cat;
base_iterator m_begin, m_end;
value_type m_current;
const condition *m_condition;
};
......@@ -646,26 +651,26 @@ class conditional_iterator_proxy
/** @cond */
template <typename Category, typename... Ts>
iterator_proxy<Category, Ts...>::iterator_proxy(Category &cat, row_iterator pos, char const *const columns[N])
iterator_proxy<Category, Ts...>::iterator_proxy(Category &cat, row_iterator pos, char const *const items[N])
: m_category(&cat)
, m_begin(pos)
, m_end(cat.end())
{
for (uint16_t i = 0; i < N; ++i)
m_column_ix[i] = m_category->get_column_ix(columns[i]);
m_item_ix[i] = m_category->get_item_ix(items[i]);
}
template <typename Category, typename... Ts>
iterator_proxy<Category, Ts...>::iterator_proxy(Category &cat, row_iterator pos, std::initializer_list<char const *> columns)
iterator_proxy<Category, Ts...>::iterator_proxy(Category &cat, row_iterator pos, std::initializer_list<char const *> items)
: m_category(&cat)
, m_begin(pos)
, m_end(cat.end())
{
// static_assert(columns.size() == N, "The list of column names should be exactly the same as the list of requested columns");
// static_assert(items.size() == N, "The list of item names should be exactly the same as the list of requested items");
std::uint16_t i = 0;
for (auto column : columns)
m_column_ix[i++] = m_category->get_column_ix(column);
for (auto item : items)
m_item_ix[i++] = m_category->get_item_ix(item);
}
// --------------------------------------------------------------------
......@@ -673,13 +678,13 @@ iterator_proxy<Category, Ts...>::iterator_proxy(Category &cat, row_iterator pos,
template <typename Category, typename... Ts>
conditional_iterator_proxy<Category, Ts...>::conditional_iterator_impl::conditional_iterator_impl(
Category &cat, row_iterator pos, const condition &cond, const std::array<uint16_t, N> &cix)
: mCat(&cat)
, mBegin(pos, cix)
, mEnd(cat.end(), cix)
: m_cat(&cat)
, m_begin(pos, cix)
, m_end(cat.end(), cix)
, m_condition(&cond)
{
if (m_condition == nullptr or m_condition->empty())
mBegin = mEnd;
m_begin = m_end;
}
template <typename Category, typename... Ts>
......@@ -702,7 +707,7 @@ conditional_iterator_proxy<Category, Ts...>::conditional_iterator_proxy(Category
, mCBegin(pos)
, mCEnd(cat.end())
{
static_assert(sizeof...(Ts) == sizeof...(Ns), "Number of column names should be equal to number of requested value types");
static_assert(sizeof...(Ts) == sizeof...(Ns), "Number of item names should be equal to number of requested value types");
if (m_condition)
{
......@@ -715,7 +720,7 @@ conditional_iterator_proxy<Category, Ts...>::conditional_iterator_proxy(Category
mCBegin = mCEnd;
uint16_t i = 0;
((mCix[i++] = m_cat->get_column_ix(names)), ...);
((mCix[i++] = m_cat->get_item_ix(names)), ...);
}
template <typename Category, typename... Ts>
......
......@@ -72,7 +72,7 @@ class structure;
*
* The class atom is a kind of flyweight class. It can be copied
* with low overhead. All data is stored in the underlying mmCIF
* categories but some very often used fields are cached in the
* categories but some very often used items are cached in the
* impl.
*
* It is also possible to have symmetry copies of atoms. They
......@@ -207,7 +207,7 @@ class atom
/// \brief Copy assignement operator
atom &operator=(const atom &rhs) = default;
/// \brief Return the field named @a name in the _atom_site category for this atom
/// \brief Return the item named @a name in the _atom_site category for this atom
std::string get_property(std::string_view name) const
{
if (not m_impl)
......@@ -215,7 +215,7 @@ class atom
return m_impl->get_property(name);
}
/// \brief Return the field named @a name in the _atom_site category for this atom cast to an int
/// \brief Return the item named @a name in the _atom_site category for this atom cast to an int
int get_property_int(std::string_view name) const
{
if (not m_impl)
......@@ -223,7 +223,7 @@ class atom
return m_impl->get_property_int(name);
}
/// \brief Return the field named @a name in the _atom_site category for this atom cast to a float
/// \brief Return the item named @a name in the _atom_site category for this atom cast to a float
float get_property_float(std::string_view name) const
{
if (not m_impl)
......@@ -231,7 +231,7 @@ class atom
return m_impl->get_property_float(name);
}
/// \brief Set value for the field named @a name in the _atom_site category to @a value
/// \brief Set value for the item named @a name in the _atom_site category to @a value
void set_property(const std::string_view name, const std::string &value)
{
if (not m_impl)
......@@ -239,7 +239,7 @@ class atom
m_impl->set_property(name, value);
}
/// \brief Set value for the field named @a name in the _atom_site category to @a value
/// \brief Set value for the item named @a name in the _atom_site category to @a value
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
void set_property(const std::string_view name, const T &value)
{
......@@ -730,7 +730,7 @@ class sugar : public residue
/**
* @brief Return the sugar number in the glycosylation tree
*
* To store the sugar number, the auth_seq_id field has been overloaded
* To store the sugar number, the auth_seq_id item has been overloaded
* in the specification. But since a sugar number should be, ehm, a number
* and auth_seq_id is specified to contain a string, we do a check here
* to see if it really is a number.
......
......@@ -143,9 +143,9 @@ class sac_parser
enum class CIFToken
{
Unknown,
UNKNOWN,
Eof,
END_OF_FILE,
DATA,
LOOP,
......@@ -153,24 +153,24 @@ class sac_parser
SAVE_,
SAVE_NAME,
STOP,
Tag,
Value
ITEM_NAME,
VALUE
};
static constexpr const char *get_token_name(CIFToken token)
{
switch (token)
{
case CIFToken::Unknown: return "Unknown";
case CIFToken::Eof: return "Eof";
case CIFToken::UNKNOWN: return "Unknown";
case CIFToken::END_OF_FILE: return "Eof";
case CIFToken::DATA: return "DATA";
case CIFToken::LOOP: return "LOOP";
case CIFToken::GLOBAL: return "GLOBAL";
case CIFToken::SAVE_: return "SAVE";
case CIFToken::SAVE_NAME: return "SAVE+name";
case CIFToken::STOP: return "STOP";
case CIFToken::Tag: return "Tag";
case CIFToken::Value: return "Value";
case CIFToken::ITEM_NAME: return "Tag";
case CIFToken::VALUE: return "Value";
default: return "Invalid token parameter";
}
}
......@@ -267,9 +267,9 @@ class sac_parser
QuotedString,
QuotedStringQuote,
UnquotedString,
Tag,
TextField,
TextFieldNL,
ItemName,
TextItem,
TextItemNL,
Reserved,
Value
};
......
......@@ -28,6 +28,8 @@
#include "cif++/file.hpp"
#include <system_error>
/**
* @file pdb.hpp
*
......@@ -107,9 +109,10 @@ inline void write(const std::filesystem::path &p, const file &f)
*
* \param file The cif::file that hopefully contains some valid data
* \param dictionary The mmcif dictionary to use
* \result Returns true if the resulting file is valid
*/
void reconstruct_pdbx(file &pdbx_file, std::string_view dictionary = "mmcif_pdbx");
bool reconstruct_pdbx(file &pdbx_file, std::string_view dictionary = "mmcif_pdbx");
/** \brief This is an extension to cif::validator, use the logic in common
* PDBx files to see if the file is internally consistent.
......@@ -119,6 +122,8 @@ void reconstruct_pdbx(file &pdbx_file, std::string_view dictionary = "mmcif_pdbx
* atom_site -> pdbx_poly_seq_scheme -> entity_poly_seq -> entity_poly -> entity
*
* Use the common \ref cif::VERBOSE flag to turn on diagnostic messages.
*
* This function throws a std::system_error in case of an error
*
* \param file The input file
* \param dictionary The mmcif dictionary to use
......@@ -127,6 +132,43 @@ void reconstruct_pdbx(file &pdbx_file, std::string_view dictionary = "mmcif_pdbx
bool is_valid_pdbx_file(const file &pdbx_file, std::string_view dictionary = "mmcif_pdbx");
/** \brief This is an extension to cif::validator, use the logic in common
* PDBx files to see if the file is internally consistent.
*
* This function for now checks if the following categories are consistent:
*
* atom_site -> pdbx_poly_seq_scheme -> entity_poly_seq -> entity_poly -> entity
*
* Use the common \ref cif::VERBOSE flag to turn on diagnostic messages.
*
* The dictionary is assumed to be specified in the file or to be the
* default mmcif_pdbx.dic dictionary.
*
* \param file The input file
* \param ec The error_code in case something was wrong
* \result Returns true if the file was valid and consistent
*/
bool is_valid_pdbx_file(const file &pdbx_file, std::error_code &ec);
/** \brief This is an extension to cif::validator, use the logic in common
* PDBx files to see if the file is internally consistent.
*
* This function for now checks if the following categories are consistent:
*
* atom_site -> pdbx_poly_seq_scheme -> entity_poly_seq -> entity_poly -> entity
*
* Use the common \ref cif::VERBOSE flag to turn on diagnostic messages.
*
* \param file The input file
* \param dictionary The dictionary to use
* \param ec The error_code in case something was wrong
* \result Returns true if the file was valid and consistent
*/
bool is_valid_pdbx_file(const file &pdbx_file, std::string_view dictionary,
std::error_code &ec);
// --------------------------------------------------------------------
// Other I/O related routines
......
......@@ -35,7 +35,10 @@
#if __has_include(<clipper/core/coords.h>)
#define HAVE_LIBCLIPPER 1
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
#include <clipper/core/coords.h>
#pragma GCC diagnostic pop
#endif
/** \file point.hpp
......
......@@ -51,7 +51,7 @@
* std::string name = rh["label_atom_id"].as<std::string>();
*
* // by index:
* uint16_t ix = atom_site.get_column_ix("label_atom_id");
* uint16_t ix = atom_site.get_item_ix("label_atom_id");
* assert(rh[ix].as<std::string() == name);
* @endcode
*
......@@ -87,15 +87,15 @@ namespace detail
{
static constexpr size_t N = sizeof...(C);
get_row_result(const row_handle &r, std::array<uint16_t, N> &&columns)
get_row_result(const row_handle &r, std::array<uint16_t, N> &&items)
: m_row(r)
, m_columns(std::move(columns))
, m_items(std::move(items))
{
}
const item_handle operator[](uint16_t ix) const
{
return m_row[m_columns[ix]];
return m_row[m_items[ix]];
}
template <typename... Ts, std::enable_if_t<N == sizeof...(Ts), int> = 0>
......@@ -107,11 +107,11 @@ namespace detail
template <typename... Ts, size_t... Is>
std::tuple<Ts...> get(std::index_sequence<Is...>) const
{
return std::tuple<Ts...>{ m_row[m_columns[Is]].template as<Ts>()... };
return std::tuple<Ts...>{ m_row[m_items[Is]].template as<Ts>()... };
}
const row_handle &m_row;
std::array<uint16_t, N> m_columns;
std::array<uint16_t, N> m_items;
};
// we want to be able to tie some variables to a get_row_result, for this we use tiewraps
......@@ -244,70 +244,70 @@ class row_handle
return not empty();
}
/// \brief return a cif::item_handle to the item in column @a column_ix
item_handle operator[](uint16_t column_ix)
/// \brief return a cif::item_handle to the item in item @a item_ix
item_handle operator[](uint16_t item_ix)
{
return empty() ? item_handle::s_null_item : item_handle(column_ix, *this);
return empty() ? item_handle::s_null_item : item_handle(item_ix, *this);
}
/// \brief return a const cif::item_handle to the item in column @a column_ix
const item_handle operator[](uint16_t column_ix) const
/// \brief return a const cif::item_handle to the item in item @a item_ix
const item_handle operator[](uint16_t item_ix) const
{
return empty() ? item_handle::s_null_item : item_handle(column_ix, const_cast<row_handle &>(*this));
return empty() ? item_handle::s_null_item : item_handle(item_ix, const_cast<row_handle &>(*this));
}
/// \brief return a cif::item_handle to the item in the column named @a column_name
item_handle operator[](std::string_view column_name)
/// \brief return a cif::item_handle to the item in the item named @a item_name
item_handle operator[](std::string_view item_name)
{
return empty() ? item_handle::s_null_item : item_handle(add_column(column_name), *this);
return empty() ? item_handle::s_null_item : item_handle(add_item(item_name), *this);
}
/// \brief return a const cif::item_handle to the item in the column named @a column_name
const item_handle operator[](std::string_view column_name) const
/// \brief return a const cif::item_handle to the item in the item named @a item_name
const item_handle operator[](std::string_view item_name) const
{
return empty() ? item_handle::s_null_item : item_handle(get_column_ix(column_name), const_cast<row_handle &>(*this));
return empty() ? item_handle::s_null_item : item_handle(get_item_ix(item_name), const_cast<row_handle &>(*this));
}
/// \brief Return an object that can be used in combination with cif::tie
/// to assign the values for the columns @a columns
/// to assign the values for the items @a items
template <typename... C>
auto get(C... columns) const
auto get(C... items) const
{
return detail::get_row_result<C...>(*this, { get_column_ix(columns)... });
return detail::get_row_result<C...>(*this, { get_item_ix(items)... });
}
/// \brief Return a tuple of values of types @a Ts for the columns @a columns
/// \brief Return a tuple of values of types @a Ts for the items @a items
template <typename... Ts, typename... C, std::enable_if_t<sizeof...(Ts) == sizeof...(C) and sizeof...(C) != 1, int> = 0>
std::tuple<Ts...> get(C... columns) const
std::tuple<Ts...> get(C... items) const
{
return detail::get_row_result<Ts...>(*this, { get_column_ix(columns)... });
return detail::get_row_result<Ts...>(*this, { get_item_ix(items)... });
}
/// \brief Get the value of column @a column cast to type @a T
/// \brief Get the value of item @a item cast to type @a T
template <typename T>
T get(const char *column) const
T get(const char *item) const
{
return operator[](get_column_ix(column)).template as<T>();
return operator[](get_item_ix(item)).template as<T>();
}
/// \brief Get the value of column @a column cast to type @a T
/// \brief Get the value of item @a item cast to type @a T
template <typename T>
T get(std::string_view column) const
T get(std::string_view item) const
{
return operator[](get_column_ix(column)).template as<T>();
return operator[](get_item_ix(item)).template as<T>();
}
/// \brief assign each of the columns named in @a values to their respective value
/// \brief assign each of the items named in @a values to their respective value
void assign(const std::vector<item> &values)
{
for (auto &value : values)
assign(value, true);
}
/** \brief assign the value @a value to the column named @a name
/** \brief assign the value @a value to the item named @a name
*
* If updateLinked it true, linked records are updated as well.
* That means that if column @a name is part of the link definition
* That means that if item @a name is part of the link definition
* and the link results in a linked record in another category
* this record in the linked category is updated as well.
*
......@@ -317,13 +317,13 @@ class row_handle
void assign(std::string_view name, std::string_view value, bool updateLinked, bool validate = true)
{
assign(add_column(name), value, updateLinked, validate);
assign(add_item(name), value, updateLinked, validate);
}
/** \brief assign the value @a value to column at index @a column
/** \brief assign the value @a value to item at index @a item
*
* If updateLinked it true, linked records are updated as well.
* That means that if column @a column is part of the link definition
* That means that if item @a item is part of the link definition
* and the link results in a linked record in another category
* this record in the linked category is updated as well.
*
......@@ -331,7 +331,7 @@ class row_handle
* checked to see if it conforms to the rules defined in the dictionary
*/
void assign(uint16_t column, std::string_view value, bool updateLinked, bool validate = true);
void assign(uint16_t item, std::string_view value, bool updateLinked, bool validate = true);
/// \brief compare two rows
bool operator==(const row_handle &rhs) const { return m_category == rhs.m_category and m_row == rhs.m_row; }
......@@ -340,10 +340,10 @@ class row_handle
bool operator!=(const row_handle &rhs) const { return m_category != rhs.m_category or m_row != rhs.m_row; }
private:
uint16_t get_column_ix(std::string_view name) const;
std::string_view get_column_name(uint16_t ix) const;
uint16_t get_item_ix(std::string_view name) const;
std::string_view get_item_name(uint16_t ix) const;
uint16_t add_column(std::string_view name);
uint16_t add_item(std::string_view name);
row *get_row()
{
......@@ -360,7 +360,7 @@ class row_handle
assign(i.name(), i.value(), updateLinked);
}
void swap(uint16_t column, row_handle &r);
void swap(uint16_t item, row_handle &r);
category *m_category = nullptr;
row *m_row = nullptr;
......
......@@ -317,7 +317,7 @@ inline char tolower(int ch)
// --------------------------------------------------------------------
/** \brief return a tuple consisting of the category and item name for @a tag
/** \brief return a tuple consisting of the category and item name for @a item_name
*
* The category name is stripped of its leading underscore character.
*
......@@ -325,7 +325,19 @@ inline char tolower(int ch)
* cif 1.0 formatted data.
*/
std::tuple<std::string, std::string> split_tag_name(std::string_view tag);
[[deprecated("use split_item_name instead")]]
std::tuple<std::string, std::string> split_tag_name(std::string_view item_name);
/** \brief return a tuple consisting of the category and item name for @a item_name
*
* The category name is stripped of its leading underscore character.
*
* If no dot character was found, the category name is empty. That's for
* cif 1.0 formatted data.
*/
std::tuple<std::string, std::string> split_item_name(std::string_view item_name);
// --------------------------------------------------------------------
......
......@@ -28,9 +28,11 @@
#include "cif++/text.hpp"
#include <cassert>
#include <filesystem>
#include <list>
#include <mutex>
#include <system_error>
#include <utility>
/**
......@@ -49,27 +51,148 @@ namespace cif
struct category_validator;
// --------------------------------------------------------------------
// New: error_code
/**
* @brief The exception thrown when a validation error occurs
* @enum validation_error
*
* @brief A stronly typed class containing the error codes reported by @ref cif::validator and friends
*/
class validation_error : public std::exception
enum class validation_error
{
value_does_not_match_rx = 1, /**< The value of an item does not conform to the regular expression specified for it */
value_is_not_in_enumeration_list, /**< The value of an item is not in the list of values allowed */
not_a_known_primitive_type, /**< The type is not a known primitive type */
undefined_category, /**< Category has no definition in the dictionary */
unknown_item, /**< The item is not defined to be part of the category */
incorrect_item_validator, /**< Incorrectly specified validator for item */
missing_mandatory_items, /**< Missing mandatory items */
missing_key_items, /**< An index could not be constructed due to missing key items */
item_not_allowed_in_category, /**< Requested item allowed in category according to dictionary */
empty_file, /**< The file contains no datablocks */
empty_datablock, /**< The datablock contains no categories */
empty_category, /**< The category is empty */
not_valid_pdbx, /**< The file is not a valid PDBx file */
};
/**
* @brief The implementation for @ref validation_category error messages
*
*/
class validation_category_impl : public std::error_category
{
public:
/// @brief Constructor
validation_error(const std::string &msg);
/**
* @brief User friendly name
*
* @return const char*
*/
/// @brief Constructor
validation_error(const std::string &cat, const std::string &item,
const std::string &msg);
const char *name() const noexcept override
{
return "cif::validation";
}
/**
* @brief Provide the error message as a string for the error code @a ev
*
* @param ev The error code
* @return std::string
*/
std::string message(int ev) const override
{
switch (static_cast<validation_error>(ev))
{
case validation_error::value_does_not_match_rx:
return "Value in item does not match regular expression";
case validation_error::value_is_not_in_enumeration_list:
return "Value is not in the enumerated list of valid values";
case validation_error::not_a_known_primitive_type:
return "The type is not a known primitive type";
case validation_error::undefined_category:
return "Category has no definition in the dictionary";
case validation_error::unknown_item:
return "Item is not defined to be part of the category";
case validation_error::incorrect_item_validator:
return "Incorrectly specified validator for item";
case validation_error::missing_mandatory_items:
return "Missing mandatory items";
case validation_error::missing_key_items:
return "An index could not be constructed due to missing key items";
case validation_error::item_not_allowed_in_category:
return "Requested item allowed in category according to dictionary";
case validation_error::empty_file:
return "The file contains no datablocks";
case validation_error::empty_datablock:
return "The datablock contains no categories";
case validation_error::empty_category:
return "The category is empty";
case validation_error::not_valid_pdbx:
return "The file is not a valid PDBx file";
default:
assert(false);
return "unknown error code";
}
}
/**
* @brief Return whether two error codes are equivalent, always false in this case
*
*/
bool equivalent(const std::error_code & /*code*/, int /*condition*/) const noexcept override
{
return false;
}
};
/**
* @brief Return the implementation for the validation_category
*
* @return std::error_category&
*/
inline std::error_category &validation_category()
{
static validation_category_impl instance;
return instance;
}
inline std::error_code make_error_code(validation_error e)
{
return std::error_code(static_cast<int>(e), validation_category());
}
inline std::error_condition make_error_condition(validation_error e)
{
return std::error_condition(static_cast<int>(e), validation_category());
}
/// @brief The description of the error
const char *what() const noexcept { return m_msg.c_str(); }
// --------------------------------------------------------------------
class validation_exception : public std::runtime_error
{
public:
validation_exception(validation_error err)
: validation_exception(make_error_code(err))
{
}
validation_exception(validation_error err, std::string_view category)
: validation_exception(make_error_code(err), category)
{
}
/// @cond
std::string m_msg;
/// @endcond
validation_exception(validation_error err, std::string_view category, std::string_view item)
: validation_exception(make_error_code(err), category, item)
{
}
validation_exception(std::error_code ec);
validation_exception(std::error_code ec, std::string_view category);
validation_exception(std::error_code ec, std::string_view category, std::string_view item);
};
// --------------------------------------------------------------------
......@@ -85,6 +208,9 @@ enum class DDL_PrimitiveType
/// @brief Return the DDL_PrimitiveType encoded in @a s
DDL_PrimitiveType map_to_primitive_type(std::string_view s);
/// @brief Return the DDL_PrimitiveType encoded in @a s, error reporting variant
DDL_PrimitiveType map_to_primitive_type(std::string_view s, std::error_code &ec) noexcept;
struct regex_impl;
/**
......@@ -146,6 +272,26 @@ struct type_validator
int compare(std::string_view a, std::string_view b) const;
};
/** @brief Item alias, items can be renamed over time
*/
struct item_alias
{
item_alias(const std::string &alias_name, const std::string &dictionary, const std::string &version)
: m_name(alias_name)
, m_dict(dictionary)
, m_vers(version)
{
}
item_alias(const item_alias &) = default;
item_alias &operator=(const item_alias &) = default;
std::string m_name; ///< The alias_name
std::string m_dict; ///< The dictionary in which it was known
std::string m_vers; ///< The version of the dictionary
};
/**
* @brief An item_validator binds a type_validator to an item in
* a category along with other information found in the dictionary.
......@@ -157,28 +303,32 @@ struct type_validator
*/
struct item_validator
{
std::string m_tag; ///< The item name
std::string m_item_name; ///< The item name
bool m_mandatory; ///< Flag indicating this item is mandatory
const type_validator *m_type; ///< The type for this item
cif::iset m_enums; ///< If filled, the set of allowed values
std::string m_default; ///< If filled, a default value for this item
category_validator *m_category = nullptr; ///< The category_validator this item_validator belongs to
std::vector<item_alias> m_aliases; ///< The aliases for this item
/// @brief Compare based on the name
bool operator<(const item_validator &rhs) const
{
return icompare(m_tag, rhs.m_tag) < 0;
return icompare(m_item_name, rhs.m_item_name) < 0;
}
/// @brief Compare based on the name
bool operator==(const item_validator &rhs) const
{
return iequals(m_tag, rhs.m_tag);
return iequals(m_item_name, rhs.m_item_name);
}
/// @brief Validate the value in @a value for this item
/// Will throw a validation_error exception if it fails
/// Will throw a std::system_error exception if it fails
void operator()(std::string_view value) const;
/// @brief A more gentle version of value validation
bool validate_value(std::string_view value, std::error_code &ec) const noexcept;
};
/**
......@@ -191,8 +341,8 @@ struct category_validator
{
std::string m_name; ///< The name of the category
std::vector<std::string> m_keys; ///< The list of items that make up the key
cif::iset m_groups; ///< The category groups this category belongs to
cif::iset m_mandatory_fields; ///< The mandatory fields for this category
cif::iset m_groups; ///< The category groups this category belongs to
cif::iset m_mandatory_items; ///< The mandatory items for this category
std::set<item_validator> m_item_validators; ///< The item validators for the items in this category
/// @brief return true if this category sorts before @a rhs
......@@ -202,10 +352,13 @@ struct category_validator
}
/// @brief Add item_validator @a v to the list of item validators
void addItemValidator(item_validator &&v);
void add_item_validator(item_validator &&v);
/// @brief Return the item_validator for item @a tag, may return nullptr
const item_validator *get_validator_for_item(std::string_view tag) const;
/// @brief Return the item_validator for item @a item_name, may return nullptr
const item_validator *get_validator_for_item(std::string_view item_name) const;
/// @brief Return the item_validator for an item that has as alias name @a item_name, may return nullptr
const item_validator *get_validator_for_aliased_item(std::string_view item_name) const;
};
/**
......@@ -284,7 +437,24 @@ class validator
std::vector<const link_validator *> get_links_for_child(std::string_view category) const;
/// @brief Bottleneck function to report an error in validation
void report_error(const std::string &msg, bool fatal) const;
void report_error(validation_error err, bool fatal = true) const
{
report_error(make_error_code(err), fatal);
}
/// @brief Bottleneck function to report an error in validation
void report_error(std::error_code ec, bool fatal = true) const;
/// @brief Bottleneck function to report an error in validation
void report_error(validation_error err, std::string_view category,
std::string_view item, bool fatal = true) const
{
report_error(make_error_code(err), category, item, fatal);
}
/// @brief Bottleneck function to report an error in validation
void report_error(std::error_code ec, std::string_view category,
std::string_view item, bool fatal = true) const;
const std::string &name() const { return m_name; } ///< Get the name of this validator
void set_name(const std::string &name) { m_name = name; } ///< Set the name of this validator
......
......@@ -2712,4 +2712,96 @@ _pdbx_chem_comp_audit.processing_site
HIS "Create component" 1999-07-08 EBI
HIS "Modify descriptor" 2011-06-04 RCSB
#
data_HOH
#
_chem_comp.id HOH
_chem_comp.name WATER
_chem_comp.type NON-POLYMER
_chem_comp.pdbx_type HETAS
_chem_comp.formula "H2 O"
_chem_comp.mon_nstd_parent_comp_id ?
_chem_comp.pdbx_synonyms ?
_chem_comp.pdbx_formal_charge 0
_chem_comp.pdbx_initial_date 1999-07-08
_chem_comp.pdbx_modified_date 2011-06-04
_chem_comp.pdbx_ambiguous_flag N
_chem_comp.pdbx_release_status REL
_chem_comp.pdbx_replaced_by ?
_chem_comp.pdbx_replaces MTO
_chem_comp.formula_weight 18.015
_chem_comp.one_letter_code ?
_chem_comp.three_letter_code HOH
_chem_comp.pdbx_model_coordinates_details ?
_chem_comp.pdbx_model_coordinates_missing_flag N
_chem_comp.pdbx_ideal_coordinates_details ?
_chem_comp.pdbx_ideal_coordinates_missing_flag N
_chem_comp.pdbx_model_coordinates_db_code 1NHE
_chem_comp.pdbx_subcomponent_list ?
_chem_comp.pdbx_processing_site RCSB
# #
loop_
_chem_comp_atom.comp_id
_chem_comp_atom.atom_id
_chem_comp_atom.alt_atom_id
_chem_comp_atom.type_symbol
_chem_comp_atom.charge
_chem_comp_atom.pdbx_align
_chem_comp_atom.pdbx_aromatic_flag
_chem_comp_atom.pdbx_leaving_atom_flag
_chem_comp_atom.pdbx_stereo_config
_chem_comp_atom.model_Cartn_x
_chem_comp_atom.model_Cartn_y
_chem_comp_atom.model_Cartn_z
_chem_comp_atom.pdbx_model_Cartn_x_ideal
_chem_comp_atom.pdbx_model_Cartn_y_ideal
_chem_comp_atom.pdbx_model_Cartn_z_ideal
_chem_comp_atom.pdbx_component_atom_id
_chem_comp_atom.pdbx_component_comp_id
_chem_comp_atom.pdbx_ordinal
HOH O O O 0 1 N N N -23.107 18.401 -21.626 -0.064 0.000 0.000 O HOH 1
HOH H1 1H H 0 1 N N N -22.157 18.401 -21.626 0.512 0.000 -0.776 H1 HOH 2
HOH H2 2H H 0 1 N N N -23.424 18.401 -20.730 0.512 0.000 0.776 H2 HOH 3
# #
loop_
_chem_comp_bond.comp_id
_chem_comp_bond.atom_id_1
_chem_comp_bond.atom_id_2
_chem_comp_bond.value_order
_chem_comp_bond.pdbx_aromatic_flag
_chem_comp_bond.pdbx_stereo_config
_chem_comp_bond.pdbx_ordinal
HOH O H1 SING N N 1
HOH O H2 SING N N 2
# #
loop_
_pdbx_chem_comp_descriptor.comp_id
_pdbx_chem_comp_descriptor.type
_pdbx_chem_comp_descriptor.program
_pdbx_chem_comp_descriptor.program_version
_pdbx_chem_comp_descriptor.descriptor
HOH SMILES ACDLabs 10.04 O
HOH SMILES_CANONICAL CACTVS 3.341 O
HOH SMILES CACTVS 3.341 O
HOH SMILES_CANONICAL "OpenEye OEToolkits" 1.5.0 O
HOH SMILES "OpenEye OEToolkits" 1.5.0 O
HOH InChI InChI 1.03 InChI=1S/H2O/h1H2
HOH InChIKey InChI 1.03 XLYOFNOQVPJJNP-UHFFFAOYSA-N
# #
loop_
_pdbx_chem_comp_identifier.comp_id
_pdbx_chem_comp_identifier.type
_pdbx_chem_comp_identifier.program
_pdbx_chem_comp_identifier.program_version
_pdbx_chem_comp_identifier.identifier
HOH "SYSTEMATIC NAME" ACDLabs 10.04 water
HOH "SYSTEMATIC NAME" "OpenEye OEToolkits" 1.5.0 oxidane
# #
loop_
_pdbx_chem_comp_audit.comp_id
_pdbx_chem_comp_audit.action_type
_pdbx_chem_comp_audit.date
_pdbx_chem_comp_audit.processing_site
HOH "Create component" 1999-07-08 RCSB
HOH "Modify descriptor" 2011-06-04 RCSB
##
......@@ -33,7 +33,7 @@
#include <stack>
// TODO: Find out what the rules are exactly for linked items, the current implementation
// is inconsistent. It all depends whether a link is satified if a field taking part in the
// is inconsistent. It all depends whether a link is satified if a item taking part in the
// set of linked items is null at one side and not null in the other.
namespace cif
......@@ -52,7 +52,7 @@ class row_comparator
for (auto &k : cv->m_keys)
{
uint16_t ix = cat.add_column(k);
uint16_t ix = cat.add_item(k);
auto iv = cv->get_validator_for_item(k);
if (iv == nullptr)
......@@ -111,7 +111,7 @@ class row_comparator
if (d != 0)
break;
++ai;
}
......@@ -300,7 +300,7 @@ class category_index
return h;
}
// Fix m_next fields for rows in order of this index
// Fix m_next items for rows in order of this index
entry *reorder(entry *e)
{
auto result = e;
......@@ -356,11 +356,12 @@ row *category_index::find_by_value(const category &cat, row_initializer k) const
// sort the values in k first
row_initializer k2;
for (auto &f : cat.key_field_indices())
for (auto &f : cat.key_item_indices())
{
auto fld = cat.get_column_name(f);
auto fld = cat.get_item_name(f);
auto ki = find_if(k.begin(), k.end(), [&fld](auto &i) { return i.name() == fld; });
auto ki = find_if(k.begin(), k.end(), [&fld](auto &i)
{ return i.name() == fld; });
if (ki == k.end())
k2.emplace_back(fld, "");
else
......@@ -403,7 +404,7 @@ category_index::entry *category_index::insert(category &cat, entry *h, row *v)
row_handle rh(cat, *v);
std::ostringstream os;
for (auto col : cat.key_fields())
for (auto col : cat.key_items())
{
if (rh[col])
os << col << ": " << std::quoted(rh[col].text()) << "; ";
......@@ -507,7 +508,7 @@ category::category(std::string_view name)
category::category(const category &rhs)
: m_name(rhs.m_name)
, m_columns(rhs.m_columns)
, m_items(rhs.m_items)
, m_cascade(rhs.m_cascade)
{
for (auto r = rhs.m_head; r != nullptr; r = r->m_next)
......@@ -522,7 +523,7 @@ category::category(const category &rhs)
category::category(category &&rhs)
: m_name(std::move(rhs.m_name))
, m_columns(std::move(rhs.m_columns))
, m_items(std::move(rhs.m_items))
, m_validator(rhs.m_validator)
, m_cat_validator(rhs.m_cat_validator)
, m_parent_links(std::move(rhs.m_parent_links))
......@@ -545,7 +546,7 @@ category &category::operator=(const category &rhs)
clear();
m_name = rhs.m_name;
m_columns = rhs.m_columns;
m_items = rhs.m_items;
m_cascade = rhs.m_cascade;
m_validator = nullptr;
......@@ -572,7 +573,7 @@ category &category::operator=(category &&rhs)
if (this != &rhs)
{
m_name = std::move(rhs.m_name);
m_columns = std::move(rhs.m_columns);
m_items = std::move(rhs.m_items);
m_cascade = rhs.m_cascade;
m_validator = rhs.m_validator;
m_cat_validator = rhs.m_cat_validator;
......@@ -594,42 +595,75 @@ category::~category()
// --------------------------------------------------------------------
iset category::get_columns() const
void category::remove_item(std::string_view item_name)
{
for (size_t ix = 0; ix < m_items.size(); ++ix)
{
if (not iequals(item_name, m_items[ix].m_name))
continue;
for (row *r = m_head; r != nullptr; r = r->m_next)
{
if (r->size() > ix)
r->erase(r->begin() + ix);
}
m_items.erase(m_items.begin() + ix);
break;
}
}
void category::rename_item(std::string_view from_name, std::string_view to_name)
{
for (size_t ix = 0; ix < m_items.size(); ++ix)
{
if (not iequals(from_name, m_items[ix].m_name))
continue;
m_items[ix].m_name = to_name;
m_items[ix].m_validator = m_cat_validator ? m_cat_validator->get_validator_for_item(to_name) : nullptr;
break;
}
}
iset category::get_items() const
{
iset result;
for (auto &col : m_columns)
for (auto &col : m_items)
result.insert(col.m_name);
return result;
}
iset category::key_fields() const
iset category::key_items() const
{
if (m_validator == nullptr)
throw std::runtime_error("No Validator specified");
if (m_cat_validator == nullptr)
m_validator->report_error("undefined Category", true);
throw validation_exception(validation_error::undefined_category);
iset result;
for (auto &iv : m_cat_validator->m_item_validators)
result.insert(iv.m_tag);
result.insert(iv.m_item_name);
return result;
}
std::set<uint16_t> category::key_field_indices() const
std::set<uint16_t> category::key_item_indices() const
{
if (m_validator == nullptr)
throw std::runtime_error("No Validator specified");
if (m_cat_validator == nullptr)
m_validator->report_error("undefined Category", true);
throw validation_exception(validation_error::undefined_category);
std::set<uint16_t> result;
for (auto &k : m_cat_validator->m_keys)
result.insert(get_column_ix(k));
result.insert(get_item_ix(k));
return result;
}
......@@ -659,8 +693,8 @@ void category::set_validator(const validator *v, datablock &db)
std::vector<uint16_t> kix;
for (auto k : m_cat_validator->m_keys)
{
kix.push_back(get_column_ix(k));
if (kix.back() >= m_columns.size())
kix.push_back(get_item_ix(k));
if (kix.back() >= m_items.size())
missing.insert(k);
}
}
......@@ -670,17 +704,17 @@ void category::set_validator(const validator *v, datablock &db)
else
{
std::ostringstream msg;
msg << "Cannot construct index since the key field" << (missing.size() > 1 ? "s" : "") << " "
<< cif::join(missing, ", ") << " in " << m_name << " " << (missing.size() == 1 ? "is" : "are") << " missing\n";
throw std::runtime_error(msg.str());
msg << "Cannot construct index since the key item" << (missing.size() > 1 ? "s" : "") << " "
<< cif::join(missing, ", ") << " in " << m_name << " " << (missing.size() == 1 ? "is" : "are") << " missing\n";
throw missing_key_error(msg.str(), *missing.begin());
}
}
}
else
m_cat_validator = nullptr;
for (auto &&[column, cv] : m_columns)
cv = m_cat_validator ? m_cat_validator->get_validator_for_item(column) : nullptr;
for (auto &&[item, cv] : m_items)
cv = m_cat_validator ? m_cat_validator->get_validator_for_item(item) : nullptr;
update_links(db);
}
......@@ -726,31 +760,31 @@ bool category::is_valid() const
if (m_cat_validator == nullptr)
{
m_validator->report_error("undefined category " + m_name, false);
m_validator->report_error(validation_error::undefined_category, m_name, {}, false);
return false;
}
auto mandatory = m_cat_validator->m_mandatory_fields;
auto mandatory = m_cat_validator->m_mandatory_items;
for (auto &col : m_columns)
for (auto &col : m_items)
{
auto iv = m_cat_validator->get_validator_for_item(col.m_name);
if (iv == nullptr)
{
m_validator->report_error("Field " + col.m_name + " is not valid in category " + m_name, false);
m_validator->report_error(validation_error::unknown_item, col.m_name, m_name, false);
result = false;
}
// col.m_validator = iv;
if (col.m_validator != iv)
m_validator->report_error("Column validator is not specified correctly", true);
m_validator->report_error(validation_error::incorrect_item_validator, true);
mandatory.erase(col.m_name);
}
if (not mandatory.empty())
{
m_validator->report_error("In category " + m_name + " the following mandatory fields are missing: " + join(mandatory, ", "), false);
m_validator->report_error(validation_error::missing_mandatory_items, m_name, join(mandatory, ", "), false);
result = false;
}
......@@ -760,44 +794,44 @@ bool category::is_valid() const
for (auto k : m_cat_validator->m_keys)
{
if (get_column_ix(k) >= m_columns.size())
if (get_item_ix(k) >= m_items.size())
missing.insert(k);
}
m_validator->report_error("In category " + m_name + " the index is missing, likely due to missing key fields: " + join(missing, ", "), false);
m_validator->report_error(validation_error::missing_key_items, m_name, join(missing, ", "), false);
result = false;
}
#if not defined(NDEBUG)
// check index?
if (m_index)
{
if (m_index->size() != size())
m_validator->report_error("size of index is not equal to size of category " + m_name, true);
// #if not defined(NDEBUG)
// // check index?
// if (m_index)
// {
// if (m_index->size() != size())
// m_validator->report_error("size of index is not equal to size of category " + m_name, true);
// m_index->validate();
for (auto r : *this)
{
auto p = r.get_row();
if (m_index->find(*this, p) != p)
m_validator->report_error("Key not found in index for category " + m_name, true);
}
}
#endif
// // m_index->validate();
// for (auto r : *this)
// {
// auto p = r.get_row();
// if (m_index->find(*this, p) != p)
// m_validator->report_error("Key not found in index for category " + m_name, true);
// }
// }
// #endif
// validate all values
mandatory = m_cat_validator->m_mandatory_fields;
mandatory = m_cat_validator->m_mandatory_items;
for (auto ri = m_head; ri != nullptr; ri = ri->m_next)
{
for (uint16_t cix = 0; cix < m_columns.size(); ++cix)
for (uint16_t cix = 0; cix < m_items.size(); ++cix)
{
bool seen = false;
auto iv = m_columns[cix].m_validator;
auto iv = m_items[cix].m_validator;
if (iv == nullptr)
{
m_validator->report_error("invalid field " + m_columns[cix].m_name + " for category " + m_name, false);
// no need to report, should have been reported already above
result = false;
continue;
}
......@@ -806,14 +840,13 @@ bool category::is_valid() const
if (vi != nullptr)
{
seen = true;
try
{
(*iv)(vi->text());
}
catch (const std::exception &e)
std::error_code ec;
iv->validate_value(vi->text(), ec);
if (ec != std::errc())
{
result = false;
m_validator->report_error("Error validating " + m_columns[cix].m_name + ": " + e.what(), false);
m_validator->report_error(ec, m_name, m_items[cix].m_name, false);
continue;
}
}
......@@ -823,7 +856,7 @@ bool category::is_valid() const
if (iv != nullptr and iv->m_mandatory)
{
m_validator->report_error("missing mandatory field " + m_columns[cix].m_name + " for category " + m_name, false);
m_validator->report_error(validation_error::missing_mandatory_items, m_name, m_items[cix].m_name, false);
result = false;
}
}
......@@ -860,7 +893,7 @@ bool category::validate_links() const
auto cond = get_parents_condition(r, *parent);
if (not cond)
continue;
if (not parent->exists(std::move(cond)))
if (not parent->contains(std::move(cond)))
{
++missing;
if (VERBOSE and first_missing_rows.size() < 5)
......@@ -873,12 +906,12 @@ bool category::validate_links() const
result = false;
std::cerr << "Links for " << link.v->m_link_group_label << " are incomplete\n"
<< " There are " << missing << " items in " << m_name << " that don't have matching parent items in " << parent->m_name << '\n';
<< " There are " << missing << " items in " << m_name << " that don't have matching parent items in " << parent->m_name << '\n';
if (VERBOSE)
{
std::cerr << "showing first " << first_missing_rows.size() << " rows\n"
<< '\n';
std::cerr << "showing first " << first_missing_rows.size() << " rows\n"
<< '\n';
first_missing_rows.write(std::cerr, link.v->m_child_keys, false);
......@@ -919,7 +952,9 @@ condition category::get_parents_condition(row_handle rh, const category &parentC
condition result;
auto links = m_validator->get_links_for_child(m_name);
links.erase(remove_if(links.begin(), links.end(), [n=parentCat.m_name](auto &l) { return l->m_parent_category != n; }), links.end());
links.erase(remove_if(links.begin(), links.end(), [n = parentCat.m_name](auto &l)
{ return l->m_parent_category != n; }),
links.end());
if (not links.empty())
{
......@@ -953,13 +988,15 @@ condition category::get_children_condition(row_handle rh, const category &childC
condition result;
iset mandatoryChildFields;
iset mandatoryChildItems;
auto childCatValidator = m_validator->get_validator_for_category(childCat.name());
if (childCatValidator != nullptr)
mandatoryChildFields = childCatValidator->m_mandatory_fields;
mandatoryChildItems = childCatValidator->m_mandatory_items;
auto links = m_validator->get_links_for_parent(m_name);
links.erase(remove_if(links.begin(), links.end(), [n=childCat.m_name](auto &l) { return l->m_child_category != n; }), links.end());
links.erase(remove_if(links.begin(), links.end(), [n = childCat.m_name](auto &l)
{ return l->m_child_category != n; }),
links.end());
if (not links.empty())
{
......@@ -976,7 +1013,7 @@ condition category::get_children_condition(row_handle rh, const category &childC
if (parentValue.empty())
cond = std::move(cond) and key(childKey) == null;
else if (link->m_parent_keys.size() > 1 and not mandatoryChildFields.contains(childKey))
else if (link->m_parent_keys.size() > 1 and not mandatoryChildItems.contains(childKey))
cond = std::move(cond) and (key(childKey) == parentValue.text() or key(childKey) == null);
else
cond = std::move(cond) and key(childKey) == parentValue.text();
......@@ -997,7 +1034,7 @@ bool category::has_children(row_handle r) const
for (auto &&[childCat, link] : m_child_links)
{
if (not childCat->exists(get_children_condition(r, *childCat)))
if (not childCat->contains(get_children_condition(r, *childCat)))
continue;
result = true;
......@@ -1013,7 +1050,7 @@ bool category::has_parents(row_handle r) const
for (auto &&[parentCat, link] : m_parent_links)
{
if (not parentCat->exists(get_parents_condition(r, *parentCat)))
if (not parentCat->contains(get_parents_condition(r, *parentCat)))
continue;
result = true;
......@@ -1123,7 +1160,7 @@ category::iterator category::erase(iterator pos)
return result;
}
template<typename T>
template <typename T>
class save_value
{
public:
......@@ -1213,8 +1250,8 @@ void category::erase_orphans(condition &&cond, category &parent)
{
if (not cond(r))
continue;
if (parent.exists(get_parents_condition(r, parent)))
if (parent.contains(get_parents_condition(r, parent)))
continue;
if (VERBOSE > 1)
......@@ -1222,11 +1259,10 @@ void category::erase_orphans(condition &&cond, category &parent)
category c(m_name);
c.emplace(r);
std::cerr << "Removing orphaned record: \n"
<< c << '\n'
<< '\n';
<< c << '\n'
<< '\n';
}
remove.emplace_back(r.m_row);
}
......@@ -1244,17 +1280,17 @@ std::string category::get_unique_id(std::function<std::string(int)> generator)
std::string result = generator(static_cast<int>(m_last_unique_num++));
std::string id_tag = "id";
std::string id_name = "id";
if (m_cat_validator != nullptr and m_cat_validator->m_keys.size() == 1)
{
id_tag = m_cat_validator->m_keys.front();
id_name = m_cat_validator->m_keys.front();
if (m_index == nullptr and m_cat_validator != nullptr)
m_index = new category_index(*this);
for (;;)
{
if (m_index->find_by_value(*this, {{ id_tag, result }}) == nullptr)
if (m_index->find_by_value(*this, { { id_name, result } }) == nullptr)
break;
result = generator(static_cast<int>(m_last_unique_num++));
}
......@@ -1263,9 +1299,9 @@ std::string category::get_unique_id(std::function<std::string(int)> generator)
{
for (;;)
{
if (not exists(key(id_tag) == result))
if (not contains(key(id_name) == result))
break;
result = generator(static_cast<int>(m_last_unique_num++));
}
}
......@@ -1273,57 +1309,89 @@ std::string category::get_unique_id(std::function<std::string(int)> generator)
return result;
}
void category::update_value(const std::vector<row_handle> &rows, std::string_view tag, std::string_view value)
std::string category::get_unique_value(std::string_view item_name)
{
std::string result;
if (m_validator and m_cat_validator)
{
auto iv = m_cat_validator->get_validator_for_item(item_name);
if (iv and iv->m_type and iv->m_type->m_primitive_type == DDL_PrimitiveType::Numb)
{
uint64_t v = find_max<uint64_t>(item_name);
result = std::to_string(v + 1);
}
}
if (result.empty())
{
// brain-dead implementation
for (size_t ix = 0; ix < size(); ++ix)
{
// result = m_name + "-" + std::to_string(ix);
result = cif_id_for_number(ix);
if (not contains(key(item_name) == result))
break;
}
}
return result;
}
void category::update_value(const std::vector<row_handle> &rows, std::string_view item_name,
value_provider_type &&value_provider)
{
using namespace std::literals;
if (rows.empty())
return;
auto colIx = get_column_ix(tag);
if (colIx >= m_columns.size())
throw std::runtime_error("Invalid column " + std::string{ value } + " for " + m_name);
auto colIx = get_item_ix(item_name);
if (colIx >= m_items.size())
throw validation_exception(validation_error::unknown_item, m_name, item_name);
auto &col = m_columns[colIx];
auto &col = m_items[colIx];
// this is expensive, but better throw early on
// check the value
if (col.m_validator)
(*col.m_validator)(value);
// first some sanity checks, what was the old value and is it the same for all rows?
std::string oldValue{ rows.front()[tag].text() };
for (auto row : rows)
{
if (oldValue != row[tag].text())
throw std::runtime_error("Inconsistent old values in update_value");
}
if (oldValue == value) // no need to do anything
return;
for (auto row : rows)
{
std::string value{ value_provider(row[item_name].text()) };
// update rows, but do not cascade
for (auto row : rows)
row.assign(colIx, value, false);
std::error_code ec;
col.m_validator->validate_value(value, ec);
if (ec)
throw validation_exception(ec, m_name, item_name);
}
}
// see if we need to update any child categories that depend on this value
// update and see if we need to update any child categories that depend on this value
for (auto parent : rows)
{
std::string oldValue{ parent[item_name].text() };
std::string value{ value_provider(oldValue) };
parent.assign(colIx, value, false);
for (auto &&[childCat, linked] : m_child_links)
{
if (std::find(linked->m_parent_keys.begin(), linked->m_parent_keys.end(), tag) == linked->m_parent_keys.end())
if (std::find(linked->m_parent_keys.begin(), linked->m_parent_keys.end(), item_name) == linked->m_parent_keys.end())
continue;
condition cond;
std::string childTag;
std::string childItemName;
for (size_t ix = 0; ix < linked->m_parent_keys.size(); ++ix)
{
std::string pk = linked->m_parent_keys[ix];
std::string ck = linked->m_child_keys[ix];
if (pk == tag)
if (pk == item_name)
{
childTag = ck;
childItemName = ck;
cond = std::move(cond) && key(ck) == oldValue;
}
else
......@@ -1370,13 +1438,13 @@ void category::update_value(const std::vector<row_handle> &rows, std::string_vie
std::string pk = linked->m_parent_keys[ix];
std::string ck = linked->m_child_keys[ix];
if (pk == tag)
if (pk == item_name)
check = std::move(check) && key(ck) == value;
else
check = std::move(check) && key(ck) == parent[pk].text();
}
if (childCat->exists(std::move(check))) // phew..., narrow escape
if (childCat->contains(std::move(check))) // phew..., narrow escape
continue;
// create the actual copy, if we can...
......@@ -1392,27 +1460,27 @@ void category::update_value(const std::vector<row_handle> &rows, std::string_vie
// cannot update this...
if (cif::VERBOSE > 0)
std::cerr << "Cannot update child " << childCat->m_name << "." << childTag << " with value " << value << '\n';
std::cerr << "Cannot update child " << childCat->m_name << "." << childItemName << " with value " << value << '\n';
}
// finally, update the children
if (not process.empty())
childCat->update_value(process, childTag, value);
childCat->update_value(process, childItemName, value);
}
}
}
void category::update_value(row *row, uint16_t column, std::string_view value, bool updateLinked, bool validate)
void category::update_value(row *row, uint16_t item, std::string_view value, bool updateLinked, bool validate)
{
// make sure we have an index, if possible
if (m_index == nullptr and m_cat_validator != nullptr)
if ((updateLinked or validate) and m_index == nullptr and m_cat_validator != nullptr)
m_index = new category_index(*this);
auto &col = m_columns[column];
auto &col = m_items[item];
std::string_view oldValue;
auto ival = row->get(column);
auto ival = row->get(item);
if (ival != nullptr)
oldValue = ival->text();
......@@ -1425,12 +1493,12 @@ void category::update_value(row *row, uint16_t column, std::string_view value, b
if (col.m_validator and validate)
col.m_validator->operator()(value);
// If the field is part of the Key for this category, remove it from the index
// If the item is part of the Key for this category, remove it from the index
// before updating
bool reinsert = false;
if (updateLinked and // an update of an Item's value
m_index != nullptr and key_field_indices().count(column))
m_index != nullptr and key_item_indices().count(item))
{
reinsert = m_index->find(*this, row);
if (reinsert)
......@@ -1439,12 +1507,12 @@ void category::update_value(row *row, uint16_t column, std::string_view value, b
// first remove old value with cix
if (ival != nullptr)
row->remove(column);
row->remove(item);
if (not value.empty())
row->append(column, { value });
row->append(item, { value });
if (reinsert)
if (reinsert and m_index != nullptr)
m_index->insert(*this, row);
// see if we need to update any child categories that depend on this value
......@@ -1455,22 +1523,22 @@ void category::update_value(row *row, uint16_t column, std::string_view value, b
for (auto &&[childCat, linked] : m_child_links)
{
if (std::find(linked->m_parent_keys.begin(), linked->m_parent_keys.end(), iv->m_tag) == linked->m_parent_keys.end())
if (std::find(linked->m_parent_keys.begin(), linked->m_parent_keys.end(), iv->m_item_name) == linked->m_parent_keys.end())
continue;
condition cond;
std::string childTag;
std::string childItemName;
for (size_t ix = 0; ix < linked->m_parent_keys.size(); ++ix)
{
std::string pk = linked->m_parent_keys[ix];
std::string ck = linked->m_child_keys[ix];
// TODO: add code to *NOT* test mandatory fields for Empty
// TODO: add code to *NOT* test mandatory items for Empty
if (pk == iv->m_tag)
if (pk == iv->m_item_name)
{
childTag = ck;
childItemName = ck;
cond = std::move(cond) and key(ck) == oldStrValue;
}
else
......@@ -1503,7 +1571,7 @@ void category::update_value(row *row, uint16_t column, std::string_view value, b
std::string pk = linked->m_parent_keys[ix];
std::string ck = linked->m_child_keys[ix];
if (pk == iv->m_tag)
if (pk == iv->m_item_name)
cond_n = std::move(cond_n) and key(ck) == value;
else
{
......@@ -1525,7 +1593,7 @@ void category::update_value(row *row, uint16_t column, std::string_view value, b
}
for (auto cr : rows)
cr.assign(childTag, value, false);
cr.assign(childItemName, value, false);
}
}
}
......@@ -1541,8 +1609,8 @@ row *category::clone_row(const row &r)
auto &i = r[ix];
if (not i)
continue;
result->append( ix, { i.text() });
result->append(ix, { i.text() });
}
}
catch (...)
......@@ -1573,7 +1641,7 @@ row_handle category::create_copy(row_handle r)
{
auto i = r.m_row->get(ix);
if (i != nullptr)
items.emplace_back(m_columns[ix].m_name, i->text());
items.emplace_back(m_items[ix].m_name, i->text());
}
if (m_cat_validator and m_cat_validator->m_keys.size() == 1)
......@@ -1609,19 +1677,19 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
if (n == nullptr)
throw std::runtime_error("Invalid pointer passed to insert");
// #ifndef NDEBUG
// if (m_validator)
// is_valid();
// #endif
// #ifndef NDEBUG
// if (m_validator)
// is_valid();
// #endif
try
{
// First, make sure all mandatory fields are supplied
// First, make sure all mandatory items are supplied
if (m_cat_validator != nullptr)
{
for (uint16_t ix = 0; ix < static_cast<uint16_t>(m_columns.size()); ++ix)
for (uint16_t ix = 0; ix < static_cast<uint16_t>(m_items.size()); ++ix)
{
const auto &[column, iv] = m_columns[ix];
const auto &[item, iv] = m_items[ix];
if (iv == nullptr)
continue;
......@@ -1636,7 +1704,7 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
}
if (not seen and iv->m_mandatory)
throw std::runtime_error("missing mandatory field " + column + " for category " + m_name);
throw std::runtime_error("missing mandatory item " + item + " for category " + m_name);
}
}
......@@ -1669,13 +1737,13 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
throw;
}
// #ifndef NDEBUG
// if (m_validator)
// is_valid();
// #endif
// #ifndef NDEBUG
// if (m_validator)
// is_valid();
// #endif
}
void category::swap_item(uint16_t column_ix, row_handle &a, row_handle &b)
void category::swap_item(uint16_t item_ix, row_handle &a, row_handle &b)
{
assert(this == a.m_category);
assert(this == b.m_category);
......@@ -1683,10 +1751,10 @@ void category::swap_item(uint16_t column_ix, row_handle &a, row_handle &b)
auto &ra = *a.m_row;
auto &rb = *b.m_row;
std::swap(ra.at(column_ix), rb.at(column_ix));
std::swap(ra.at(item_ix), rb.at(item_ix));
}
void category::sort(std::function<int(row_handle,row_handle)> f)
void category::sort(std::function<int(row_handle, row_handle)> f)
{
if (m_head == nullptr)
return;
......@@ -1710,7 +1778,7 @@ void category::sort(std::function<int(row_handle,row_handle)> f)
r->m_next = nullptr;
assert(r == m_tail);
assert(size() == rows.size());
assert(size() == rows.size());
}
void category::reorder_by_index()
......@@ -1723,7 +1791,7 @@ namespace detail
{
size_t write_value(std::ostream &os, std::string_view value, size_t offset, size_t width, bool right_aligned)
{
if (value.find('\n') != std::string::npos or width == 0 or value.length() > 132) // write as text field
if (value.find('\n') != std::string::npos or width == 0 or value.length() > 132) // write as text item
{
if (offset > 0)
os << '\n';
......@@ -1818,36 +1886,36 @@ namespace detail
} // namespace detail
std::vector<std::string> category::get_tag_order() const
std::vector<std::string> category::get_item_order() const
{
std::vector<std::string> result;
for (auto &c : m_columns)
for (auto &c : m_items)
result.push_back("_" + m_name + "." + c.m_name);
return result;
}
void category::write(std::ostream &os) const
{
std::vector<uint16_t> order(m_columns.size());
std::vector<uint16_t> order(m_items.size());
iota(order.begin(), order.end(), static_cast<uint16_t>(0));
write(os, order, false);
}
void category::write(std::ostream &os, const std::vector<std::string> &columns, bool addMissingColumns)
void category::write(std::ostream &os, const std::vector<std::string> &items, bool addMissingItems)
{
// make sure all columns are present
for (auto &c : columns)
add_column(c);
// make sure all items are present
for (auto &c : items)
add_item(c);
std::vector<uint16_t> order;
order.reserve(m_columns.size());
order.reserve(m_items.size());
for (auto &c : columns)
order.push_back(get_column_ix(c));
for (auto &c : items)
order.push_back(get_item_ix(c));
if (addMissingColumns)
if (addMissingItems)
{
for (uint16_t i = 0; i < m_columns.size(); ++i)
for (uint16_t i = 0; i < m_items.size(); ++i)
{
if (std::find(order.begin(), order.end(), i) == order.end())
order.push_back(i);
......@@ -1857,7 +1925,7 @@ void category::write(std::ostream &os, const std::vector<std::string> &columns,
write(os, order, true);
}
void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyColumns) const
void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyItems) const
{
if (empty())
return;
......@@ -1865,16 +1933,16 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
// If the first Row has a next, we need a loop_
bool needLoop = (m_head->m_next != nullptr);
std::vector<bool> right_aligned(m_columns.size(), false);
std::vector<bool> right_aligned(m_items.size(), false);
if (m_cat_validator != nullptr)
{
for (auto cix : order)
{
auto &col = m_columns[cix];
auto &col = m_items[cix];
right_aligned[cix] = col.m_validator != nullptr and
col.m_validator->m_type != nullptr and
col.m_validator->m_type->m_primitive_type == cif::DDL_PrimitiveType::Numb;
col.m_validator->m_type != nullptr and
col.m_validator->m_type->m_primitive_type == cif::DDL_PrimitiveType::Numb;
}
}
......@@ -1882,16 +1950,16 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
{
os << "loop_\n";
std::vector<size_t> columnWidths(m_columns.size());
std::vector<size_t> itemWidths(m_items.size());
for (auto cix : order)
{
auto &col = m_columns[cix];
auto &col = m_items[cix];
os << '_';
if (not m_name.empty())
os << m_name << '.';
os << col.m_name << ' ' << '\n';
columnWidths[cix] = 2;
itemWidths[cix] = 2;
}
for (auto r = m_head; r != nullptr; r = r->m_next)
......@@ -1912,8 +1980,8 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
if (l > 132)
continue;
if (columnWidths[ix] < l + 1)
columnWidths[ix] = l + 1;
if (itemWidths[ix] < l + 1)
itemWidths[ix] = l + 1;
}
}
}
......@@ -1924,7 +1992,7 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
for (uint16_t cix : order)
{
size_t w = columnWidths[cix];
size_t w = itemWidths[cix];
std::string_view s;
auto iv = r->get(cix);
......@@ -1964,12 +2032,12 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
// first find the indent level
size_t l = 0;
for (auto &col : m_columns)
for (auto &col : m_items)
{
std::string tag = '_' + m_name + '.' + col.m_name;
std::string item_name = '_' + m_name + '.' + col.m_name;
if (l < tag.length())
l = tag.length();
if (l < item_name.length())
l = item_name.length();
}
l += 3;
......@@ -2000,7 +2068,7 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
for (uint16_t cix : order)
{
auto &col = m_columns[cix];
auto &col = m_items[cix];
os << '_';
if (not m_name.empty())
......@@ -2032,76 +2100,84 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
bool category::operator==(const category &rhs) const
{
// shortcut
if (this == &rhs)
return true;
auto &a = *this;
auto &b = rhs;
using namespace std::placeholders;
// set<std::string> tagsA(a.fields()), tagsB(b.fields());
//
// if (tagsA != tagsB)
// std::cout << "Unequal number of fields\n";
using namespace std::placeholders;
// set<std::string> item_namesA(a.items()), item_namesB(b.items());
//
// if (item_namesA != item_namesB)
// std::cout << "Unequal number of items\n";
const category_validator *catValidator = nullptr;
auto validator = a.get_validator();
if (validator != nullptr)
catValidator = validator->get_validator_for_category(a.name());
typedef std::function<int(std::string_view,std::string_view)> compType;
std::vector<std::tuple<std::string,compType>> tags;
typedef std::function<int(std::string_view, std::string_view)> compType;
std::vector<std::tuple<std::string, compType>> item_names;
std::vector<std::string> keys;
std::vector<size_t> keyIx;
if (catValidator == nullptr)
{
for (auto& tag: a.get_columns())
for (auto &item_name : a.get_items())
{
tags.push_back(std::make_tuple(tag, [](std::string_view va, std::string_view vb) { return va.compare(vb); }));
item_names.push_back(std::make_tuple(item_name, [](std::string_view va, std::string_view vb)
{ return va.compare(vb); }));
keyIx.push_back(keys.size());
keys.push_back(tag);
keys.push_back(item_name);
}
}
else
{
keys = catValidator->m_keys;
for (auto& tag: a.key_fields())
for (auto &item_name : a.key_items())
{
auto iv = catValidator->get_validator_for_item(tag);
auto iv = catValidator->get_validator_for_item(item_name);
if (iv == nullptr)
throw std::runtime_error("missing item validator");
auto tv = iv->m_type;
if (tv == nullptr)
throw std::runtime_error("missing type validator");
tags.push_back(std::make_tuple(tag, std::bind(&cif::type_validator::compare, tv, std::placeholders::_1, std::placeholders::_2)));
auto pred = [tag](const std::string& s) -> bool { return cif::iequals(tag, s) == 0; };
item_names.push_back(std::make_tuple(item_name, std::bind(&cif::type_validator::compare, tv, std::placeholders::_1, std::placeholders::_2)));
auto pred = [item_name](const std::string &s) -> bool
{
return cif::iequals(item_name, s) == 0;
};
if (find_if(keys.begin(), keys.end(), pred) == keys.end())
keyIx.push_back(tags.size() - 1);
keyIx.push_back(item_names.size() - 1);
}
}
// a.reorderByIndex();
// b.reorderByIndex();
auto rowEqual = [&](const row_handle& a, const row_handle& b)
auto rowEqual = [&](const row_handle &a, const row_handle &b)
{
int d = 0;
for (auto kix: keyIx)
for (auto kix : keyIx)
{
std::string tag;
std::string item_name;
compType compare;
std::tie(tag, compare) = tags[kix];
d = compare(a[tag].text(), b[tag].text());
std::tie(item_name, compare) = item_names[kix];
d = compare(a[item_name].text(), b[item_name].text());
if (d != 0)
break;
}
return d == 0;
};
......@@ -2110,30 +2186,34 @@ bool category::operator==(const category &rhs) const
{
if (ai == a.end() or bi == b.end())
return false;
auto ra = *ai, rb = *bi;
if (not rowEqual(ra, rb))
return false;
std::vector<std::string> missingA, missingB, different;
for (auto& tt: tags)
for (auto &tt : item_names)
{
std::string tag;
std::string item_name;
compType compare;
std::tie(tag, compare) = tt;
std::tie(item_name, compare) = tt;
// make it an option to compare unapplicable to empty or something
auto ta = ra[tag].text(); if (ta == "." or ta == "?") ta = "";
auto tb = rb[tag].text(); if (tb == "." or tb == "?") tb = "";
auto ta = ra[item_name].text();
if (ta == "." or ta == "?")
ta = "";
auto tb = rb[item_name].text();
if (tb == "." or tb == "?")
tb = "";
if (compare(ta, tb) != 0)
return false;
}
++ai;
++bi;
}
......
......@@ -311,6 +311,18 @@ float compound::bond_length(const std::string &atomId_1, const std::string &atom
}
// --------------------------------------------------------------------
bool compound::is_peptide() const
{
return iequals(m_type, "l-peptide linking") or iequals(m_type, "peptide linking");
}
bool compound::is_base() const
{
return iequals(m_type, "dna linking") or iequals(m_type, "rna linking");
}
// --------------------------------------------------------------------
// known amino acids and bases
const std::map<std::string, char> compound_factory::kAAMap{
......@@ -660,25 +672,67 @@ void compound_factory::pop_dictionary()
m_impl = m_impl->next();
}
const compound *compound_factory::create(std::string id)
const compound *compound_factory::create(std::string_view id)
{
auto result = m_impl ? m_impl->get(id) : nullptr;
auto result = m_impl ? m_impl->get(std::string{ id }) : nullptr;
if (not result)
report_missing_compound(id);
return result;
}
bool compound_factory::is_known_peptide(const std::string &resName) const
bool compound_factory::is_known_peptide(const std::string &res_name) const
{
return kAAMap.count(res_name) > 0;
}
bool compound_factory::is_known_base(const std::string &res_name) const
{
return kBaseMap.count(res_name) > 0;
}
/// Return whether @a res_name is a peptide
bool compound_factory::is_peptide(std::string_view res_name) const
{
bool result = is_std_peptide(res_name);
if (not result and m_impl)
{
auto compound = const_cast<compound_factory&>(*this).create(res_name);
result = compound != nullptr and compound->is_peptide();
}
return result;
}
/// Return whether @a res_name is a base
bool compound_factory::is_base(std::string_view res_name) const
{
bool result = is_std_base(res_name);
if (not result and m_impl)
{
auto compound = const_cast<compound_factory&>(*this).create(res_name);
result = compound != nullptr and compound->is_base();
}
return result;
}
/// Return whether @a res_name is one of the standard peptides
bool compound_factory::is_std_peptide(std::string_view res_name) const
{
return kAAMap.count(std::string{ res_name }) > 0;
}
/// Return whether @a res_name is one of the standard bases
bool compound_factory::is_std_base(std::string_view res_name) const
{
return kAAMap.count(resName) > 0;
return kBaseMap.count(std::string{ res_name }) > 0;
}
bool compound_factory::is_known_base(const std::string &resName) const
/// Return whether @a res_name is a monomer (either base or peptide)
bool compound_factory::is_monomer(std::string_view res_name) const
{
return kBaseMap.count(resName) > 0;
return is_peptide(res_name) or is_base(res_name);
}
void compound_factory::report_missing_compound(const std::string &compound_id)
void compound_factory::report_missing_compound(std::string_view compound_id)
{
static bool s_reported = false;
if (std::exchange(s_reported, true) == false)
......@@ -703,8 +757,8 @@ void compound_factory::report_missing_compound(const std::string &compound_id)
<< "update=true\n\n"
<< "If you do not have a working cron script, you can manually update the files\n"
<< "in /var/cache/libcifpp using the following commands:\n\n"
<< "curl -o " << CACHE_DIR << "/components.cif https://files.wwpdb.org/pub/pdb/data/monomers/components.cif.gz\n"
<< "curl -o " << CACHE_DIR << "/mmcif_pdbx.dic https://mmcif.wwpdb.org/dictionaries/ascii/mmcif_pdbx_v50.dic.gz\n"
<< "curl -o " << CACHE_DIR << "/components.cif https://files.wwpdb.org/pub/pdb/data/monomers/components.cif\n"
<< "curl -o " << CACHE_DIR << "/mmcif_pdbx.dic https://mmcif.wwpdb.org/dictionaries/ascii/mmcif_pdbx_v50.dic\n"
<< "curl -o " << CACHE_DIR << "/mmcif_ma.dic https://github.com/ihmwg/ModelCIF/raw/master/dist/mmcif_ma.dic\n\n";
#endif
......
......@@ -30,17 +30,17 @@
namespace cif
{
iset get_category_fields(const category &cat)
iset get_category_items(const category &cat)
{
return cat.key_fields();
return cat.key_items();
}
uint16_t get_column_ix(const category &cat, std::string_view col)
uint16_t get_item_ix(const category &cat, std::string_view col)
{
return cat.get_column_ix(col);
return cat.get_item_ix(col);
}
bool is_column_type_uchar(const category &cat, std::string_view col)
bool is_item_type_uchar(const category &cat, std::string_view col)
{
bool result = false;
......@@ -63,14 +63,14 @@ namespace detail
condition_impl *key_equals_condition_impl::prepare(const category &c)
{
m_item_ix = c.get_column_ix(m_item_tag);
m_icase = is_column_type_uchar(c, m_item_tag);
m_item_ix = c.get_item_ix(m_item_name);
m_icase = is_item_type_uchar(c, m_item_name);
if (c.get_cat_validator() != nullptr and
c.key_field_indices().contains(m_item_ix) and
c.key_field_indices().size() == 1)
c.key_item_indices().contains(m_item_ix) and
c.key_item_indices().size() == 1)
{
m_single_hit = c[{ { m_item_tag, m_value } }];
m_single_hit = c[{ { m_item_name, m_value } }];
}
return this;
......
......@@ -85,6 +85,40 @@ bool datablock::is_valid() const
return result;
}
bool datablock::is_valid()
{
if (m_validator == nullptr)
throw std::runtime_error("Validator not specified");
bool result = true;
for (auto &cat : *this)
result = cat.is_valid() and result;
// Add or remove the audit_conform block here.
if (result)
{
// If the dictionary declares an audit_conform category, put it in,
// but only if it does not exist already!
if (m_validator->get_validator_for_category("audit_conform") != nullptr)
{
auto &audit_conform = operator[]("audit_conform");
audit_conform.clear();
audit_conform.emplace({
// clang-format off
{ "dict_name", m_validator->name() },
{ "dict_version", m_validator->version() }
// clang-format on
});
}
}
else
erase(std::find_if(begin(), end(), [](category &cat) { return cat.name() == "audit_conform"; }), end());
return result;
}
bool datablock::validate_links() const
{
bool result = true;
......@@ -143,13 +177,6 @@ std::tuple<datablock::iterator, bool> datablock::emplace(std::string_view name)
if (iequals(name, i->name()))
{
is_new = false;
if (i != begin())
{
auto n = std::next(i);
splice(begin(), *this, i, n);
}
break;
}
......@@ -158,25 +185,24 @@ std::tuple<datablock::iterator, bool> datablock::emplace(std::string_view name)
if (is_new)
{
auto &c = emplace_back(name);
c.set_validator(m_validator, *this);
i = insert(end(), {name});
i->set_validator(m_validator, *this);
}
assert(end() != begin());
return std::make_tuple(std::prev(end()), is_new);
assert(i != end());
return std::make_tuple(i, is_new);
}
std::vector<std::string> datablock::get_tag_order() const
std::vector<std::string> datablock::get_item_order() const
{
std::vector<std::string> result;
// for entry and audit_conform on top
auto ci = find_if(begin(), end(), [](const category &cat)
{ return cat.name() == "entry"; });
if (ci != end())
{
auto cto = ci->get_tag_order();
auto cto = ci->get_item_order();
result.insert(result.end(), cto.begin(), cto.end());
}
......@@ -184,7 +210,7 @@ std::vector<std::string> datablock::get_tag_order() const
{ return cat.name() == "audit_conform"; });
if (ci != end())
{
auto cto = ci->get_tag_order();
auto cto = ci->get_item_order();
result.insert(result.end(), cto.begin(), cto.end());
}
......@@ -192,7 +218,7 @@ std::vector<std::string> datablock::get_tag_order() const
{
if (cat.name() == "entry" or cat.name() == "audit_conform")
continue;
auto cto = cat.get_tag_order();
auto cto = cat.get_item_order();
result.insert(result.end(), cto.begin(), cto.end());
}
......@@ -251,16 +277,6 @@ void datablock::write(std::ostream &os) const
if (m_validator and size() > 0)
{
// If the dictionary declares an audit_conform category, put it in,
// but only if it does not exist already!
if (get("audit_conform") == nullptr and m_validator->get_validator_for_category("audit_conform") != nullptr)
{
category auditConform("audit_conform");
auditConform.emplace({ { "dict_name", m_validator->name() },
{ "dict_version", m_validator->version() } });
auditConform.write(os);
}
// base order on parent child relationships, parents first
cat_order_t cat_order;
......@@ -327,16 +343,16 @@ void datablock::write(std::ostream &os) const
}
}
void datablock::write(std::ostream &os, const std::vector<std::string> &tag_order)
void datablock::write(std::ostream &os, const std::vector<std::string> &item_name_order)
{
os << "data_" << m_name << '\n'
<< "# \n";
std::vector<std::string> cat_order;
for (auto &o : tag_order)
for (auto &o : item_name_order)
{
std::string cat_name, item_name;
std::tie(cat_name, item_name) = split_tag_name(o);
std::tie(cat_name, item_name) = split_item_name(o);
if (find_if(cat_order.rbegin(), cat_order.rend(), [cat_name](const std::string &s) -> bool
{ return iequals(cat_name, s); }) == cat_order.rend())
cat_order.push_back(cat_name);
......@@ -349,10 +365,10 @@ void datablock::write(std::ostream &os, const std::vector<std::string> &tag_orde
continue;
std::vector<std::string> items;
for (auto &o : tag_order)
for (auto &o : item_name_order)
{
std::string cat_name, item_name;
std::tie(cat_name, item_name) = split_tag_name(o);
std::tie(cat_name, item_name) = split_item_name(o);
if (cat_name == c)
items.push_back(item_name);
......@@ -374,6 +390,10 @@ void datablock::write(std::ostream &os, const std::vector<std::string> &tag_orde
bool datablock::operator==(const datablock &rhs) const
{
// shortcut
if (this == &rhs)
return true;
auto &dbA = *this;
auto &dbB = rhs;
......
......@@ -50,7 +50,7 @@ class dictionary_parser : public parser
try
{
while (m_lookahead != CIFToken::Eof)
while (m_lookahead != CIFToken::END_OF_FILE)
{
switch (m_lookahead)
{
......@@ -87,7 +87,7 @@ class dictionary_parser : public parser
error("Undefined category '" + iv.first);
for (auto &v : iv.second)
const_cast<category_validator *>(cv)->addItemValidator(std::move(v));
const_cast<category_validator *>(cv)->add_item_validator(std::move(v));
}
// check all item validators for having a typeValidator
......@@ -128,7 +128,7 @@ class dictionary_parser : public parser
datablock::iterator cat = dict.end();
match(CIFToken::SAVE_NAME);
while (m_lookahead == CIFToken::LOOP or m_lookahead == CIFToken::Tag)
while (m_lookahead == CIFToken::LOOP or m_lookahead == CIFToken::ITEM_NAME)
{
if (m_lookahead == CIFToken::LOOP)
{
......@@ -136,30 +136,30 @@ class dictionary_parser : public parser
match(CIFToken::LOOP);
std::vector<std::string> tags;
while (m_lookahead == CIFToken::Tag)
std::vector<std::string> item_names;
while (m_lookahead == CIFToken::ITEM_NAME)
{
std::string catName, item_name;
std::tie(catName, item_name) = split_tag_name(m_token_value);
std::tie(catName, item_name) = split_item_name(m_token_value);
if (cat == dict.end())
std::tie(cat, std::ignore) = dict.emplace(catName);
else if (not iequals(cat->name(), catName))
error("inconsistent categories in loop_");
tags.push_back(item_name);
match(CIFToken::Tag);
item_names.push_back(item_name);
match(CIFToken::ITEM_NAME);
}
while (m_lookahead == CIFToken::Value)
while (m_lookahead == CIFToken::VALUE)
{
cat->emplace({});
auto row = cat->back();
for (auto tag : tags)
for (auto item_name : item_names)
{
row[tag] = m_token_value;
match(CIFToken::Value);
row[item_name] = m_token_value;
match(CIFToken::VALUE);
}
}
......@@ -168,18 +168,18 @@ class dictionary_parser : public parser
else
{
std::string catName, item_name;
std::tie(catName, item_name) = split_tag_name(m_token_value);
std::tie(catName, item_name) = split_item_name(m_token_value);
if (cat == dict.end() or not iequals(cat->name(), catName))
std::tie(cat, std::ignore) = dict.emplace(catName);
match(CIFToken::Tag);
match(CIFToken::ITEM_NAME);
if (cat->empty())
cat->emplace({});
cat->back()[item_name] = m_token_value;
match(CIFToken::Value);
match(CIFToken::VALUE);
}
}
......@@ -191,7 +191,7 @@ class dictionary_parser : public parser
std::vector<std::string> keys;
for (auto k : dict["category_key"])
keys.push_back(std::get<1>(split_tag_name(k["name"].as<std::string>())));
keys.push_back(std::get<1>(split_item_name(k["name"].as<std::string>())));
iset groups;
for (auto g : dict["category_group"])
......@@ -224,20 +224,27 @@ class dictionary_parser : public parser
// }
// }
std::vector<item_alias> aliases;
for (const auto &[alias_name, dictionary, version] :
dict["item_aliases"].rows<std::string,std::string,std::string>("alias_name", "dictionary", "version"))
{
aliases.emplace_back(alias_name, dictionary, version);
}
// collect the dict from our dataBlock and construct validators
for (auto i : dict["item"])
{
std::string tagName, category, mandatory;
cif::tie(tagName, category, mandatory) = i.get("name", "category_id", "mandatory_code");
std::string item, category, mandatory;
cif::tie(item, category, mandatory) = i.get("name", "category_id", "mandatory_code");
std::string cat_name, item_name;
std::tie(cat_name, item_name) = split_tag_name(tagName);
std::tie(cat_name, item_name) = split_item_name(item);
if (cat_name.empty() or item_name.empty())
error("Invalid tag name in _item.name " + tagName);
error("Invalid item name in _item.name " + item);
if (not iequals(category, cat_name) and not(category.empty() or category == "?"))
error("specified category id does match the implicit category name for tag '" + tagName + '\'');
error("specified category id does match the implicit category name for item '" + item + '\'');
else
category = cat_name;
......@@ -245,7 +252,7 @@ class dictionary_parser : public parser
auto vi = find(ivs.begin(), ivs.end(), item_validator{ item_name });
if (vi == ivs.end())
ivs.push_back(item_validator{ item_name, iequals(mandatory, "yes"), tv, ess, defaultValue /*, defaultIsNull*/ });
ivs.push_back(item_validator{ item_name, iequals(mandatory, "yes"), tv, ess, defaultValue, nullptr, std::move(aliases) });
else
{
// need to update the itemValidator?
......@@ -253,22 +260,22 @@ class dictionary_parser : public parser
{
if (VERBOSE > 2)
{
std::cerr << "inconsistent mandatory value for " << tagName << " in dictionary\n";
std::cerr << "inconsistent mandatory value for " << item << " in dictionary\n";
if (iequals(tagName, saveFrameName))
if (iequals(item, saveFrameName))
std::cerr << "choosing " << mandatory << '\n';
else
std::cerr << "choosing " << (vi->m_mandatory ? "Y" : "N") << '\n';
}
if (iequals(tagName, saveFrameName))
if (iequals(item, saveFrameName))
vi->m_mandatory = (iequals(mandatory, "yes"));
}
if (vi->m_type != nullptr and tv != nullptr and vi->m_type != tv)
{
if (VERBOSE > 1)
std::cerr << "inconsistent type for " << tagName << " in dictionary\n";
std::cerr << "inconsistent type for " << item << " in dictionary\n";
}
// vi->mMandatory = (iequals(mandatory, "yes"));
......@@ -351,7 +358,7 @@ class dictionary_parser : public parser
}
size_t ix = linkIndex.at(key);
addLink(ix, piv->m_tag, civ->m_tag);
addLink(ix, piv->m_item_name, civ->m_item_name);
}
// Only process inline linked items if the linked group list is absent
......@@ -379,7 +386,7 @@ class dictionary_parser : public parser
}
size_t ix = linkIndex.at(key);
addLink(ix, piv->m_tag, civ->m_tag);
addLink(ix, piv->m_item_name, civ->m_item_name);
}
}
......@@ -410,7 +417,7 @@ class dictionary_parser : public parser
for (auto &iv : cv.m_item_validators)
{
if (iv.m_type == nullptr and cif::VERBOSE >= 0)
std::cerr << "Missing item_type for " << iv.m_tag << '\n';
std::cerr << "Missing item_type for " << iv.m_item_name << '\n';
}
}
}
......
......@@ -158,13 +158,6 @@ std::tuple<file::iterator, bool> file::emplace(std::string_view name)
if (iequals(name, i->name()))
{
is_new = false;
if (i != begin())
{
auto n = std::next(i);
splice(begin(), *this, i, n);
}
break;
}
......@@ -173,12 +166,12 @@ std::tuple<file::iterator, bool> file::emplace(std::string_view name)
if (is_new)
{
auto &db = emplace_back(name);
db.set_validator(m_validator);
i = insert(end(), { name });
i->set_validator(m_validator);
}
assert(begin() != end());
return std::make_tuple(std::prev(end()), is_new);
assert(i != end());
return std::make_tuple(i, is_new);
}
void file::load(const std::filesystem::path &p)
......
......@@ -35,7 +35,7 @@ const item_handle item_handle::s_null_item;
row_handle s_null_row_handle;
item_handle::item_handle()
: m_column(std::numeric_limits<uint16_t>::max())
: m_item_ix(std::numeric_limits<uint16_t>::max())
, m_row_handle(s_null_row_handle)
{
}
......@@ -44,7 +44,7 @@ std::string_view item_handle::text() const
{
if (not m_row_handle.empty())
{
auto iv = m_row_handle.m_row->get(m_column);
auto iv = m_row_handle.m_row->get(m_item_ix);
if (iv != nullptr)
return iv->text();
}
......@@ -52,17 +52,17 @@ std::string_view item_handle::text() const
return {};
}
void item_handle::assign_value(const item &v)
void item_handle::assign_value(std::string_view value)
{
assert(not m_row_handle.empty());
m_row_handle.assign(m_column, v.value(), true);
m_row_handle.assign(m_item_ix, value, true);
}
void item_handle::swap(item_handle &b)
{
assert(m_column == b.m_column);
assert(m_item_ix == b.m_item_ix);
// assert(&m_row_handle.m_category == &b.m_row_handle.m_category);
m_row_handle.swap(m_column, b.m_row_handle);
m_row_handle.swap(m_item_ix, b.m_row_handle);
}
}
......@@ -163,9 +163,9 @@ int atom::atom_impl::get_charge() const
// const std::string atom::atom_impl::get_property(const std::string_view name) const
// {
// for (auto &&[tag, ref] : mCachedRefs)
// for (auto &&[item_name, ref] : mCachedRefs)
// {
// if (tag == name)
// if (item_name == name)
// return ref.as<std::string>();
// }
......@@ -175,9 +175,9 @@ int atom::atom_impl::get_charge() const
// void atom::atom_impl::set_property(const std::string_view name, const std::string &value)
// {
// for (auto &&[tag, ref] : mCachedRefs)
// for (auto &&[item_name, ref] : mCachedRefs)
// {
// if (tag != name)
// if (item_name != name)
// continue;
// ref = value;
......@@ -1783,7 +1783,7 @@ atom &structure::emplace_atom(atom &&atom)
std::string symbol = atom.get_property("type_symbol");
using namespace cif::literals;
if (not atom_type.exists("symbol"_key == symbol))
if (not atom_type.contains("symbol"_key == symbol))
atom_type.emplace({ { "symbol", symbol } });
return m_atoms.emplace_back(std::move(atom));
......@@ -1969,7 +1969,7 @@ void structure::change_residue(residue &res, const std::string &newCompound,
// create rest
auto &chemComp = m_db["chem_comp"];
if (not chemComp.exists(key("id") == newCompound))
if (not chemComp.contains(key("id") == newCompound))
{
chemComp.emplace({{"id", newCompound},
{"name", compound->name()},
......@@ -2702,7 +2702,7 @@ void structure::cleanup_empty_categories()
for (auto chemComp : chem_comp)
{
std::string compID = chemComp["id"].as<std::string>();
if (atomSite.exists("label_comp_id"_key == compID or "auth_comp_id"_key == compID))
if (atomSite.contains("label_comp_id"_key == compID or "auth_comp_id"_key == compID))
continue;
obsoleteChemComps.push_back(chemComp);
......@@ -2719,7 +2719,7 @@ void structure::cleanup_empty_categories()
for (auto entity : entities)
{
std::string entityID = entity["id"].as<std::string>();
if (atomSite.exists("label_entity_id"_key == entityID))
if (atomSite.contains("label_entity_id"_key == entityID))
continue;
obsoleteEntities.push_back(entity);
......
......@@ -269,7 +269,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
{
const auto kEOF = std::char_traits<char>::eof();
CIFToken result = CIFToken::Unknown;
CIFToken result = CIFToken::UNKNOWN;
int quoteChar = 0;
State state = State::Start;
m_bol = false;
......@@ -279,7 +279,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
reserved_words_automaton dag;
while (result == CIFToken::Unknown)
while (result == CIFToken::UNKNOWN)
{
auto ch = get_next_char();
......@@ -287,7 +287,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
{
case State::Start:
if (ch == kEOF)
result = CIFToken::Eof;
result = CIFToken::END_OF_FILE;
else if (ch == '\n')
{
m_bol = true;
......@@ -298,9 +298,9 @@ sac_parser::CIFToken sac_parser::get_next_token()
else if (ch == '#')
state = State::Comment;
else if (ch == '_')
state = State::Tag;
state = State::ItemName;
else if (ch == ';' and m_bol)
state = State::TextField;
state = State::TextItem;
else if (ch == '?')
state = State::QuestionMark;
else if (ch == '\'' or ch == '"')
......@@ -316,7 +316,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
case State::White:
if (ch == kEOF)
result = CIFToken::Eof;
result = CIFToken::END_OF_FILE;
else if (not is_space(ch))
{
state = State::Start;
......@@ -335,7 +335,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
m_token_buffer.clear();
}
else if (ch == kEOF)
result = CIFToken::Eof;
result = CIFToken::END_OF_FILE;
else if (not is_any_print(ch))
error("invalid character in comment");
break;
......@@ -344,29 +344,29 @@ sac_parser::CIFToken sac_parser::get_next_token()
if (not is_non_blank(ch))
{
retract();
result = CIFToken::Value;
result = CIFToken::VALUE;
}
else
state = State::Value;
break;
case State::TextField:
case State::TextItem:
if (ch == '\n')
state = State::TextFieldNL;
state = State::TextItemNL;
else if (ch == kEOF)
error("unterminated textfield");
else if (not is_any_print(ch) and cif::VERBOSE > 2)
warning("invalid character in text field '" + std::string({static_cast<char>(ch)}) + "' (" + std::to_string((int)ch) + ")");
break;
case State::TextFieldNL:
case State::TextItemNL:
if (is_text_lead(ch) or ch == ' ' or ch == '\t')
state = State::TextField;
state = State::TextItem;
else if (ch == ';')
{
assert(m_token_buffer.size() >= 2);
m_token_value = std::string_view(m_token_buffer.data() + 1, m_token_buffer.size() - 3);
result = CIFToken::Value;
result = CIFToken::VALUE;
}
else if (ch == kEOF)
error("unterminated textfield");
......@@ -387,7 +387,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
if (is_white(ch))
{
retract();
result = CIFToken::Value;
result = CIFToken::VALUE;
if (m_token_buffer.size() < 2)
error("Invalid quoted string token");
......@@ -403,11 +403,11 @@ sac_parser::CIFToken sac_parser::get_next_token()
error("invalid character in quoted string");
break;
case State::Tag:
case State::ItemName:
if (not is_non_blank(ch))
{
retract();
result = CIFToken::Tag;
result = CIFToken::ITEM_NAME;
m_token_value = std::string_view(m_token_buffer.data(), m_token_buffer.size());
}
break;
......@@ -422,7 +422,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
if (not is_non_blank(ch))
{
retract();
result = CIFToken::Value;
result = CIFToken::VALUE;
m_token_value = std::string_view(m_token_buffer.data(), m_token_buffer.size());
}
else
......@@ -467,7 +467,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
if (not is_non_blank(ch))
{
retract();
result = CIFToken::Value;
result = CIFToken::VALUE;
m_token_value = std::string_view(m_token_buffer.data(), m_token_buffer.size());
break;
}
......@@ -483,7 +483,7 @@ sac_parser::CIFToken sac_parser::get_next_token()
if (VERBOSE >= 5)
{
std::cerr << get_token_name(result);
if (result != CIFToken::Eof)
if (result != CIFToken::END_OF_FILE)
std::cerr << " " << std::quoted(m_token_value);
std::cerr << '\n';
}
......@@ -710,7 +710,7 @@ bool sac_parser::parse_single_datablock(const std::string &datablock, const data
void sac_parser::parse_file()
{
while (m_lookahead != CIFToken::Eof)
while (m_lookahead != CIFToken::END_OF_FILE)
{
switch (m_lookahead)
{
......@@ -735,10 +735,10 @@ void sac_parser::parse_file()
void sac_parser::parse_global()
{
match(CIFToken::GLOBAL);
while (m_lookahead == CIFToken::Tag)
while (m_lookahead == CIFToken::ITEM_NAME)
{
match(CIFToken::Tag);
match(CIFToken::Value);
match(CIFToken::ITEM_NAME);
match(CIFToken::VALUE);
}
}
......@@ -747,7 +747,7 @@ void sac_parser::parse_datablock()
static const std::string kUnitializedCategory("<invalid>");
std::string cat = kUnitializedCategory; // intial value acts as a guard for empty category names
while (m_lookahead == CIFToken::LOOP or m_lookahead == CIFToken::Tag or m_lookahead == CIFToken::SAVE_NAME)
while (m_lookahead == CIFToken::LOOP or m_lookahead == CIFToken::ITEM_NAME or m_lookahead == CIFToken::SAVE_NAME)
{
switch (m_lookahead)
{
......@@ -757,12 +757,12 @@ void sac_parser::parse_datablock()
match(CIFToken::LOOP);
std::vector<std::string> tags;
std::vector<std::string> item_names;
while (m_lookahead == CIFToken::Tag)
while (m_lookahead == CIFToken::ITEM_NAME)
{
std::string catName, itemName;
std::tie(catName, itemName) = split_tag_name(m_token_value);
std::tie(catName, itemName) = split_item_name(m_token_value);
if (cat == kUnitializedCategory)
{
......@@ -772,19 +772,19 @@ void sac_parser::parse_datablock()
else if (not iequals(cat, catName))
error("inconsistent categories in loop_");
tags.push_back(itemName);
item_names.push_back(itemName);
match(CIFToken::Tag);
match(CIFToken::ITEM_NAME);
}
while (m_lookahead == CIFToken::Value)
while (m_lookahead == CIFToken::VALUE)
{
produce_row();
for (auto tag : tags)
for (auto item_name : item_names)
{
produce_item(cat, tag, m_token_value);
match(CIFToken::Value);
produce_item(cat, item_name, m_token_value);
match(CIFToken::VALUE);
}
}
......@@ -792,10 +792,10 @@ void sac_parser::parse_datablock()
break;
}
case CIFToken::Tag:
case CIFToken::ITEM_NAME:
{
std::string catName, itemName;
std::tie(catName, itemName) = split_tag_name(m_token_value);
std::tie(catName, itemName) = split_item_name(m_token_value);
if (not iequals(cat, catName))
{
......@@ -804,11 +804,11 @@ void sac_parser::parse_datablock()
produce_row();
}
match(CIFToken::Tag);
match(CIFToken::ITEM_NAME);
produce_item(cat, itemName, m_token_value);
match(CIFToken::Value);
match(CIFToken::VALUE);
break;
}
......
......@@ -1123,9 +1123,6 @@ void PDBFileParser::PreParseInput(std::istream &is)
if (lookahead.back() == '\r')
lookahead.pop_back();
// if (cif::starts_with(lookahead, "HEADER") == false)
// throw std::runtime_error("This does not look like a PDB file, should start with a HEADER line");
auto contNr = [&lookahead](int offset, int len) -> int
{
std::string cs = lookahead.substr(offset, len);
......@@ -1558,52 +1555,54 @@ void PDBFileParser::ParseTitle()
// 11 - 80 Specification compound Description of the molecular components.
// list
std::string value{ mRec->vS(11) };
if (value.find(':') == std::string::npos)
{
// special case for dumb, stripped files
auto &comp = GetOrCreateCompound(1);
comp.mInfo["MOLECULE"] = value;
}
else
if (mRec->is("COMPND"))
{
SpecificationListParser p(value);
for (;;)
std::string value{ mRec->vS(11) };
if (value.find(':') == std::string::npos)
{
std::string key, val;
std::tie(key, val) = p.GetNextSpecification();
if (key.empty())
break;
// special case for dumb, stripped files
auto &comp = GetOrCreateCompound(1);
comp.mInfo["MOLECULE"] = value;
}
else
{
SpecificationListParser p(value);
if (not iequals(key, "MOL_ID") and mCompounds.empty())
for (;;)
{
if (cif::VERBOSE > 0)
std::cerr << "Ignoring invalid COMPND record\n";
break;
}
std::string key, val;
std::tie(key, val) = p.GetNextSpecification();
if (key == "MOL_ID")
{
auto &comp = GetOrCreateCompound(stoi(val));
comp.mTitle = title;
}
else if (key == "CHAIN")
{
for (auto c : cif::split<std::string>(val, ","))
if (key.empty())
break;
if (not iequals(key, "MOL_ID") and mCompounds.empty())
{
cif::trim(c);
mCompounds.back().mChains.insert(c[0]);
if (cif::VERBOSE > 0)
std::cerr << "Ignoring invalid COMPND record\n";
break;
}
if (key == "MOL_ID")
{
auto &comp = GetOrCreateCompound(stoi(val));
comp.mTitle = title;
}
else if (key == "CHAIN")
{
for (auto c : cif::split<std::string>(val, ","))
{
cif::trim(c);
mCompounds.back().mChains.insert(c[0]);
}
}
else
mCompounds.back().mInfo[key] = val;
}
else
mCompounds.back().mInfo[key] = val;
}
}
if (mRec->is("COMPND"))
GetNextRecord();
}
// SOURCE
Match("SOURCE", false);
......@@ -1740,7 +1739,7 @@ void PDBFileParser::ParseTitle()
int n = 1;
cat = getCategory("audit_author");
value = { mRec->vS(11) };
std::string value = { mRec->vS(11) };
for (auto author : cif::split<std::string>(value, ",", true))
{
// clang-format off
......@@ -3646,7 +3645,7 @@ void PDBFileParser::ConstructEntities()
PDBChain::AtomRes ar{ resName, resSeq, iCode };
if ((chain.mResiduesSeen.empty() or chain.mResiduesSeen.back() != ar) and
(cif::compound_factory::instance().is_known_peptide(resName) or cif::compound_factory::instance().is_known_base(resName)))
cif::compound_factory::instance().is_monomer(resName))
{
chain.mResiduesSeen.push_back(ar);
}
......@@ -3731,11 +3730,8 @@ void PDBFileParser::ConstructEntities()
{
std::string resName = chain.mResiduesSeen[ix].mMonID;
if (cif::compound_factory::instance().is_known_peptide(resName) or
cif::compound_factory::instance().is_known_base(resName))
{
if (cif::compound_factory::instance().is_monomer(resName))
chain.mTerIndex = ix + 1;
}
InsertChemComp(resName);
}
......@@ -3814,7 +3810,7 @@ void PDBFileParser::ConstructEntities()
int residueCount = (residuePerChainCounter[chainID] += 1);
// There appears to be a program that writes out HETATM records as ATOM records....
if (not(cif::compound_factory::instance().is_known_peptide(resName) or cif::compound_factory::instance().is_known_base(resName)) or
if (not cif::compound_factory::instance().is_monomer(resName) or
terminatedChains.count(chainID) or
(chain.mTerIndex > 0 and residueCount >= chain.mTerIndex))
{
......@@ -4559,7 +4555,7 @@ void PDBFileParser::ConstructEntities()
std::string formula;
std::string type;
std::string nstd = ".";
std::string formulaWeight;
std::optional<float> formulaWeight;
if (compound != nullptr)
{
......@@ -4570,7 +4566,7 @@ void PDBFileParser::ConstructEntities()
nstd = "y";
formula = compound->formula();
formulaWeight = std::to_string(compound->formula_weight());
formulaWeight = compound->formula_weight();
}
if (name.empty())
......@@ -4597,7 +4593,7 @@ void PDBFileParser::ConstructEntities()
{ "id", cc },
{ "name", name },
{ "formula", formula },
{ "formula_weight", formulaWeight },
{ "formula_weight", formulaWeight, 3 },
{ "mon_nstd_flag", nstd },
{ "type", type }
});
......@@ -4712,7 +4708,7 @@ void PDBFileParser::ConstructEntities()
}
if (formula_weight > 0)
entity["formula_weight"] = formula_weight;
entity.assign({ { "formula_weight", formula_weight, 3 } });
}
}
......@@ -5581,31 +5577,6 @@ void PDBFileParser::ParseCrystallographic()
GetNextRecord();
}
else
{
// clang-format off
// no cryst1, make a simple one, like this:
// CRYST1 1.000 1.000 1.000 90.00 90.00 90.00 P 1 1
getCategory("cell")->emplace({
{ "entry_id", mStructureID }, // 1 - 6 Record name "CRYST1"
{ "length_a", 1 }, // 7 - 15 Real(9.3) a a (Angstroms).
{ "length_b", 1 }, // 16 - 24 Real(9.3) b b (Angstroms).
{ "length_c", 1 }, // 25 - 33 Real(9.3) c c (Angstroms).
{ "angle_alpha", 90 }, // 34 - 40 Real(7.2) alpha alpha (degrees).
{ "angle_beta", 90 }, // 41 - 47 Real(7.2) beta beta (degrees).
{ "angle_gamma", 90 }, // 48 - 54 Real(7.2) gamma gamma (degrees).
/* goes into symmetry */ // 56 - 66 LString sGroup Space group.
{ "Z_PDB", 1 } // 67 - 70 Integer z Z value.
});
getCategory("symmetry")->emplace({
{ "entry_id", mStructureID },
{ "space_group_name_H-M", "P 1" },
{ "Int_Tables_number", 1 }
});
// clang-format on
}
}
void PDBFileParser::ParseCoordinateTransformation()
......@@ -6466,7 +6437,12 @@ file read(std::istream &is)
// and so the very first character in a valid PDB file
// is 'H'. It is as simple as that.
if (ch == 'h' or ch == 'H')
// Well, not quite, Unfortunately... People insisted that
// having only ATOM records also makes up a valid PDB file...
// Since mmCIF files cannot validly start with a letter character
// apart from the letter 'd', the test has changed into the following:
if (std::isalpha(ch) and std::toupper(ch) != 'D')
read_pdb_file(is, result);
else
{
......
......@@ -1493,8 +1493,8 @@ bool Remark3Parser::parse(const std::string &expMethod, PDBRecord *r, cif::datab
auto r1 = cat1.front();
auto r2 = cat2.front();
for (auto column : cat1.key_fields())
r2[column] = r1[column].text();
for (auto item : cat1.key_items())
r2[item] = r1[item].text();
}
}
else
......
......@@ -31,6 +31,304 @@
namespace cif::pdb
{
using residue_key_type = std::tuple<
std::optional<std::string>,
std::optional<int>,
std::optional<std::string>,
std::optional<std::string>,
std::optional<int>,
std::optional<std::string>>;
template <typename T>
auto get_either_or(std::optional<T> &a, std::optional<T> &b)
{
if (a.has_value())
return a.value();
else if (b.has_value())
return b.value();
else
return T{};
}
inline std::string get_asym_id(residue_key_type &k)
{
return get_either_or(std::get<0>(k), std::get<3>(k));
}
inline int get_seq_id(residue_key_type &k)
{
return get_either_or(std::get<1>(k), std::get<4>(k));
}
inline std::string get_comp_id(residue_key_type &k)
{
return get_either_or(std::get<2>(k), std::get<5>(k));
}
inline bool has_asym_id(residue_key_type &k)
{
return std::get<0>(k).has_value() or std::get<3>(k).has_value();
}
inline bool has_seq_id(residue_key_type &k)
{
return std::get<1>(k).has_value() or std::get<4>(k).has_value();
}
inline bool has_comp_id(residue_key_type &k)
{
return std::get<2>(k).has_value() or std::get<5>(k).has_value();
}
condition get_condition(residue_key_type &k)
{
return key("auth_asym_id") == std::get<0>(k) and
key("auth_seq_id") == std::get<1>(k) and
key("auth_comp_id") == std::get<2>(k) and
key("label_asym_id") == std::get<3>(k) and
key("label_seq_id") == std::get<4>(k) and
key("label_comp_id") == std::get<5>(k);
}
// --------------------------------------------------------------------
void createEntityIDs(datablock &db)
{
// Suppose the file does not have entity ID's. We have to make up some
// walk the atoms. For each auth_asym_id we have a new struct_asym.
// Within the same auth_asym_id's check for a break between polymer and
// non-polymer atoms. If found, create new entity
// Each residue with separate seq_id in asym with same auth_asym_id and
// of type non-polymer is a separate struct asym
//
// that should cover it
auto &atom_site = db["atom_site"];
auto &cf = compound_factory::instance();
std::vector<std::vector<residue_key_type>> entities;
std::string lastAsymID;
int lastSeqID = -1;
std::vector<residue_key_type> waters;
for (residue_key_type k : atom_site.rows<std::optional<std::string>,
std::optional<int>,
std::optional<std::string>,
std::optional<std::string>,
std::optional<int>,
std::optional<std::string>>(
"auth_asym_id", "auth_seq_id", "auth_comp_id",
"label_asym_id", "label_seq_id", "label_comp_id"))
{
std::string comp_id = get_comp_id(k);
if (cf.is_water(comp_id))
{
waters.emplace_back(k);
continue;
}
std::string asym_id = get_asym_id(k);
int seq_id = get_seq_id(k);
bool is_monomer = cf.is_monomer(comp_id);
if (lastAsymID == asym_id and lastSeqID == seq_id and not is_monomer)
continue;
if (asym_id != lastAsymID or (not is_monomer and lastSeqID != seq_id))
entities.push_back({});
entities.back().emplace_back(k);
lastAsymID = asym_id;
lastSeqID = seq_id;
}
std::map<size_t, std::string> entity_ids;
atom_site.add_item("label_entity_id");
for (size_t i = 0; i < entities.size(); ++i)
{
if (entity_ids.contains(i))
continue;
auto entity_id = std::to_string(i + 1);
entity_ids[i] = entity_id;
for (size_t j = i + 1; j < entities.size(); ++j)
{
if (entities[i] == entities[j])
entity_ids[j] = entity_id;
}
}
for (size_t ix = 0; auto &e : entities)
{
auto k = e.front();
const auto &entity_id = entity_ids[ix++];
std::string comp_id = get_comp_id(k);
for (auto &k : e)
atom_site.update_value(get_condition(k), "label_entity_id", entity_id);
}
if (not waters.empty())
{
std::string waterEntityID = std::to_string(entities.size() + 1);
for (auto &k : waters)
atom_site.update_value(get_condition(k), "label_entity_id", waterEntityID);
}
}
void fillLabelAsymID(category &atom_site)
{
std::map<std::tuple<std::string, std::string>, std::string> mapAuthAsymIDAndEntityToLabelAsymID;
// pray that label_entity_id is filled in and use that to discriminate between asyms
if (atom_site.has_item("label_asym_id"))
{
for (const auto &[label_entity_id, auth_asym_id, label_asym_id] :
atom_site.find<std::optional<std::string>, std::string, std::string>(
key("label_asym_id") != cif::null, "label_entity_id", "auth_asym_id", "label_asym_id"))
{
if (not label_entity_id.has_value())
continue;
auto key = make_tuple(auth_asym_id, *label_entity_id);
auto i = mapAuthAsymIDAndEntityToLabelAsymID.find(key);
if (i == mapAuthAsymIDAndEntityToLabelAsymID.end())
mapAuthAsymIDAndEntityToLabelAsymID.emplace(make_pair(key, label_asym_id));
else if (i->second != label_asym_id)
{
if (cif::VERBOSE > 0)
std::clog << "Inconsistent assignment of label_asym_id for the tuple entity_id: " << *label_entity_id << " and auth_asym_id: " << auth_asym_id << '\n';
mapAuthAsymIDAndEntityToLabelAsymID.clear();
break;
}
}
}
else
{
// horror scenario..
// We filled in entity_ids, right? use those along with auth_asym_id
// to come up with new label_asym_ids
atom_site.add_item("label_asym_id");
for (auto key : atom_site.rows<std::string, std::string>(
"auth_asym_id", "label_entity_id"))
{
if (not mapAuthAsymIDAndEntityToLabelAsymID.contains(key))
{
std::string asym_id = cif_id_for_number(mapAuthAsymIDAndEntityToLabelAsymID.size());
mapAuthAsymIDAndEntityToLabelAsymID[key] = asym_id;
}
}
}
for (const auto &[key, value] : mapAuthAsymIDAndEntityToLabelAsymID)
{
const auto &[auth_asym_id, label_entity_id] = key;
atom_site.update_value(
cif::key("label_asym_id") == null and
cif::key("auth_asym_id") == auth_asym_id and
cif::key("label_entity_id") == label_entity_id,
"label_asym_id", value);
}
// Check to see if we're done
if (atom_site.contains(key("label_asym_id") == cif::null))
{
// nope, not yet.
throw std::runtime_error("atom_site category still contains records with empty label_asym_id, don't know how to continue");
}
}
void fixNegativeSeqID(category &atom_site)
{
std::set<std::string> asymsWithNegativeSeqID;
for (auto asym_id : atom_site.find<std::string>(key("label_seq_id") < 0, "label_asym_id"))
asymsWithNegativeSeqID.emplace(asym_id);
for (auto asym_id : asymsWithNegativeSeqID)
{
// create a pseudo entity_poly_seq first
std::vector<std::tuple<std::string, int>> poly_seq;
for (auto key : atom_site.find<std::string, int>(key("label_asym_id") == asym_id, "auth_seq_id", "label_seq_id"))
{
if (poly_seq.empty() or poly_seq.back() != key)
poly_seq.emplace_back(key);
}
// simply renumber all items, but only if it is really a poly (i.e. size > 1)
if (poly_seq.size() > 1)
{
int seq_id = 1;
for (const auto &[auth_seq_id, label_seq_id] : poly_seq)
{
for (auto row : atom_site.find(key("label_asym_id") == asym_id and
key("auth_seq_id") == auth_seq_id and
key("label_seq_id") == label_seq_id))
{
row.assign("label_seq_id", std::to_string(seq_id), false, false);
}
++seq_id;
}
}
else if (poly_seq.size() == 1) // a monomer?
{
const auto &[auth_seq_id, label_seq_id] = poly_seq.front();
for (auto row : atom_site.find(key("label_asym_id") == asym_id and
key("auth_seq_id") == auth_seq_id and
key("label_seq_id") == label_seq_id))
{
row.assign("label_seq_id", ".", false, false);
}
}
}
}
void checkChemCompRecords(datablock &db)
{
auto &cf = compound_factory::instance();
auto &chem_comp = db["chem_comp"];
for (auto chem_comp_entry : chem_comp)
{
auto compound = cf.create(chem_comp_entry["id"].text());
if (not compound)
std::cerr << "Unknown compound: " << chem_comp_entry["id"].text() << '\n';
else
{
std::vector<item> items;
if (not chem_comp_entry["type"])
items.emplace_back(item{ "type", compound->type() });
if (not chem_comp_entry["name"])
items.emplace_back(item{ "name", compound->name() });
if (not chem_comp_entry["formula"])
items.emplace_back(item{ "formula", compound->formula() });
if (not chem_comp_entry["formula_weight"])
items.emplace_back(item{ "formula_weight", compound->formula_weight() });
if (not items.empty())
chem_comp_entry.assign(items);
}
}
}
void checkAtomRecords(datablock &db)
{
......@@ -42,46 +340,50 @@ void checkAtomRecords(datablock &db)
auto &atom_type = db["atom_type"];
auto &chem_comp = db["chem_comp"];
// Some common errors: missing label_asym_id for some of the atom records
if (atom_site.contains(key("label_asym_id") == cif::null))
fillLabelAsymID(atom_site);
// And negative seq_id values
if (atom_site.contains(key("label_seq_id") < 0))
fixNegativeSeqID(atom_site);
for (auto row : atom_site)
{
const auto &[symbol, label_asym_id, auth_asym_id, label_comp_id, auth_comp_id, label_seq_id, auth_seq_id, label_atom_id, auth_atom_id] =
row.get<std::string, std::optional<std::string>, std::optional<std::string>, std::optional<std::string>, std::optional<std::string>,
std::optional<int>, std::optional<std::string>, std::optional<std::string>, std::optional<std::string>>(
"type_symbol", "label_asym_id", "auth_asym_id", "label_comp_id", "auth_comp_id", "label_seq_id", "auth_seq_id", "label_atom_id", "auth_atom_id");
if (symbol.empty())
residue_key_type k = row.get<std::optional<std::string>,
std::optional<int>,
std::optional<std::string>,
std::optional<std::string>,
std::optional<int>,
std::optional<std::string>>(
"auth_asym_id", "auth_seq_id", "auth_comp_id",
"label_asym_id", "label_seq_id", "label_comp_id");
if (row["type_symbol"].empty())
throw std::runtime_error("Missing type symbol in atom_site record");
std::string symbol{ row["type_symbol"].text() };
if (atom_type.count("symbol"_key == symbol) == 0)
atom_type.emplace({ { "symbol", symbol } });
if (not(label_asym_id.has_value() or auth_asym_id.has_value()))
if (not has_asym_id(k))
throw std::runtime_error("atom_site records does not have a label_asym_id nor an auth_asym_id, cannot continue");
if (not(label_comp_id.has_value() or auth_comp_id.has_value()))
if (not has_comp_id(k))
throw std::runtime_error("atom_site records does not have a label_comp_id nor an auth_comp_id, cannot continue");
if (not(label_atom_id.has_value() or auth_atom_id.has_value()))
if (not has_seq_id(k))
throw std::runtime_error("atom_site records does not have a label_atom_id nor an auth_atom_id, cannot continue");
std::string asym_id = label_asym_id.value_or(*auth_asym_id);
std::string comp_id = label_comp_id.value_or(*auth_comp_id);
std::string asym_id = get_asym_id(k);
std::string comp_id = get_comp_id(k);
bool is_peptide = cf.is_known_peptide(comp_id);
bool is_peptide = cf.is_peptide(comp_id);
auto compound = cf.create(comp_id);
if (not compound)
throw std::runtime_error("Missing compound information for " + comp_id);
std::string mon_nstd_flag(".");
if (is_peptide)
{
if (compound_factory::kAAMap.find(comp_id) != compound_factory::kAAMap.end())
mon_nstd_flag = "y";
else
mon_nstd_flag = "n";
}
auto chem_comp_entry = chem_comp.find_first("id"_key == comp_id);
if (not chem_comp_entry)
......@@ -89,7 +391,7 @@ void checkAtomRecords(datablock &db)
chem_comp.emplace({ //
{ "id", comp_id },
{ "type", compound->type() },
{ "mon_nstd_flag", mon_nstd_flag },
{ "mon_nstd_flag", cf.is_std_monomer(comp_id) ? "y" : "n" },
{ "name", compound->name() },
{ "formula", compound->formula() },
{ "formula_weight", compound->formula_weight() } });
......@@ -101,7 +403,7 @@ void checkAtomRecords(datablock &db)
if (not chem_comp_entry["type"])
items.emplace_back(item{ "type", compound->type() });
if (not chem_comp_entry["mon_nstd_flag"])
items.emplace_back(item{ "mon_nstd_flag", mon_nstd_flag });
items.emplace_back(item{ "mon_nstd_flag", cf.is_std_monomer(comp_id) ? "y" : "n" });
if (not chem_comp_entry["name"])
items.emplace_back(item{ "name", compound->name() });
if (not chem_comp_entry["formula"])
......@@ -110,23 +412,135 @@ void checkAtomRecords(datablock &db)
items.emplace_back(item{ "formula_weight", compound->formula_weight() });
if (not items.empty())
chem_comp_entry.assign(std::move(items));
chem_comp_entry.assign(items);
}
if (is_peptide and not(label_seq_id.has_value() or auth_seq_id.has_value()))
if (is_peptide and not has_seq_id(k))
throw std::runtime_error("atom_site record has peptide comp_id but no sequence number, cannot continue");
std::string seq_id;
if (label_seq_id.has_value())
seq_id = std::to_string(*label_seq_id);
else if (auth_seq_id.has_value())
seq_id = *auth_seq_id;
row.assign({ //
{ "auth_asym_id", auth_asym_id.value_or(*label_asym_id) },
{ "auth_seq_id", auth_seq_id.value_or(std::to_string(*label_seq_id)) },
{ "auth_comp_id", auth_comp_id.value_or(*label_comp_id) },
{ "auth_atom_id", auth_atom_id.value_or(*label_atom_id) } });
int seq_id = get_seq_id(k);
if (row["label_seq_id"].empty())
row["label_seq_id"] = std::to_string(seq_id);
if (row["label_atom_id"].empty())
row["label_atom_id"] = row["auth_atom_id"].text();
if (row["label_asym_id"].empty())
row["label_asym_id"] = row["auth_asym_id"].text();
if (row["label_seq_id"].empty())
row["label_seq_id"] = row["auth_seq_id"].text();
if (row["label_comp_id"].empty())
row["label_comp_id"] = row["auth_comp_id"].text();
if (row["label_atom_id"].empty())
row["label_atom_id"] = row["auth_atom_id"].text();
// Rewrite the coordinates and other items that look better in a fixed format
// Be careful not to nuke invalidly formatted data here
for (auto [item_name, prec] : std::vector<std::tuple<std::string_view, std::string::size_type>>{
{ "cartn_x", 3 },
{ "cartn_y", 3 },
{ "cartn_z", 3 },
{ "occupancy", 2 },
{ "b_iso_or_equiv", 2 } })
{
if (row[item_name].empty())
continue;
float v;
auto s = row.get<std::string>(item_name);
if (auto [ptr, ec] = cif::from_chars(s.data(), s.data() + s.length(), v); ec != std::errc())
continue;
if (s.length() < prec + 1 or s[s.length() - prec - 1] != '.')
{
char b[12];
if (auto [ptr, ec] = cif::to_chars(b, b + sizeof(b), v, cif::chars_format::fixed, prec); ec == std::errc())
row.assign(item_name, { b, static_cast<std::string::size_type>(ptr - b) }, false, false);
}
}
}
// auto *cv = atom_site.get_cat_validator();
// if (cv)
// {
// // See if there are items that are no longer known
// for (auto item_name : atom_site.get_items())
// {
// if (cv->get_validator_for_item(item_name) != nullptr)
// continue;
// auto r = atom_site.find_first(key(item_name) != null);
// if (not r)
// {
// if (cif::VERBOSE > 0)
// std::clog << "Dropping unknown item " << item_name << '\n';
// atom_site.remove_item(item_name);
// }
// else if (cif::VERBOSE > 0)
// std::clog << "Keeping unknown item " << std::quoted(item_name) << " in atom_site since it is not empty\n";
// }
// }
}
void checkAtomAnisotropRecords(datablock &db)
{
using namespace literals;
auto &atom_site = db["atom_site"];
auto &atom_site_anisotrop = db["atom_site_anisotrop"];
// auto m_validator = db.get_validator();
// if (not m_validator)
// return;
std::vector<row_handle> to_be_deleted;
bool warnReplaceTypeSymbol = true;
for (auto row : atom_site_anisotrop)
{
auto parents = atom_site_anisotrop.get_parents(row, atom_site);
if (parents.size() != 1)
{
to_be_deleted.emplace_back(row);
continue;
}
// this happens sometimes (Phenix):
auto parent = parents.front();
if (row["type_symbol"].empty())
row["type_symbol"] = parent["type_symbol"].text();
else if (row["type_symbol"].text() != parent["type_symbol"].text())
{
if (cif::VERBOSE and std::exchange(warnReplaceTypeSymbol, false))
std::clog << "Replacing type_symbol in atom_site_anisotrop record(s)\n";
row["type_symbol"] != parent["type_symbol"].text();
}
if (row["pdbx_auth_alt_id"].empty())
row["pdbx_auth_alt_id"] = parent["pdbx_auth_alt_id"].text();
if (row["pdbx_label_seq_id"].empty())
row["pdbx_label_seq_id"] = parent["label_seq_id"].text();
if (row["pdbx_label_asym_id"].empty())
row["pdbx_label_asym_id"] = parent["label_asym_id"].text();
if (row["pdbx_label_atom_id"].empty())
row["pdbx_label_atom_id"] = parent["label_atom_id"].text();
if (row["pdbx_label_comp_id"].empty())
row["pdbx_label_comp_id"] = parent["label_comp_id"].text();
if (row["pdbx_PDB_model_num"].empty())
row["pdbx_PDB_model_num"] = parent["pdbx_PDB_model_num"].text();
}
if (not to_be_deleted.empty())
{
if (cif::VERBOSE > 0)
std::clog << "Dropped " << to_be_deleted.size() << " anisotrop records since they did not have exactly one parent\n";
for (auto row : to_be_deleted)
atom_site_anisotrop.erase(row);
}
}
......@@ -135,14 +549,18 @@ void createStructAsym(datablock &db)
auto &atom_site = db["atom_site"];
auto &struct_asym = db["struct_asym"];
for (auto label_asym_id : atom_site.rows<std::string>("label_asym_id"))
for (const auto &[label_asym_id, entity_id] : atom_site.rows<std::string, std::string>("label_asym_id", "label_entity_id"))
{
if (label_asym_id.empty())
throw std::runtime_error("File contains atom_site records without a label_asym_id");
if (struct_asym.count(key("id") == label_asym_id) == 0)
{
struct_asym.emplace({ //
{ "id", label_asym_id } });
struct_asym.emplace({
// clang-format off
{ "id", label_asym_id },
{ "entity_id", entity_id }
//clang-format on
});
}
}
}
......@@ -154,39 +572,39 @@ void createEntity(datablock &db)
auto &cf = compound_factory::instance();
auto &atom_site = db["atom_site"];
atom_site.add_column("label_entity_id");
atom_site.add_item("label_entity_id");
auto &struct_asym = db["struct_asym"];
struct_asym.add_column("entity_id");
struct_asym.add_item("entity_id");
std::map<std::string,std::vector<std::tuple<std::string,int>>> asyms;
std::map<std::string, std::vector<std::tuple<std::string, int>>> asyms;
for (auto asym_id : db["struct_asym"].rows<std::string>("id"))
{
int last_seq_id = -1;
for (const auto &[comp_id, seq_id] : atom_site.find<std::string,int>("label_asym_id"_key == asym_id, "label_comp_id", "label_seq_id"))
for (const auto &[comp_id, seq_id] : atom_site.find<std::string, int>("label_asym_id"_key == asym_id, "label_comp_id", "label_seq_id"))
{
if (seq_id == last_seq_id)
continue;
last_seq_id = seq_id;
asyms[asym_id].emplace_back(comp_id, last_seq_id);
}
}
auto less = [](const std::vector<std::tuple<std::string,int>> &a, const std::vector<std::tuple<std::string,int>> &b)
auto less = [](const std::vector<std::tuple<std::string, int>> &a, const std::vector<std::tuple<std::string, int>> &b)
{
int d = static_cast<int>(a.size()) - static_cast<int>(b.size());
return d == 0 ? a > b : d > 0;
};
std::set<std::vector<std::tuple<std::string,int>>,decltype(less)> entities(less);
std::set<std::vector<std::tuple<std::string, int>>, decltype(less)> entities(less);
for (const auto &[asym_id, content] : asyms)
entities.emplace(content);
auto water_weight = cf.create("HOH")->formula_weight();
int poly_count = 0;
......@@ -230,7 +648,7 @@ void createEntity(datablock &db)
{
if (ac != content)
continue;
atom_site.update_value("label_asym_id"_key == asym_id, "label_entity_id", entity_id);
struct_asym.update_value("id"_key == asym_id, "entity_id", entity_id);
......@@ -240,13 +658,12 @@ void createEntity(datablock &db)
count = atom_site.count("label_asym_id"_key == asym_id and "label_atom_id"_key == "O");
}
entity.emplace({ //
entity.emplace({ //
{ "id", entity_id },
{ "type", type },
{ "pdbx_description", desc },
{ "formula_weight", weight },
{ "pdbx_number_of_molecules", count }
});
{ "pdbx_number_of_molecules", count } });
}
}
......@@ -263,16 +680,17 @@ void createEntityPoly(datablock &db)
{
std::string type;
int last_seq_id = -1;
std::string seq, seq_can;
std::map<std::string, std::string> seq, seq_can;
bool non_std_monomer = false;
bool non_std_linkage = false;
std::string pdb_strand_id;
std::vector<std::string> pdb_strand_ids;
for (const auto &[comp_id, seq_id, auth_asym_id] : atom_site.find<std::string,int,std::string>("label_entity_id"_key == entity_id, "label_comp_id", "label_seq_id", "auth_asym_id"))
for (const auto &[comp_id, seq_id, auth_asym_id] : atom_site.find<std::string, int, std::string>(
"label_entity_id"_key == entity_id, "label_comp_id", "label_seq_id", "auth_asym_id"))
{
if (seq_id == last_seq_id)
continue;
last_seq_id = seq_id;
auto c = cf.create(comp_id);
......@@ -280,16 +698,20 @@ void createEntityPoly(datablock &db)
std::string letter;
char letter_can;
// TODO: Perhaps we should improve this...
// TODO: Perhaps we should improve this...
if (type != "other")
{
std::string c_type;
if (cf.is_known_base(comp_id))
if (cf.is_base(comp_id))
{
c_type = "polydeoxyribonucleotide";
letter = letter_can = compound_factory::kBaseMap.at(comp_id);
letter_can = compound_factory::kBaseMap.at(comp_id);
if (comp_id.length() == 1)
letter = letter_can;
else
letter = '(' + letter_can + ')';
}
else if (cf.is_known_peptide(comp_id))
else if (cf.is_peptide(comp_id))
{
c_type = "polypeptide(L)";
letter = letter_can = compound_factory::kAAMap.at(comp_id);
......@@ -301,7 +723,7 @@ void createEntityPoly(datablock &db)
letter_can = c->one_letter_code();
if (letter_can == 0)
letter_can = 'X';
letter = '(' + comp_id + ')';
non_std_linkage = true;
......@@ -326,40 +748,60 @@ void createEntityPoly(datablock &db)
type = "other";
}
seq += letter;
seq_can += letter_can;
seq[auth_asym_id] += letter;
seq_can[auth_asym_id] += letter_can;
pdb_strand_id = auth_asym_id;
if (find(pdb_strand_ids.begin(), pdb_strand_ids.end(), auth_asym_id) == pdb_strand_ids.end())
pdb_strand_ids.emplace_back(auth_asym_id);
}
for (auto i = seq.begin() + 80; i < seq.end(); i += 80)
i = seq.insert(i, '\n') + 1;
for (auto i = seq_can.begin() + 76; i < seq_can.end(); i += 76)
// sanity check, each seq should be the same
std::string entity_seq;
std::string entity_seq_can;
for (const auto &[auth_asym_id_1, seq_1] : seq)
{
if (entity_seq.empty())
{
entity_seq = seq_1;
entity_seq_can = seq_can[auth_asym_id_1];
}
for (const auto &[auth_asym_id_2, seq_2] : seq)
{
if (auth_asym_id_1 != auth_asym_id_2 and seq_1 != seq_2)
throw std::runtime_error("Inconsistent sequences for auth_asym_id " + auth_asym_id_1 + " and " + auth_asym_id_2);
}
}
for (auto i = entity_seq.begin() + 80; i < entity_seq.end(); i += 80)
i = entity_seq.insert(i, '\n') + 1;
for (auto i = entity_seq_can.begin() + 76; i < entity_seq_can.end(); i += 76)
{
auto j = i;
while (j < i + 4 and j < seq_can.end())
while (j < i + 4 and j < entity_seq_can.end())
{
if (*j == '(')
break;
++j;
}
if (j < seq_can.end())
i = seq_can.insert(j, '\n') + 1;
if (j < entity_seq_can.end())
i = entity_seq_can.insert(j, '\n') + 1;
else
i = j;
}
entity_poly.emplace({ //
entity_poly.emplace({ //
{ "entity_id", entity_id },
{ "type", type },
{ "nstd_linkage", non_std_linkage },
{ "nstd_monomer", non_std_monomer },
{ "pdbx_seq_one_letter_code", seq },
{ "pdbx_seq_one_letter_code_can", seq_can },
{ "pdbx_strand_id", pdb_strand_id }
});
{ "pdbx_seq_one_letter_code", entity_seq },
{ "pdbx_seq_one_letter_code_can", entity_seq_can },
{ "pdbx_strand_id", join(pdb_strand_ids, ",") } });
}
}
......@@ -381,7 +823,7 @@ void createEntityPolySeq(datablock &db)
std::string last_comp_id;
std::string asym_id = struct_asym.find_first<std::string>("entity_id"_key == entity_id, "id");
for (const auto &[comp_id, seq_id] : atom_site.find<std::string,int>("label_entity_id"_key == entity_id and "label_asym_id"_key == asym_id, "label_comp_id", "label_seq_id"))
for (const auto &[comp_id, seq_id] : atom_site.find<std::string, int>("label_entity_id"_key == entity_id and "label_asym_id"_key == asym_id, "label_comp_id", "label_seq_id"))
{
bool hetero = false;
......@@ -395,27 +837,22 @@ void createEntityPolySeq(datablock &db)
if (hetero)
{
entity_poly_seq.back().assign({
{ "hetero", true }
});
entity_poly_seq.back().assign({ { "hetero", true } });
}
entity_poly_seq.emplace({ //
entity_poly_seq.emplace({ //
{ "entity_id", entity_id },
{ "num", seq_id },
{ "mon_id", comp_id },
{ "hetero", hetero }
});
{ "hetero", hetero } });
last_seq_id = seq_id;
last_comp_id = comp_id;
}
// you cannot assume this is correct...
entity_poly_seq.sort([](row_handle a, row_handle b)
{
return a.get<int>("num") < b.get<int>("num");
});
{ return a.get<int>("num") < b.get<int>("num"); });
}
}
......@@ -432,21 +869,32 @@ void createPdbxPolySeqScheme(datablock &db)
auto &struct_asym = db["struct_asym"];
auto &pdbx_poly_seq_scheme = db["pdbx_poly_seq_scheme"];
for (const auto &[entity_id, pdb_strand_id] : entity_poly.rows<std::string, std::string>("entity_id", "pdbx_strand_id"))
// Find the mapping between asym_id and pdb_strand_id first
std::map<std::string, std::string> asym_id_to_pdb_strand_map;
for (const auto &[entity_id, pdb_strand_ids] : entity_poly.rows<std::string, std::string>("entity_id", "pdbx_strand_id"))
{
for (auto pdb_strand_id : split(pdb_strand_ids, ","))
{
auto asym_id = atom_site.find_first<std::string>(key("label_entity_id") == entity_id and key("auth_asym_id") == pdb_strand_id, "label_asym_id");
asym_id_to_pdb_strand_map[asym_id] = pdb_strand_id;
}
}
for (auto &entity_id : entity_poly.rows<std::string>("entity_id"))
{
for (auto asym_id : struct_asym.find<std::string>("entity_id"_key == entity_id, "id"))
{
for (const auto &[comp_id, num, hetero] : entity_poly_seq.find<std::string,int,bool>("entity_id"_key == entity_id, "mon_id", "num", "hetero"))
for (const auto &[comp_id, num, hetero] : entity_poly_seq.find<std::string, int, bool>("entity_id"_key == entity_id, "mon_id", "num", "hetero"))
{
const auto &[auth_seq_num, auth_mon_id, ins_code] =
atom_site.find_first<std::string,std::string,std::optional<std::string>>(
atom_site.find_first<std::string, std::string, std::optional<std::string>>(
"label_asym_id"_key == asym_id and "label_seq_id"_key == num,
"auth_seq_id", "auth_comp_id", "pdbx_PDB_ins_code"
);
"auth_seq_id", "auth_comp_id", "pdbx_PDB_ins_code");
pdbx_poly_seq_scheme.emplace({ //
{ "asym_id", asym_id },
{ "entity_id", entity_id },
{ "entity_id", entity_id },
{ "seq_id", num },
{ "mon_id", comp_id },
{ "ndb_seq_num", num },
......@@ -454,16 +902,89 @@ void createPdbxPolySeqScheme(datablock &db)
{ "auth_seq_num", auth_seq_num },
{ "pdb_mon_id", auth_mon_id },
{ "auth_mon_id", auth_mon_id },
{ "pdb_strand_id", pdb_strand_id },
{ "pdb_strand_id", asym_id_to_pdb_strand_map[asym_id] },
{ "pdb_ins_code", ins_code },
{ "hetero", hetero }
});
{ "hetero", hetero } });
}
}
}
}
void reconstruct_pdbx(file &file, std::string_view dictionary)
// Some programs write out a ndb_poly_seq_scheme, which has been replaced by pdbx_poly_seq_scheme
void comparePolySeqSchemes(datablock &db)
{
auto &ndb_poly_seq_scheme = db["ndb_poly_seq_scheme"];
auto &pdbx_poly_seq_scheme = db["pdbx_poly_seq_scheme"];
// Since often ndb_poly_seq_scheme only contains an id and mon_id item
// we assume that it should match the accompanying pdbx_poly_seq
std::vector<std::string> asym_ids_ndb, asym_ids_pdbx;
for (auto asym_id : ndb_poly_seq_scheme.rows<std::string>("id"))
{
auto i = std::lower_bound(asym_ids_ndb.begin(), asym_ids_ndb.end(), asym_id);
if (i == asym_ids_ndb.end() or *i != asym_id)
asym_ids_ndb.insert(i, asym_id);
}
for (auto asym_id : pdbx_poly_seq_scheme.rows<std::string>("asym_id"))
{
auto i = std::lower_bound(asym_ids_pdbx.begin(), asym_ids_pdbx.end(), asym_id);
if (i == asym_ids_pdbx.end() or *i != asym_id)
asym_ids_pdbx.insert(i, asym_id);
}
// If we have different Asym ID's assume the ndb is invalid.
if (asym_ids_ndb != asym_ids_pdbx)
{
if (cif::VERBOSE > 0)
std::clog << "The asym ID's of ndb_poly_seq_scheme and pdbx_poly_seq_scheme are not equal, dropping ndb_poly_seq_scheme\n";
ndb_poly_seq_scheme.clear();
}
else
{
for (const auto &asym_id : asym_ids_ndb)
{
bool valid = true;
auto ndb_range = ndb_poly_seq_scheme.find(key("id") == asym_id);
auto pdbx_range = pdbx_poly_seq_scheme.find(key("asym_id") == asym_id);
for (auto ndb_i = ndb_range.begin(), pdbx_i = pdbx_range.begin();
ndb_i != ndb_range.end() or pdbx_i != pdbx_range.end(); ++ndb_i, ++pdbx_i)
{
if (ndb_i == ndb_range.end() or pdbx_i == pdbx_range.end())
{
if (cif::VERBOSE > 0)
std::clog << "The sequences in ndb_poly_seq_scheme and pdbx_poly_seq_scheme are unequal in size for asym ID " << asym_id << '\n';
valid = false;
break;
}
auto ndb_mon_id = ndb_i->get<std::string>("mon_id");
auto pdbx_mon_id = pdbx_i->get<std::string>("mon_id");
if (ndb_mon_id != pdbx_mon_id)
{
if (cif::VERBOSE > 0)
std::clog << "The sequences in ndb_poly_seq_scheme and pdbx_poly_seq_scheme contain different mon ID's for asym ID " << asym_id << '\n';
valid = false;
break;
}
}
if (not valid)
{
if (cif::VERBOSE > 0)
std::clog << "Dropping asym ID " << asym_id << " from ndb_poly_seq_scheme\n";
ndb_poly_seq_scheme.erase(key("id") == asym_id);
}
}
}
}
bool reconstruct_pdbx(file &file, std::string_view dictionary)
{
if (file.empty())
throw std::runtime_error("Cannot reconstruct PDBx, file seems to be empty");
......@@ -498,64 +1019,262 @@ void reconstruct_pdbx(file &file, std::string_view dictionary)
entry_id = entry.front().get<std::string>("id");
}
// Start with chem_comp, it is often missing many fields
// that can easily be filled in.
checkChemCompRecords(db);
// If the data is really horrible, it might not contain entities
if (not db["atom_site"].find_first(key("label_entity_id") != null))
createEntityIDs(db);
// Now see if atom records make sense at all
checkAtomRecords(db);
std::vector<std::string> invalidCategories;
// clean up each category
for (auto &cat : db)
{
auto cv = validator.get_validator_for_category(cat.name());
if (not cv)
continue;
for (auto link : validator.get_links_for_child(cat.name()))
try
{
if (link->m_parent_category != "entry")
auto cv = validator.get_validator_for_category(cat.name());
if (not cv)
continue;
// So, this cat should have a link to the entry
// Start by renaming items that may have old names based on alias info
auto pk = find(link->m_parent_keys.begin(), link->m_parent_keys.end(), "id");
if (pk == link->m_parent_keys.end())
continue;
for (auto item_name : cat.get_items())
{
auto iv = cv->get_validator_for_item(item_name);
if (iv) // know, must be OK then`
continue;
auto ix = pk - link->m_parent_keys.begin();
auto key = link->m_child_keys[ix];
iv = cv->get_validator_for_aliased_item(item_name);
if (not iv)
continue;
for (auto row : cat)
if (cif::VERBOSE > 0)
std::clog << "Renaming " << item_name << " to " << iv->m_item_name << " in category " << cat.name() << '\n';
cat.rename_item(item_name, iv->m_item_name);
}
// In case a single ID field is missing, add it
if (cv->m_keys.size() == 1 and not cat.has_item(cv->m_keys.front()))
{
row.assign({ { key, entry_id } });
std::string key = cv->m_keys.front();
auto iv = cv->get_validator_for_item(key);
bool number = iv != nullptr and
iv->m_type != nullptr and
iv->m_type->m_primitive_type == cif::DDL_PrimitiveType::Numb;
for (size_t ix = 0; auto row : cat)
{
if (number)
row.assign(key, std::to_string(++ix), false, false);
else
row.assign(key, cif::cif_id_for_number(ix++), false, false);
}
}
}
// See if all categories that need a key do have a value
if (cv->m_keys.size() == 1)
{
auto key = cv->m_keys.front();
for (auto row : cat)
for (auto link : validator.get_links_for_child(cat.name()))
{
if (link->m_parent_category != "entry")
continue;
// So, this cat should have a link to the entry
auto pk = find(link->m_parent_keys.begin(), link->m_parent_keys.end(), "id");
if (pk == link->m_parent_keys.end())
continue;
auto ix = pk - link->m_parent_keys.begin();
auto key = link->m_child_keys[ix];
for (auto row : cat)
{
row.assign({ { key, entry_id } });
}
}
// Fill in all mandatory items
for (auto item : cv->m_mandatory_items)
{
auto ord = row.get<std::string>(key.c_str());
if (ord.empty())
row.assign({ //
{ key, cat.get_unique_id([](int nr)
{ return std::to_string(nr); }) } });
if (not cat.has_item(item))
{
if (cif::VERBOSE > 0)
std::clog << "Adding mandatory item " << item << " to category " << cat.name() << '\n';
cat.add_item(item);
cat.update_value(all(), item, "?");
}
}
// validate all values, and if they do not validate replace the content with an unknown flag
for (auto item_name : cat.get_items())
{
auto iv = cv->get_validator_for_item(item_name);
if (not iv)
{
// Drop this item
cat.remove_item(item_name);
continue;
}
auto ix = cat.get_item_ix(item_name);
for (auto row : cat)
{
std::error_code ec;
std::string_view value = row[ix].text();
if (not iv->validate_value(value, ec))
{
if (cif::VERBOSE > 0)
std::clog << "Replacing value (" << std::quoted(value) << ") for item " << item_name << " in category " << cat.name() << " since it does not validate\n";
row[ix] = "?";
}
}
}
enum class State
{
Start,
MissingKeys,
DuplicateKeys
} state = State::Start;
for (;;)
{
// See if we can build an index
try
{
cat.set_validator(&validator, db);
}
catch (const missing_key_error &ex)
{
if (state == State::MissingKeys)
{
if (cif::VERBOSE > 0)
std::clog << "Repairing failed for category " << cat.name() << ", missing keys remain: " << ex.what() << '\n';
throw;
}
state = State::MissingKeys;
auto key = ex.get_key();
if (cif::VERBOSE > 0)
std::clog << "Need to add key " << key << " to category " << cat.name() << '\n';
for (auto row : cat)
{
auto ord = row.get<std::string>(key.c_str());
if (ord.empty())
row.assign({ //
{ key, cat.get_unique_value(key) } });
}
continue;
}
catch (const duplicate_key_error &ex)
{
if (state == State::DuplicateKeys)
{
if (cif::VERBOSE > 0)
std::clog << "Repairing failed for category " << cat.name() << ", duplicate keys remain: " << ex.what() << '\n';
throw;
}
state = State::DuplicateKeys;
if (cif::VERBOSE > 0)
std::clog << "Attempt to fix " << cat.name() << " failed: " << ex.what() << '\n';
// replace items that do not define a relation to a parent
std::set<std::string> replaceableKeys;
for (auto key : cv->m_keys)
{
bool replaceable = true;
for (auto lv : validator.get_links_for_child(cat.name()))
{
if (find(lv->m_child_keys.begin(), lv->m_child_keys.end(), key) != lv->m_child_keys.end())
{
replaceable = false;
break;
}
}
if (replaceable)
replaceableKeys.insert(key);
}
if (replaceableKeys.empty())
throw std::runtime_error("Cannot repair category " + cat.name() + " since it contains duplicate keys that cannot be replaced");
for (auto key : replaceableKeys)
{
for (auto row : cat)
row.assign(key, cat.get_unique_value(key), false, false);
}
continue;
}
break;
}
}
catch (const std::exception &ex)
{
if (cif::VERBOSE > 0)
std::clog << ex.what() << '\n';
std::clog << "Will drop category " << cat.name() << " since it cannot be repaired\n";
invalidCategories.emplace_back(cat.name());
}
}
file.load_dictionary(dictionary);
for (auto cat_name : invalidCategories)
{
auto i = find_if(db.begin(), db.end(), [cat_name](const category &cat)
{ return cat.name() == cat_name; });
if (i != db.end())
db.erase(i);
}
// Now create any missing categories
db["chem_comp"].reorder_by_index();
// First, see if atom records make sense at all
// Will take care of atom_type and chem_comp as well.
checkAtomRecords(db);
file.load_dictionary(dictionary);
if (db.get("atom_site_anisotrop"))
checkAtomAnisotropRecords(db);
// Now create any missing categories
// Next make sure we have struct_asym records
if (db.get("struct_asym") == nullptr)
createStructAsym(db);
if (db.get("entity") == nullptr)
createEntity(db);
if (db.get("pdbx_poly_seq_scheme") == nullptr)
createPdbxPolySeqScheme(db);
if (db.get("ndb_poly_seq_scheme") != nullptr)
comparePolySeqSchemes(db);
// skip unknown categories for now
bool valid = true;
for (auto &cat : db)
valid = valid and (cat.get_cat_validator() == nullptr or cat.is_valid());
return valid and is_valid_pdbx_file(file, dictionary);
}
} // namespace cif::pdb
......@@ -69,26 +69,65 @@ condition get_parents_condition(const validator &validator, row_handle rh, const
bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
{
using namespace cif::literals;
std::error_code ec;
bool result = is_valid_pdbx_file(file, dictionary, ec);
return result and ec == std::errc();
}
auto &cf = cif::compound_factory::instance();
auto &validator = cif::validator_factory::instance().operator[](dictionary);
bool is_valid_pdbx_file(const file &file, std::error_code &ec)
{
bool result = false;
if (file.empty())
ec = make_error_code(validation_error::empty_file);
else
{
std::string dictionary = "mmcif_pdbx";
for (auto &db : file)
{
auto audit_conform = db.get("audit_conform");
if (audit_conform == nullptr)
continue;
if (not audit_conform->empty())
{
auto specified_dict = audit_conform->front()["dict_name"];
if (not specified_dict.empty())
dictionary = specified_dict.as<std::string>();
}
break;
}
result = is_valid_pdbx_file(file, dictionary, ec);
}
return result;
}
bool is_valid_pdbx_file(const file &file, std::string_view dictionary, std::error_code &ec)
{
using namespace cif::literals;
bool result = true;
try
{
auto &cf = cif::compound_factory::instance();
auto &validator = cif::validator_factory::instance().operator[](dictionary);
if (file.empty())
throw validation_error("Empty file");
throw std::runtime_error("Empty file");
auto &db = file.front();
if (db.empty())
throw validation_error("Empty datablock");
throw std::runtime_error("Empty datablock");
auto &atom_site = db["atom_site"];
if (atom_site.empty())
throw validation_error("Empty or missing atom_site category");
throw std::runtime_error("Empty or missing atom_site category");
auto &pdbx_poly_seq_scheme = db["pdbx_poly_seq_scheme"];
......@@ -106,34 +145,38 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
last_seq_id = *seq_id;
auto comp_id = r.get<std::string>("label_comp_id");
if (not cf.is_known_peptide(comp_id))
if (not cf.is_monomer(comp_id))
continue;
auto p = pdbx_poly_seq_scheme.find(get_parents_condition(validator, r, pdbx_poly_seq_scheme));
if (p.size() != 1)
throw validation_error("For each residue in atom_site that is a residue in a polymer there should be exactly one pdbx_poly_seq_scheme record");
{
if (cif::VERBOSE > 0)
std::clog << "In atom_site record: " << r["id"].text() << '\n';
throw std::runtime_error("For each monomer in atom_site there should be exactly one pdbx_poly_seq_scheme record");
}
}
auto &entity = db["entity"];
if (entity.empty())
throw validation_error("Entity category is missing or empty");
throw std::runtime_error("Entity category is missing or empty");
auto &entity_poly = db["entity_poly"];
if (entity_poly.empty())
throw validation_error("Entity_poly category is missing or empty");
throw std::runtime_error("Entity_poly category is missing or empty");
auto &entity_poly_seq = db["entity_poly_seq"];
if (entity_poly_seq.empty())
throw validation_error("Entity_poly_seq category is missing or empty");
throw std::runtime_error("Entity_poly_seq category is missing or empty");
auto &struct_asym = db["struct_asym"];
if (struct_asym.empty())
throw validation_error("struct_asym category is missing or empty");
throw std::runtime_error("struct_asym category is missing or empty");
for (auto entity_id : entity.find<std::string>("type"_key == "polymer", "id"))
{
if (entity_poly.count("entity_id"_key == entity_id) != 1)
throw validation_error("There should be exactly one entity_poly record per polymer entity");
throw std::runtime_error("There should be exactly one entity_poly record per polymer entity");
const auto entity_poly_type = entity_poly.find1<std::string>("entity_id"_key == entity_id, "type");
......@@ -151,7 +194,7 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
"seq_id"_key == num and
"hetero"_key == hetero) != 1)
{
throw validation_error("For each entity_poly_seq record there should be exactly one pdbx_poly_seq record");
throw std::runtime_error("For each entity_poly_seq record there should be exactly one pdbx_poly_seq record");
}
}
}
......@@ -163,11 +206,11 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
"num"_key == seq_id and
"hetero"_key == hetero) != 1)
{
throw validation_error("For each pdbx_poly_seq/struct_asym record there should be exactly one entity_poly_seq record");
throw std::runtime_error("For each pdbx_poly_seq/struct_asym record there should be exactly one entity_poly_seq record");
}
if ((mon_per_seq_id[seq_id].size() > 1) != hetero)
throw validation_error("Mismatch between the hetero flag in the poly seq schemes and the number residues per seq_id");
throw std::runtime_error("Mismatch between the hetero flag in the poly seq schemes and the number residues per seq_id");
}
for (const auto &[seq_id, mon_ids] : mon_per_seq_id)
......@@ -183,8 +226,8 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
"label_asym_id"_key == asym_id and
"label_seq_id"_key == seq_id and not std::move(cond);
if (atom_site.exists(std::move(cond)))
throw validation_error("An atom_site record exists that has no parent in the poly seq scheme categories");
if (atom_site.contains(std::move(cond)))
throw std::runtime_error("An atom_site record exists that has no parent in the poly seq scheme categories");
}
}
......@@ -205,13 +248,12 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
for (auto comp_id : comp_ids)
{
std::string letter;
if (cf.is_known_base(comp_id))
letter = compound_factory::kBaseMap.at(comp_id);
else if (cf.is_known_peptide(comp_id))
letter = compound_factory::kAAMap.at(comp_id);
else
if (can)
{
if (can)
if (compound_factory::kBaseMap.contains(comp_id))
letter = compound_factory::kBaseMap.at(comp_id);
else
{
auto c = cf.create(comp_id);
if (c and c->one_letter_code())
......@@ -219,6 +261,13 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
else
letter = "X";
}
}
else
{
if (compound_factory::kAAMap.contains(comp_id))
letter = compound_factory::kAAMap.at(comp_id);
else if (comp_id.length() == 1 and compound_factory::kBaseMap.contains(comp_id))
letter = compound_factory::kBaseMap.at(comp_id);
else
letter = '(' + comp_id + ')';
}
......@@ -250,7 +299,7 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
seq->erase(std::remove_if(seq->begin(), seq->end(), [](char ch) { return std::isspace(ch); }), seq->end());
if (not seq_match(false, seq->begin(), seq->end()))
throw validation_error("Sequences do not match for entity " + entity_id);
throw std::runtime_error("Sequences do not match for entity " + entity_id);
}
if (not seq_can.has_value())
......@@ -261,11 +310,10 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
else
{
seq_can->erase(std::remove_if(seq_can->begin(), seq_can->end(), [](char ch) { return std::isspace(ch); }), seq_can->end());
if (not seq_match(true, seq_can->begin(), seq_can->end()))
throw validation_error("Canonical sequences do not match for entity " + entity_id);
throw std::runtime_error("Canonical sequences do not match for entity " + entity_id);
}
}
result = true;
......@@ -275,8 +323,12 @@ bool is_valid_pdbx_file(const file &file, std::string_view dictionary)
result = false;
if (cif::VERBOSE > 0)
std::clog << ex.what() << '\n';
ec = make_error_code(validation_error::not_valid_pdbx);
}
if (not result and ec == std::errc())
ec = make_error_code(validation_error::not_valid_pdbx);
return result;
}
......
......@@ -29,44 +29,44 @@
namespace cif
{
void row_handle::assign(uint16_t column, std::string_view value, bool updateLinked, bool validate)
void row_handle::assign(uint16_t item, std::string_view value, bool updateLinked, bool validate)
{
if (not m_category)
throw std::runtime_error("uninitialized row");
m_category->update_value(m_row, column, value, updateLinked, validate);
m_category->update_value(m_row, item, value, updateLinked, validate);
}
uint16_t row_handle::get_column_ix(std::string_view name) const
uint16_t row_handle::get_item_ix(std::string_view name) const
{
if (not m_category)
throw std::runtime_error("uninitialized row");
return m_category->get_column_ix(name);
return m_category->get_item_ix(name);
}
std::string_view row_handle::get_column_name(uint16_t ix) const
std::string_view row_handle::get_item_name(uint16_t ix) const
{
if (not m_category)
throw std::runtime_error("uninitialized row");
return m_category->get_column_name(ix);
return m_category->get_item_name(ix);
}
uint16_t row_handle::add_column(std::string_view name)
uint16_t row_handle::add_item(std::string_view name)
{
if (not m_category)
throw std::runtime_error("uninitialized row");
return m_category->add_column(name);
return m_category->add_item(name);
}
void row_handle::swap(uint16_t column, row_handle &b)
void row_handle::swap(uint16_t item, row_handle &b)
{
if (not m_category)
throw std::runtime_error("uninitialized row");
m_category->swap_item(column, *this, b);
m_category->swap_item(item, *this, b);
}
// --------------------------------------------------------------------
......@@ -86,7 +86,7 @@ row_initializer::row_initializer(row_handle rh)
auto &i = r->operator[](ix);
if (not i)
continue;
emplace_back(cat.get_column_name(ix), i.text());
emplace_back(cat.get_item_name(ix), i.text());
}
}
......
......@@ -35,24 +35,24 @@ namespace cif
// --------------------------------------------------------------------
// This really makes a difference, having our own tolower routines
const uint8_t kCharToLowerMap[256] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
const uint8_t kCharToLowerMap[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
// --------------------------------------------------------------------
......@@ -171,7 +171,7 @@ std::string trim_right_copy(std::string_view s)
e = pe;
}
return {s.begin(), e};
return { s.begin(), e };
}
std::string trim_left_copy(std::string_view s)
......@@ -185,7 +185,7 @@ std::string trim_left_copy(std::string_view s)
b = std::next(b);
}
return {b, s.end()};
return { b, s.end() };
}
void trim_left(std::string &s)
......@@ -215,19 +215,19 @@ std::string trim_copy(std::string_view s)
// --------------------------------------------------------------------
std::tuple<std::string, std::string> split_tag_name(std::string_view tag)
std::tuple<std::string, std::string> split_item_name(std::string_view item_name)
{
if (tag.empty())
throw std::runtime_error("empty tag");
if (tag[0] != '_')
throw std::runtime_error("tag '" + std::string { tag } + "' does not start with underscore");
if (item_name.empty())
throw std::runtime_error("empty item_name");
if (item_name[0] != '_')
throw std::runtime_error("item_name '" + std::string{ item_name } + "' does not start with underscore");
auto s = tag.find('.');
auto s = item_name.find('.');
if (s == std::string::npos)
// throw std::runtime_error("tag does not contain dot (" + std::string{ tag } + ')');
return std::tuple<std::string, std::string>{ "", tag.substr(1) };
// throw std::runtime_error("item_name does not contain dot (" + std::string{ item_name } + ')');
return std::tuple<std::string, std::string>{ "", item_name.substr(1) };
else
return std::tuple<std::string, std::string>{tag.substr(1, s - 1), tag.substr(s + 1)};
return std::tuple<std::string, std::string>{ item_name.substr(1, s - 1), item_name.substr(s + 1) };
}
// --------------------------------------------------------------------
......@@ -242,8 +242,7 @@ std::string cif_id_for_number(int number)
result += static_cast<char>('A' + r);
number = (number - r) / 26 - 1;
}
while (number >= 0);
} while (number >= 0);
std::reverse(result.begin(), result.end());
......@@ -298,29 +297,29 @@ enum LineBreakClass
kLBC_Unknown
};
const LineBreakClass kASCII_LBTable[128] =
{
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
kLBC_CombiningMark, kLBC_BreakAfter, kLBC_LineFeed, kLBC_MandatoryBreak, kLBC_MandatoryBreak, kLBC_CarriageReturn, kLBC_CombiningMark, kLBC_CombiningMark,
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
kLBC_Space, kLBC_Exlamation, kLBC_Quotation, kLBC_Alphabetic, kLBC_PrefixNumeric, kLBC_PostfixNumeric, kLBC_Alphabetic, kLBC_Quotation,
kLBC_OpenPunctuation, kLBC_CloseParenthesis, kLBC_Alphabetic, kLBC_PrefixNumeric,
// comma treated differently here, it is not a numeric separator in PDB
kLBC_SymbolAllowingBreakAfter /* kLBC_InfixNumericSeparator */,
kLBC_Hyphen, kLBC_InfixNumericSeparator, kLBC_SymbolAllowingBreakAfter,
kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric,
kLBC_Numeric, kLBC_Numeric, kLBC_InfixNumericSeparator, kLBC_InfixNumericSeparator, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Exlamation,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_OpenPunctuation, kLBC_PrefixNumeric, kLBC_CloseParenthesis, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_OpenPunctuation, kLBC_BreakAfter, kLBC_ClosePunctuation, kLBC_Alphabetic, kLBC_CombiningMark};
const LineBreakClass kASCII_LBTable[128] = {
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
kLBC_CombiningMark, kLBC_BreakAfter, kLBC_LineFeed, kLBC_MandatoryBreak, kLBC_MandatoryBreak, kLBC_CarriageReturn, kLBC_CombiningMark, kLBC_CombiningMark,
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark, kLBC_CombiningMark,
kLBC_Space, kLBC_Exlamation, kLBC_Quotation, kLBC_Alphabetic, kLBC_PrefixNumeric, kLBC_PostfixNumeric, kLBC_Alphabetic, kLBC_Quotation,
kLBC_OpenPunctuation, kLBC_CloseParenthesis, kLBC_Alphabetic, kLBC_PrefixNumeric,
// comma treated differently here, it is not a numeric separator in PDB
kLBC_SymbolAllowingBreakAfter /* kLBC_InfixNumericSeparator */,
kLBC_Hyphen, kLBC_InfixNumericSeparator, kLBC_SymbolAllowingBreakAfter,
kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric, kLBC_Numeric,
kLBC_Numeric, kLBC_Numeric, kLBC_InfixNumericSeparator, kLBC_InfixNumericSeparator, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Exlamation,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_OpenPunctuation, kLBC_PrefixNumeric, kLBC_CloseParenthesis, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic,
kLBC_Alphabetic, kLBC_Alphabetic, kLBC_Alphabetic, kLBC_OpenPunctuation, kLBC_BreakAfter, kLBC_ClosePunctuation, kLBC_Alphabetic, kLBC_CombiningMark
};
std::string::const_iterator nextLineBreak(std::string::const_iterator text, std::string::const_iterator end)
{
......@@ -338,33 +337,33 @@ std::string::const_iterator nextLineBreak(std::string::const_iterator text, std:
const breakAction brkTable[27][27] = {
// OP CL CP QU GL NS EX SY IS PR PO NU AL ID IN HY BA BB B2 ZW CM WJ H2 H3 JL JV JT
/* OP */ {PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, CPB, PBK, PBK, PBK, PBK, PBK, PBK},
/* CL */ {DBK, PBK, PBK, IBK, IBK, PBK, PBK, PBK, PBK, IBK, IBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* CP */ {DBK, PBK, PBK, IBK, IBK, PBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* QU */ {PBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK},
/* GL */ {IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK},
/* NS */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* EX */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* SY */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* IS */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* PR */ {IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, IBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK},
/* PO */ {IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* NU */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* AL */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* ID */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* IN */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* HY */ {DBK, PBK, PBK, IBK, DBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* BA */ {DBK, PBK, PBK, IBK, DBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* BB */ {IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK},
/* B2 */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, PBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* ZW */ {DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK},
/* CM */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK},
/* WJ */ {IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK},
/* H2 */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, IBK, IBK},
/* H3 */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, IBK},
/* JL */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, DBK},
/* JV */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, IBK, IBK},
/* JT */ {DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, IBK},
/* OP */ { PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, PBK, CPB, PBK, PBK, PBK, PBK, PBK, PBK },
/* CL */ { DBK, PBK, PBK, IBK, IBK, PBK, PBK, PBK, PBK, IBK, IBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* CP */ { DBK, PBK, PBK, IBK, IBK, PBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* QU */ { PBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
/* GL */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
/* NS */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* EX */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* SY */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* IS */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* PR */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, IBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
/* PO */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* NU */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* AL */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* ID */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* IN */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* HY */ { DBK, PBK, PBK, IBK, DBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* BA */ { DBK, PBK, PBK, IBK, DBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* BB */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
/* B2 */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, IBK, IBK, DBK, PBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* ZW */ { DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK, PBK, DBK, DBK, DBK, DBK, DBK, DBK, DBK },
/* CM */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, DBK, IBK, IBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, DBK },
/* WJ */ { IBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, IBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, IBK },
/* H2 */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, IBK, IBK },
/* H3 */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, IBK },
/* JL */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, IBK, IBK, IBK, IBK, DBK },
/* JV */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, IBK, IBK },
/* JT */ { DBK, PBK, PBK, IBK, IBK, IBK, PBK, PBK, PBK, DBK, IBK, DBK, DBK, DBK, IBK, IBK, IBK, DBK, DBK, PBK, CIB, PBK, DBK, DBK, DBK, DBK, IBK },
};
uint8_t ch = static_cast<uint8_t>(*text);
......@@ -418,7 +417,7 @@ std::string::const_iterator nextLineBreak(std::string::const_iterator text, std:
std::vector<std::string> wrapLine(const std::string &text, size_t width)
{
std::vector<std::string> result;
std::vector<size_t> offsets = {0};
std::vector<size_t> offsets = { 0 };
auto b = text.begin();
while (b != text.end())
......
......@@ -39,39 +39,47 @@
// the code will use boost::regex instead.
#if USE_BOOST_REGEX
#include <boost/regex.hpp>
# include <boost/regex.hpp>
using boost::regex;
#else
#include <regex>
# include <regex>
using std::regex;
#endif
namespace cif
{
struct regex_impl : public regex
validation_exception::validation_exception(std::error_code ec)
: runtime_error(ec.message())
{
regex_impl(std::string_view rx)
: regex(rx.begin(), rx.end(), regex::extended | regex::optimize)
{
}
};
}
validation_error::validation_error(const std::string &msg)
: m_msg(msg)
validation_exception::validation_exception(std::error_code ec, std::string_view category)
: runtime_error((ec.message() + "; category: ").append(category))
{
}
validation_error::validation_error(const std::string &cat, const std::string &item, const std::string &msg)
: m_msg("When validating _" + cat + '.' + item + ": " + msg)
validation_exception::validation_exception(std::error_code ec, std::string_view category, std::string_view item)
: runtime_error((ec.message() + "; category: ").append(category).append("; item: ").append(item))
{
}
// --------------------------------------------------------------------
DDL_PrimitiveType map_to_primitive_type(std::string_view s)
struct regex_impl : public regex
{
regex_impl(std::string_view rx)
: regex(rx.begin(), rx.end(), regex::extended | regex::optimize)
{
}
};
// --------------------------------------------------------------------
DDL_PrimitiveType map_to_primitive_type(std::string_view s, std::error_code &ec) noexcept
{
DDL_PrimitiveType result;
ec = {};
DDL_PrimitiveType result = DDL_PrimitiveType::Char;
if (iequals(s, "char"))
result = DDL_PrimitiveType::Char;
else if (iequals(s, "uchar"))
......@@ -79,7 +87,16 @@ DDL_PrimitiveType map_to_primitive_type(std::string_view s)
else if (iequals(s, "numb"))
result = DDL_PrimitiveType::Numb;
else
throw validation_error("Not a known primitive type");
ec = make_error_code(validation_error::not_a_known_primitive_type);
return result;
}
DDL_PrimitiveType map_to_primitive_type(std::string_view s)
{
std::error_code ec;
auto result = map_to_primitive_type(s, ec);
if (ec)
throw std::system_error(ec, std::string{ s });
return result;
}
......@@ -196,63 +213,72 @@ int type_validator::compare(std::string_view a, std::string_view b) const
// --------------------------------------------------------------------
// void ValidateItem::addLinked(ValidateItem* parent, const std::string& parentItem, const std::string& childItem)
//{
//// if (mParent != nullptr and VERBOSE)
//// cerr << "replacing parent in " << mCategory->m_name << " from " << mParent->mCategory->m_name << " to " << parent->mCategory->m_name << endl;
//// mParent = parent;
//
// if (m_type == nullptr and parent != nullptr)
// m_type = parent->m_type;
//
// if (parent != nullptr)
// {
// mLinked.push_back({parent, parentItem, childItem});
//
// parent->mChildren.insert(this);
////
//// if (mCategory->mKeys == std::vector<std::string>{mTag})
//// parent->mForeignKeys.insert(this);
// }
//}
void item_validator::operator()(std::string_view value) const
{
std::error_code ec;
if (not validate_value(value, ec))
throw std::system_error(ec, std::string{ value } + " does not match rx for " + m_item_name);
}
bool item_validator::validate_value(std::string_view value, std::error_code &ec) const noexcept
{
ec = {};
if (not value.empty() and value != "?" and value != ".")
{
if (m_type != nullptr and not regex_match(value.begin(), value.end(), *m_type->m_rx))
throw validation_error(m_category->m_name, m_tag, "Value '" + std::string{ value } + "' does not match type expression for type " + m_type->m_name);
if (not m_enums.empty())
{
if (m_enums.count(std::string{ value }) == 0)
throw validation_error(m_category->m_name, m_tag, "Value '" + std::string{ value } + "' is not in the list of allowed values");
}
ec = make_error_code(validation_error::value_does_not_match_rx);
else if (not m_enums.empty() and m_enums.count(std::string{ value }) == 0)
ec = make_error_code(validation_error::value_is_not_in_enumeration_list);
}
return ec == std::errc();
}
// --------------------------------------------------------------------
void category_validator::addItemValidator(item_validator &&v)
void category_validator::add_item_validator(item_validator &&v)
{
if (v.m_mandatory)
m_mandatory_fields.insert(v.m_tag);
m_mandatory_items.insert(v.m_item_name);
v.m_category = this;
auto r = m_item_validators.insert(std::move(v));
if (not r.second and VERBOSE >= 4)
std::cout << "Could not add validator for item " << v.m_tag << " to category " << m_name << '\n';
std::cout << "Could not add validator for item " << v.m_item_name << " to category " << m_name << '\n';
}
const item_validator *category_validator::get_validator_for_item(std::string_view tag) const
const item_validator *category_validator::get_validator_for_item(std::string_view item_name) const
{
const item_validator *result = nullptr;
auto i = m_item_validators.find(item_validator{ std::string(tag) });
auto i = m_item_validators.find(item_validator{ std::string(item_name) });
if (i != m_item_validators.end())
result = &*i;
else if (VERBOSE > 4)
std::cout << "No validator for tag " << tag << '\n';
std::cout << "No validator for item " << item_name << '\n';
return result;
}
const item_validator *category_validator::get_validator_for_aliased_item(std::string_view item_name) const
{
const item_validator *result = nullptr;
for (auto &iv : m_item_validators)
{
for (auto &ai : iv.m_aliases)
{
const auto &[cat, name] = split_item_name(ai.m_name);
if (iequals(name, item_name) and iequals(cat, m_name))
{
result = &iv;
break;
}
}
if (result)
break;
}
return result;
}
......@@ -295,19 +321,19 @@ const category_validator *validator::get_validator_for_category(std::string_view
return result;
}
item_validator *validator::get_validator_for_item(std::string_view tag) const
item_validator *validator::get_validator_for_item(std::string_view item_name) const
{
item_validator *result = nullptr;
std::string cat, item;
std::tie(cat, item) = split_tag_name(tag);
std::tie(cat, item) = split_item_name(item_name);
auto *cv = get_validator_for_category(cat);
if (cv != nullptr)
result = const_cast<item_validator *>(cv->get_validator_for_item(item));
if (result == nullptr and VERBOSE > 4)
std::cout << "No validator for item " << tag << '\n';
std::cout << "No validator for item " << item_name << '\n';
return result;
}
......@@ -332,11 +358,11 @@ void validator::add_link_validator(link_validator &&v)
auto piv = pcv->get_validator_for_item(v.m_parent_keys[i]);
if (piv == nullptr)
throw std::runtime_error("unknown parent tag _" + v.m_parent_category + '.' + v.m_parent_keys[i]);
throw std::runtime_error("unknown parent item _" + v.m_parent_category + '.' + v.m_parent_keys[i]);
auto civ = ccv->get_validator_for_item(v.m_child_keys[i]);
if (civ == nullptr)
throw std::runtime_error("unknown child tag _" + v.m_child_category + '.' + v.m_child_keys[i]);
throw std::runtime_error("unknown child item _" + v.m_child_category + '.' + v.m_child_keys[i]);
if (civ->m_type == nullptr and piv->m_type != nullptr)
const_cast<item_validator *>(civ)->m_type = piv->m_type;
......@@ -351,7 +377,7 @@ std::vector<const link_validator *> validator::get_links_for_parent(std::string_
for (auto &l : m_link_validators)
{
if (l.m_parent_category == category)
if (iequals(l.m_parent_category, category))
result.push_back(&l);
}
......@@ -364,19 +390,32 @@ std::vector<const link_validator *> validator::get_links_for_child(std::string_v
for (auto &l : m_link_validators)
{
if (l.m_child_category == category)
if (iequals(l.m_child_category, category))
result.push_back(&l);
}
return result;
}
void validator::report_error(const std::string &msg, bool fatal) const
void validator::report_error(std::error_code ec, bool fatal) const
{
if (m_strict or fatal)
throw validation_error(msg);
else if (VERBOSE > 0)
std::cerr << msg << '\n';
throw validation_exception(ec);
else
std::cerr << ec.message() << '\n';
}
void validator::report_error(std::error_code ec, std::string_view category,
std::string_view item, bool fatal) const
{
auto ex = item.empty() ?
validation_exception(ec, category) :
validation_exception(ec, category, item);
if (m_strict or fatal)
throw ex;
else
std::cerr << ex.what() << '\n';
}
// --------------------------------------------------------------------
......@@ -438,12 +477,12 @@ const validator &validator_factory::operator[](std::string_view dictionary_name)
if (not std::filesystem::exists(p, ec) or ec)
{
for (const char *dir : {
#if defined(CACHE_DIR)
# if defined(CACHE_DIR)
CACHE_DIR,
#endif
#if defined(DATA_DIR)
# endif
# if defined(DATA_DIR)
DATA_DIR
#endif
# endif
})
{
auto p2 = std::filesystem::path(dir) / p;
......
# We're using the older version 2 of Catch2
find_package(Catch2 QUIET)
if(NOT Catch2_FOUND)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.13.9)
FetchContent_MakeAvailable(Catch2)
set(Catch2_VERSION "2.13.9")
endif()
list(
APPEND
CIFPP_tests
unit-v2
unit-3d
format
model
rename-compound
sugar
spinner
reconstruction
validate-pdbx)
add_library(test-main OBJECT "${CMAKE_CURRENT_SOURCE_DIR}/test-main.cpp")
target_link_libraries(test-main cifpp::cifpp Catch2::Catch2)
if(${Catch2_VERSION} VERSION_GREATER_EQUAL 3.0.0)
target_compile_definitions(test-main PUBLIC CATCH22=0)
else()
target_compile_definitions(test-main PUBLIC CATCH22=1)
endif()
foreach(CIFPP_TEST IN LISTS CIFPP_tests)
set(CIFPP_TEST "${CIFPP_TEST}-test")
set(CIFPP_TEST_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/${CIFPP_TEST}.cpp")
add_executable(
${CIFPP_TEST} ${CIFPP_TEST_SOURCE} $<TARGET_OBJECTS:test-main>)
if(${Catch2_VERSION} VERSION_GREATER_EQUAL 3.0.0)
target_compile_definitions(${CIFPP_TEST} PUBLIC CATCH22=0)
else()
target_compile_definitions(${CIFPP_TEST} PUBLIC CATCH22=1)
endif()
target_link_libraries(${CIFPP_TEST} PRIVATE Threads::Threads cifpp::cifpp
Catch2::Catch2)
target_include_directories(${CIFPP_TEST} PRIVATE "${EIGEN_INCLUDE_DIR}")
if(MSVC)
# Specify unwind semantics so that MSVC knowns how to handle exceptions
target_compile_options(${CIFPP_TEST} PRIVATE /EHsc)
endif()
add_custom_target(
"run-${CIFPP_TEST}"
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Run${CIFPP_TEST}.touch ${CIFPP_TEST})
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Run${CIFPP_TEST}.touch
COMMAND $<TARGET_FILE:${CIFPP_TEST}> --data-dir
${CMAKE_CURRENT_SOURCE_DIR})
add_test(NAME ${CIFPP_TEST} COMMAND $<TARGET_FILE:${CIFPP_TEST}> --data-dir
${CMAKE_CURRENT_SOURCE_DIR})
endforeach()
\ No newline at end of file
......@@ -24,7 +24,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <catch2/catch.hpp>
#include "test-main.hpp"
#include <stdexcept>
......
......@@ -26,8 +26,6 @@
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include <stdexcept>
#include <cif++.hpp>
......
data_1CBS
#
_entry.id 1CBS
#
loop_
_atom_site.group_PDB
_atom_site.id
_atom_site.type_symbol
_atom_site.pdbx_PDB_ins_code
_atom_site.Cartn_x
_atom_site.Cartn_y
_atom_site.Cartn_z
_atom_site.occupancy
_atom_site.B_iso_or_equiv
_atom_site.pdbx_formal_charge
_atom_site.label_seq_id
_atom_site.label_comp_id
_atom_site.label_asym_id
_atom_site.label_atom_id
_atom_site.pdbx_PDB_model_num
ATOM 1 N ? 16.979 13.301 44.555 1.00 30.05 ? 1 PRO A N 1
ATOM 2 C ? 18.150 13.525 43.680 1.00 28.82 ? 1 PRO A CA 1
ATOM 3 C ? 18.656 14.966 43.784 1.00 26.59 ? 1 PRO A C 1
ATOM 4 O ? 17.890 15.889 44.078 1.00 26.84 ? 1 PRO A O 1
ATOM 5 C ? 17.678 13.270 42.255 1.00 29.24 ? 1 PRO A CB 1
ATOM 6 C ? 16.248 13.734 42.347 1.00 29.29 ? 1 PRO A CG 1
ATOM 7 C ? 15.762 13.216 43.724 1.00 30.71 ? 1 PRO A CD 1
ATOM 8 N ? 19.957 15.139 43.558 1.00 24.04 ? 2 ASN A N 1
ATOM 9 C ? 20.576 16.457 43.578 1.00 20.79 ? 2 ASN A CA 1
ATOM 10 C ? 21.301 16.714 42.262 1.00 16.75 ? 2 ASN A C 1
ATOM 11 O ? 22.402 16.215 42.028 1.00 15.23 ? 2 ASN A O 1
ATOM 12 C ? 21.559 16.620 44.724 1.00 22.81 ? 2 ASN A CB 1
ATOM 13 C ? 22.240 17.968 44.685 1.00 24.29 ? 2 ASN A CG 1
ATOM 14 O ? 21.612 18.984 44.358 1.00 21.87 ? 2 ASN A OD1 1
ATOM 15 N ? 23.537 17.983 44.966 1.00 27.94 ? 2 ASN A ND2 1
ATOM 16 N ? 20.637 17.477 41.402 1.00 14.69 ? 3 PHE A N 1
ATOM 17 C ? 21.144 17.838 40.087 1.00 12.62 ? 3 PHE A CA 1
ATOM 18 C ? 22.152 18.987 40.140 1.00 12.43 ? 3 PHE A C 1
ATOM 19 O ? 22.796 19.289 39.136 1.00 12.12 ? 3 PHE A O 1
ATOM 20 C ? 19.970 18.262 39.188 1.00 10.74 ? 3 PHE A CB 1
ATOM 21 C ? 19.073 17.128 38.750 1.00 11.85 ? 3 PHE A CG 1
ATOM 22 C ? 18.066 16.646 39.581 1.00 10.90 ? 3 PHE A CD1 1
ATOM 23 C ? 19.189 16.588 37.475 1.00 13.26 ? 3 PHE A CD2 1
ATOM 24 C ? 17.200 15.662 39.149 1.00 9.12 ? 3 PHE A CE1 1
ATOM 25 C ? 18.312 15.594 37.041 1.00 11.76 ? 3 PHE A CE2 1
ATOM 26 C ? 17.324 15.137 37.878 1.00 10.30 ? 3 PHE A CZ 1
ATOM 27 N ? 22.282 19.630 41.299 1.00 11.24 ? 4 SER A N 1
ATOM 28 C ? 23.170 20.780 41.464 1.00 11.30 ? 4 SER A CA 1
ATOM 29 C ? 24.627 20.568 41.091 1.00 10.39 ? 4 SER A C 1
ATOM 30 O ? 25.201 19.532 41.384 1.00 10.24 ? 4 SER A O 1
ATOM 31 C ? 23.112 21.301 42.906 1.00 13.53 ? 4 SER A CB 1
ATOM 32 O ? 21.821 21.787 43.240 1.00 16.76 ? 4 SER A OG 1
ATOM 33 N ? 25.224 21.572 40.460 1.00 9.87 ? 5 GLY A N 1
ATOM 34 C ? 26.628 21.486 40.103 1.00 10.86 ? 5 GLY A CA 1
ATOM 35 C ? 26.985 22.158 38.794 1.00 11.21 ? 5 GLY A C 1
ATOM 36 O ? 26.123 22.761 38.142 1.00 9.91 ? 5 GLY A O 1
ATOM 37 N ? 28.277 22.142 38.475 1.00 10.41 ? 6 ASN A N 1
ATOM 38 C ? 28.796 22.676 37.211 1.00 11.06 ? 6 ASN A CA 1
ATOM 39 C ? 29.117 21.435 36.378 1.00 10.33 ? 6 ASN A C 1
ATOM 40 O ? 29.947 20.603 36.754 1.00 11.28 ? 6 ASN A O 1
ATOM 41 C ? 30.023 23.548 37.445 1.00 12.95 ? 6 ASN A CB 1
ATOM 42 C ? 29.675 24.816 38.200 1.00 18.08 ? 6 ASN A CG 1
ATOM 43 O ? 29.022 25.708 37.665 1.00 19.52 ? 6 ASN A OD1 1
ATOM 44 N ? 30.047 24.872 39.467 1.00 21.23 ? 6 ASN A ND2 1
ATOM 45 N ? 28.399 21.289 35.272 1.00 8.66 ? 7 TRP A N 1
ATOM 46 C ? 28.518 20.119 34.424 1.00 8.74 ? 7 TRP A CA 1
ATOM 47 C ? 29.246 20.352 33.092 1.00 9.63 ? 7 TRP A C 1
ATOM 48 O ? 29.064 21.389 32.440 1.00 9.45 ? 7 TRP A O 1
ATOM 49 C ? 27.115 19.563 34.152 1.00 8.00 ? 7 TRP A CB 1
ATOM 50 C ? 26.325 19.198 35.391 1.00 8.01 ? 7 TRP A CG 1
ATOM 51 C ? 25.556 20.031 36.159 1.00 8.29 ? 7 TRP A CD1 1
ATOM 52 C ? 26.174 17.885 35.947 1.00 7.60 ? 7 TRP A CD2 1
ATOM 53 N ? 24.922 19.308 37.156 1.00 9.20 ? 7 TRP A NE1 1
ATOM 54 C ? 25.286 17.987 37.046 1.00 8.73 ? 7 TRP A CE2 1
ATOM 55 C ? 26.694 16.625 35.618 1.00 6.99 ? 7 TRP A CE3 1
ATOM 56 C ? 24.909 16.876 37.815 1.00 7.67 ? 7 TRP A CZ2 1
ATOM 57 C ? 26.320 15.527 36.380 1.00 7.58 ? 7 TRP A CZ3 1
ATOM 58 C ? 25.433 15.663 37.468 1.00 5.92 ? 7 TRP A CH2 1
ATOM 59 N ? 30.052 19.368 32.702 1.00 9.39 ? 8 LYS A N 1
ATOM 60 C ? 30.802 19.424 31.450 1.00 11.56 ? 8 LYS A CA 1
ATOM 61 C ? 30.342 18.243 30.611 1.00 10.56 ? 8 LYS A C 1
ATOM 62 O ? 30.091 17.158 31.138 1.00 10.14 ? 8 LYS A O 1
ATOM 63 C ? 32.308 19.360 31.710 1.00 15.20 ? 8 LYS A CB 1
ATOM 64 C ? 32.785 18.080 32.313 1.00 18.52 ? 8 LYS A CG 1
ATOM 65 C ? 34.263 18.182 32.618 1.00 26.26 ? 8 LYS A CD 1
ATOM 66 C ? 35.091 18.499 31.378 1.00 29.22 ? 8 LYS A CE 1
ATOM 67 N ? 35.067 17.393 30.369 1.00 32.48 ? 8 LYS A NZ 1
ATOM 68 N ? 30.222 18.447 29.308 1.00 8.21 ? 9 ILE A N 1
ATOM 69 C ? 29.739 17.384 28.441 1.00 8.08 ? 9 ILE A CA 1
ATOM 70 C ? 30.798 16.325 28.117 1.00 7.86 ? 9 ILE A C 1
ATOM 71 O ? 31.990 16.635 28.028 1.00 8.38 ? 9 ILE A O 1
ATOM 72 C ? 29.148 17.997 27.144 1.00 10.70 ? 9 ILE A CB 1
ATOM 73 C ? 28.285 16.981 26.401 1.00 10.95 ? 9 ILE A CG1 1
ATOM 74 C ? 30.261 18.500 26.243 1.00 10.70 ? 9 ILE A CG2 1
ATOM 75 C ? 27.586 17.597 25.207 1.00 13.23 ? 9 ILE A CD1 1
ATOM 76 N ? 30.373 15.067 27.995 1.00 7.08 ? 10 ILE A N 1
ATOM 77 C ? 31.288 13.988 27.656 1.00 7.45 ? 10 ILE A CA 1
ATOM 78 C ? 30.812 13.201 26.441 1.00 8.49 ? 10 ILE A C 1
ATOM 79 O ? 31.561 12.397 25.892 1.00 9.49 ? 10 ILE A O 1
ATOM 80 C ? 31.586 13.023 28.847 1.00 10.28 ? 10 ILE A CB 1
ATOM 81 C ? 30.304 12.393 29.382 1.00 10.51 ? 10 ILE A CG1 1
ATOM 82 C ? 32.349 13.756 29.963 1.00 10.10 ? 10 ILE A CG2 1
ATOM 83 C ? 30.578 11.242 30.325 1.00 12.18 ? 10 ILE A CD1 1
ATOM 84 N ? 29.566 13.419 26.030 1.00 7.59 ? 11 ARG A N 1
ATOM 85 C ? 29.015 12.742 24.851 1.00 8.70 ? 11 ARG A CA 1
ATOM 86 C ? 27.821 13.500 24.290 1.00 9.41 ? 11 ARG A C 1
ATOM 87 O ? 26.990 14.004 25.043 1.00 9.84 ? 11 ARG A O 1
ATOM 88 C ? 28.563 11.316 25.184 1.00 8.07 ? 11 ARG A CB 1
ATOM 89 C ? 27.912 10.616 23.998 1.00 12.26 ? 11 ARG A CG 1
ATOM 90 C ? 27.234 9.340 24.394 1.00 13.46 ? 11 ARG A CD 1
ATOM 91 N ? 28.157 8.304 24.847 1.00 15.44 ? 11 ARG A NE 1
ATOM 92 C ? 28.815 7.470 24.037 1.00 19.59 ? 11 ARG A CZ 1
ATOM 93 N ? 28.677 7.559 22.714 1.00 19.40 ? 11 ARG A NH1 1
ATOM 94 N ? 29.521 6.467 24.547 1.00 17.50 ? 11 ARG A NH2 1
ATOM 95 N ? 27.748 13.594 22.965 1.00 8.84 ? 12 SER A N 1
ATOM 96 C ? 26.621 14.245 22.310 1.00 8.61 ? 12 SER A CA 1
ATOM 97 C ? 26.278 13.431 21.063 1.00 9.48 ? 12 SER A C 1
ATOM 98 O ? 27.159 13.147 20.250 1.00 9.84 ? 12 SER A O 1
ATOM 99 C ? 26.966 15.676 21.925 1.00 9.02 ? 12 SER A CB 1
ATOM 100 O ? 25.863 16.285 21.273 1.00 11.97 ? 12 SER A OG 1
ATOM 101 N ? 25.016 13.038 20.924 1.00 7.59 ? 13 GLU A N 1
ATOM 102 C ? 24.586 12.258 19.768 1.00 9.67 ? 13 GLU A CA 1
ATOM 103 C ? 23.368 12.887 19.118 1.00 9.06 ? 13 GLU A C 1
ATOM 104 O ? 22.457 13.343 19.815 1.00 7.34 ? 13 GLU A O 1
ATOM 105 C ? 24.185 10.833 20.184 1.00 9.72 ? 13 GLU A CB 1
ATOM 106 C ? 25.257 10.018 20.895 1.00 15.17 ? 13 GLU A CG 1
ATOM 107 C ? 26.262 9.340 19.954 1.00 18.75 ? 13 GLU A CD 1
ATOM 108 O ? 26.031 9.310 18.726 1.00 18.53 ? 13 GLU A OE1 1
ATOM 109 O ? 27.286 8.822 20.457 1.00 19.23 ? 13 GLU A OE2 1
ATOM 110 N ? 23.363 12.919 17.786 1.00 8.79 ? 14 ASN A N 1
ATOM 111 C ? 22.202 13.408 17.025 1.00 8.29 ? 14 ASN A CA 1
ATOM 112 C ? 21.813 14.896 17.153 1.00 7.35 ? 14 ASN A C 1
ATOM 113 O ? 20.681 15.245 16.860 1.00 7.00 ? 14 ASN A O 1
ATOM 114 C ? 20.989 12.522 17.383 1.00 7.23 ? 14 ASN A CB 1
ATOM 115 C ? 20.358 11.833 16.172 1.00 9.38 ? 14 ASN A CG 1
ATOM 116 O ? 20.996 11.670 15.128 1.00 10.37 ? 14 ASN A OD1 1
ATOM 117 N ? 19.106 11.436 16.310 1.00 6.35 ? 14 ASN A ND2 1
ATOM 118 N ? 22.734 15.777 17.536 1.00 7.26 ? 15 PHE A N 1
ATOM 119 C ? 22.385 17.198 17.681 1.00 9.06 ? 15 PHE A CA 1
ATOM 120 C ? 22.041 17.878 16.358 1.00 9.15 ? 15 PHE A C 1
ATOM 121 O ? 21.041 18.578 16.265 1.00 8.64 ? 15 PHE A O 1
ATOM 122 C ? 23.497 17.990 18.379 1.00 10.05 ? 15 PHE A CB 1
ATOM 123 C ? 23.102 19.397 18.746 1.00 10.57 ? 15 PHE A CG 1
ATOM 124 C ? 22.032 19.633 19.605 1.00 13.39 ? 15 PHE A CD1 1
ATOM 125 C ? 23.813 20.485 18.254 1.00 11.47 ? 15 PHE A CD2 1
ATOM 126 C ? 21.678 20.929 19.968 1.00 13.52 ? 15 PHE A CE1 1
ATOM 127 C ? 23.467 21.784 18.609 1.00 11.60 ? 15 PHE A CE2 1
ATOM 128 C ? 22.399 22.006 19.469 1.00 13.52 ? 15 PHE A CZ 1
ATOM 129 N ? 22.878 17.699 15.342 1.00 11.17 ? 16 GLU A N 1
ATOM 130 C ? 22.583 18.313 14.053 1.00 12.58 ? 16 GLU A CA 1
ATOM 131 C ? 21.271 17.797 13.468 1.00 11.71 ? 16 GLU A C 1
ATOM 132 O ? 20.503 18.567 12.888 1.00 12.66 ? 16 GLU A O 1
ATOM 133 C ? 23.711 18.081 13.060 1.00 15.91 ? 16 GLU A CB 1
ATOM 134 C ? 23.274 18.337 11.626 1.00 21.31 ? 16 GLU A CG 1
ATOM 135 C ? 24.376 18.878 10.757 1.00 25.39 ? 16 GLU A CD 1
ATOM 136 O ? 25.526 18.984 11.240 1.00 27.92 ? 16 GLU A OE1 1
ATOM 137 O ? 24.084 19.213 9.588 1.00 28.60 ? 16 GLU A OE2 1
ATOM 138 N ? 21.018 16.497 13.619 1.00 11.67 ? 17 GLU A N 1
ATOM 139 C ? 19.785 15.878 13.116 1.00 13.65 ? 17 GLU A CA 1
ATOM 140 C ? 18.529 16.490 13.767 1.00 13.48 ? 17 GLU A C 1
ATOM 141 O ? 17.490 16.662 13.115 1.00 11.68 ? 17 GLU A O 1
ATOM 142 C ? 19.811 14.361 13.325 1.00 17.06 ? 17 GLU A CB 1
ATOM 143 C ? 20.806 13.602 12.430 1.00 23.45 ? 17 GLU A CG 1
ATOM 144 C ? 22.279 13.624 12.909 1.00 27.80 ? 17 GLU A CD 1
ATOM 145 O ? 22.637 14.338 13.881 1.00 26.52 ? 17 GLU A OE1 1
ATOM 146 O ? 23.097 12.897 12.291 1.00 31.80 ? 17 GLU A OE2 1
ATOM 147 N ? 18.640 16.834 15.048 1.00 10.82 ? 18 LEU A N 1
ATOM 148 C ? 17.547 17.468 15.777 1.00 9.45 ? 18 LEU A CA 1
ATOM 149 C ? 17.302 18.849 15.155 1.00 9.27 ? 18 LEU A C 1
ATOM 150 O ? 16.153 19.246 14.927 1.00 9.04 ? 18 LEU A O 1
ATOM 151 C ? 17.931 17.644 17.253 1.00 9.77 ? 18 LEU A CB 1
ATOM 152 C ? 16.921 18.358 18.163 1.00 11.36 ? 18 LEU A CG 1
ATOM 153 C ? 15.817 17.402 18.554 1.00 13.85 ? 18 LEU A CD1 1
ATOM 154 C ? 17.616 18.876 19.409 1.00 12.69 ? 18 LEU A CD2 1
ATOM 155 N ? 18.387 19.568 14.864 1.00 10.75 ? 19 LEU A N 1
ATOM 156 C ? 18.275 20.906 14.276 1.00 11.15 ? 19 LEU A CA 1
ATOM 157 C ? 17.671 20.873 12.874 1.00 12.52 ? 19 LEU A C 1
ATOM 158 O ? 16.932 21.777 12.485 1.00 10.05 ? 19 LEU A O 1
ATOM 159 C ? 19.631 21.616 14.263 1.00 12.01 ? 19 LEU A CB 1
ATOM 160 C ? 20.282 21.963 15.614 1.00 10.42 ? 19 LEU A CG 1
ATOM 161 C ? 21.560 22.763 15.369 1.00 13.01 ? 19 LEU A CD1 1
ATOM 162 C ? 19.312 22.742 16.513 1.00 11.45 ? 19 LEU A CD2 1
ATOM 163 N ? 17.944 19.795 12.150 1.00 14.41 ? 20 LYS A N 1
ATOM 164 C ? 17.427 19.628 10.800 1.00 16.54 ? 20 LYS A CA 1
ATOM 165 C ? 15.902 19.512 10.832 1.00 16.17 ? 20 LYS A C 1
ATOM 166 O ? 15.201 20.164 10.053 1.00 15.90 ? 20 LYS A O 1
ATOM 167 C ? 18.048 18.390 10.157 1.00 20.07 ? 20 LYS A CB 1
ATOM 168 C ? 18.592 18.643 8.765 1.00 26.61 ? 20 LYS A CG 1
ATOM 169 C ? 18.960 17.349 8.027 1.00 30.95 ? 20 LYS A CD 1
ATOM 170 C ? 20.226 16.690 8.579 1.00 35.68 ? 20 LYS A CE 1
ATOM 171 N ? 21.485 17.466 8.342 1.00 39.27 ? 20 LYS A NZ 1
ATOM 172 N ? 15.395 18.700 11.759 1.00 15.31 ? 21 VAL A N 1
ATOM 173 C ? 13.958 18.508 11.927 1.00 14.41 ? 21 VAL A CA 1
ATOM 174 C ? 13.275 19.831 12.316 1.00 15.02 ? 21 VAL A C 1
ATOM 175 O ? 12.150 20.119 11.878 1.00 13.59 ? 21 VAL A O 1
ATOM 176 C ? 13.674 17.422 12.998 1.00 14.93 ? 21 VAL A CB 1
ATOM 177 C ? 12.194 17.383 13.364 1.00 17.29 ? 21 VAL A CG1 1
ATOM 178 C ? 14.115 16.082 12.482 1.00 15.09 ? 21 VAL A CG2 1
ATOM 179 N ? 13.966 20.643 13.119 1.00 14.52 ? 22 LEU A N 1
ATOM 180 C ? 13.432 21.938 13.569 1.00 14.42 ? 22 LEU A CA 1
ATOM 181 C ? 13.478 22.984 12.467 1.00 15.49 ? 22 LEU A C 1
ATOM 182 O ? 13.038 24.115 12.666 1.00 16.81 ? 22 LEU A O 1
ATOM 183 C ? 14.180 22.440 14.818 1.00 13.61 ? 22 LEU A CB 1
ATOM 184 C ? 13.986 21.565 16.069 1.00 13.97 ? 22 LEU A CG 1
ATOM 185 C ? 14.852 22.047 17.225 1.00 13.25 ? 22 LEU A CD1 1
ATOM 186 C ? 12.525 21.580 16.467 1.00 14.62 ? 22 LEU A CD2 1
ATOM 187 N ? 14.062 22.618 11.328 1.00 16.41 ? 23 GLY A N 1
ATOM 188 C ? 14.123 23.516 10.183 1.00 17.05 ? 23 GLY A CA 1
ATOM 189 C ? 15.241 24.539 10.125 1.00 18.00 ? 23 GLY A C 1
ATOM 190 O ? 15.112 25.545 9.425 1.00 19.45 ? 23 GLY A O 1
ATOM 191 N ? 16.320 24.315 10.869 1.00 14.78 ? 24 VAL A N 1
ATOM 192 C ? 17.440 25.241 10.860 1.00 13.71 ? 24 VAL A CA 1
ATOM 193 C ? 18.289 24.983 9.607 1.00 15.09 ? 24 VAL A C 1
ATOM 194 O ? 18.679 23.840 9.334 1.00 14.12 ? 24 VAL A O 1
ATOM 195 C ? 18.297 25.081 12.139 1.00 12.19 ? 24 VAL A CB 1
ATOM 196 C ? 19.465 26.054 12.109 1.00 8.69 ? 24 VAL A CG1 1
ATOM 197 C ? 17.416 25.294 13.388 1.00 11.37 ? 24 VAL A CG2 1
ATOM 198 N ? 18.595 26.047 8.866 1.00 15.37 ? 25 ASN A N 1
ATOM 199 C ? 19.360 25.914 7.635 1.00 17.74 ? 25 ASN A CA 1
ATOM 200 C ? 20.808 25.466 7.819 1.00 18.29 ? 25 ASN A C 1
ATOM 201 O ? 21.377 25.592 8.903 1.00 18.05 ? 25 ASN A O 1
ATOM 202 C ? 19.230 27.172 6.742 1.00 19.41 ? 25 ASN A CB 1
ATOM 203 C ? 20.090 28.351 7.200 1.00 22.35 ? 25 ASN A CG 1
ATOM 204 O ? 21.207 28.189 7.698 1.00 22.64 ? 25 ASN A OD1 1
ATOM 205 N ? 19.602 29.558 6.933 1.00 24.15 ? 25 ASN A ND2 1
ATOM 206 N ? 21.398 24.971 6.733 1.00 18.67 ? 26 VAL A N 1
ATOM 207 C ? 22.755 24.444 6.742 1.00 19.24 ? 26 VAL A CA 1
ATOM 208 C ? 23.825 25.280 7.421 1.00 18.39 ? 26 VAL A C 1
ATOM 209 O ? 24.558 24.764 8.261 1.00 18.50 ? 26 VAL A O 1
ATOM 210 C ? 23.223 24.088 5.320 1.00 20.77 ? 26 VAL A CB 1
ATOM 211 C ? 24.624 23.523 5.378 1.00 22.39 ? 26 VAL A CG1 1
ATOM 212 C ? 22.276 23.084 4.698 1.00 21.28 ? 26 VAL A CG2 1
ATOM 213 N ? 23.932 26.556 7.052 1.00 19.00 ? 27 MET A N 1
ATOM 214 C ? 24.948 27.433 7.628 1.00 19.54 ? 27 MET A CA 1
ATOM 215 C ? 24.734 27.741 9.099 1.00 19.04 ? 27 MET A C 1
ATOM 216 O ? 25.702 27.820 9.849 1.00 18.28 ? 27 MET A O 1
ATOM 217 C ? 25.104 28.736 6.830 1.00 23.31 ? 27 MET A CB 1
ATOM 218 C ? 25.955 28.602 5.552 1.00 29.99 ? 27 MET A CG 1
ATOM 219 S ? 24.975 28.527 4.010 1.00 37.48 ? 27 MET A SD 1
ATOM 220 C ? 26.198 29.150 2.776 1.00 35.24 ? 27 MET A CE 1
ATOM 221 N ? 23.480 27.932 9.507 1.00 16.74 ? 28 LEU A N 1
ATOM 222 C ? 23.190 28.209 10.912 1.00 16.39 ? 28 LEU A CA 1
ATOM 223 C ? 23.477 26.954 11.722 1.00 16.86 ? 28 LEU A C 1
ATOM 224 O ? 23.954 27.038 12.852 1.00 15.09 ? 28 LEU A O 1
ATOM 225 C ? 21.739 28.679 11.111 1.00 15.94 ? 28 LEU A CB 1
ATOM 226 C ? 21.490 30.154 10.741 1.00 16.72 ? 28 LEU A CG 1
ATOM 227 C ? 20.008 30.496 10.780 1.00 14.38 ? 28 LEU A CD1 1
ATOM 228 C ? 22.302 31.074 11.665 1.00 12.81 ? 28 LEU A CD2 1
ATOM 229 N ? 23.228 25.791 11.121 1.00 16.05 ? 29 ARG A N 1
ATOM 230 C ? 23.498 24.524 11.798 1.00 18.43 ? 29 ARG A CA 1
ATOM 231 C ? 24.980 24.377 12.076 1.00 19.22 ? 29 ARG A C 1
ATOM 232 O ? 25.383 23.987 13.171 1.00 17.97 ? 29 ARG A O 1
ATOM 233 C ? 23.030 23.334 10.969 1.00 18.63 ? 29 ARG A CB 1
ATOM 234 C ? 21.596 22.983 11.189 1.00 21.26 ? 29 ARG A CG 1
ATOM 235 C ? 21.339 21.572 10.739 1.00 24.71 ? 29 ARG A CD 1
ATOM 236 N ? 20.571 21.564 9.513 1.00 29.88 ? 29 ARG A NE 1
ATOM 237 C ? 21.019 21.147 8.340 1.00 29.19 ? 29 ARG A CZ 1
ATOM 238 N ? 22.248 20.682 8.205 1.00 30.52 ? 29 ARG A NH1 1
ATOM 239 N ? 20.232 21.233 7.295 1.00 31.61 ? 29 ARG A NH2 1
ATOM 240 N ? 25.790 24.709 11.078 1.00 19.76 ? 30 LYS A N 1
ATOM 241 C ? 27.235 24.619 11.198 1.00 21.96 ? 30 LYS A CA 1
ATOM 242 C ? 27.706 25.418 12.417 1.00 20.91 ? 30 LYS A C 1
ATOM 243 O ? 28.470 24.916 13.239 1.00 22.15 ? 30 LYS A O 1
ATOM 244 C ? 27.894 25.143 9.915 1.00 25.07 ? 30 LYS A CB 1
ATOM 245 C ? 29.404 25.031 9.905 1.00 30.48 ? 30 LYS A CG 1
ATOM 246 C ? 30.013 25.631 8.639 1.00 35.43 ? 30 LYS A CD 1
ATOM 247 C ? 31.533 25.759 8.778 1.00 37.96 ? 30 LYS A CE 1
ATOM 248 N ? 32.180 26.388 7.584 1.00 41.61 ? 30 LYS A NZ 1
ATOM 249 N ? 27.208 26.643 12.544 1.00 18.38 ? 31 ILE A N 1
ATOM 250 C ? 27.557 27.527 13.652 1.00 16.41 ? 31 ILE A CA 1
ATOM 251 C ? 27.105 26.932 14.989 1.00 15.39 ? 31 ILE A C 1
ATOM 252 O ? 27.888 26.855 15.930 1.00 14.90 ? 31 ILE A O 1
ATOM 253 C ? 26.881 28.920 13.471 1.00 16.63 ? 31 ILE A CB 1
ATOM 254 C ? 27.419 29.606 12.208 1.00 18.74 ? 31 ILE A CG1 1
ATOM 255 C ? 27.071 29.791 14.713 1.00 15.71 ? 31 ILE A CG2 1
ATOM 256 C ? 26.735 30.946 11.858 1.00 17.27 ? 31 ILE A CD1 1
ATOM 257 N ? 25.853 26.487 15.048 1.00 13.39 ? 32 ALA A N 1
ATOM 258 C ? 25.271 25.930 16.267 1.00 12.76 ? 32 ALA A CA 1
ATOM 259 C ? 25.994 24.685 16.775 1.00 12.11 ? 32 ALA A C 1
ATOM 260 O ? 26.325 24.598 17.946 1.00 10.54 ? 32 ALA A O 1
ATOM 261 C ? 23.790 25.638 16.040 1.00 12.45 ? 32 ALA A CB 1
ATOM 262 N ? 26.252 23.731 15.886 1.00 11.95 ? 33 VAL A N 1
ATOM 263 C ? 26.932 22.490 16.256 1.00 13.80 ? 33 VAL A CA 1
ATOM 264 C ? 28.328 22.701 16.855 1.00 14.00 ? 33 VAL A C 1
ATOM 265 O ? 28.693 22.048 17.832 1.00 14.07 ? 33 VAL A O 1
ATOM 266 C ? 27.016 21.504 15.044 1.00 13.56 ? 33 VAL A CB 1
ATOM 267 C ? 27.909 20.318 15.375 1.00 16.07 ? 33 VAL A CG1 1
ATOM 268 C ? 25.621 21.006 14.684 1.00 14.96 ? 33 VAL A CG2 1
ATOM 269 N ? 29.101 23.620 16.281 1.00 14.73 ? 34 ALA A N 1
ATOM 270 C ? 30.443 23.898 16.780 1.00 14.95 ? 34 ALA A CA 1
ATOM 271 C ? 30.381 24.505 18.178 1.00 15.59 ? 34 ALA A C 1
ATOM 272 O ? 31.120 24.085 19.065 1.00 16.65 ? 34 ALA A O 1
ATOM 273 C ? 31.191 24.844 15.833 1.00 16.10 ? 34 ALA A CB 1
ATOM 274 N ? 29.495 25.480 18.375 1.00 13.20 ? 35 ALA A N 1
ATOM 275 C ? 29.371 26.134 19.671 1.00 13.04 ? 35 ALA A CA 1
ATOM 276 C ? 28.807 25.200 20.749 1.00 12.91 ? 35 ALA A C 1
ATOM 277 O ? 29.245 25.239 21.895 1.00 12.32 ? 35 ALA A O 1
ATOM 278 C ? 28.517 27.387 19.552 1.00 12.14 ? 35 ALA A CB 1
ATOM 279 N ? 27.878 24.332 20.362 1.00 11.40 ? 36 ALA A N 1
ATOM 280 C ? 27.253 23.416 21.312 1.00 12.63 ? 36 ALA A CA 1
ATOM 281 C ? 28.128 22.256 21.770 1.00 13.40 ? 36 ALA A C 1
ATOM 282 O ? 27.743 21.512 22.668 1.00 13.47 ? 36 ALA A O 1
ATOM 283 C ? 25.952 22.883 20.744 1.00 11.79 ? 36 ALA A CB 1
ATOM 284 N ? 29.286 22.080 21.148 1.00 13.86 ? 37 SER A N 1
ATOM 285 C ? 30.169 20.983 21.520 1.00 15.95 ? 37 SER A CA 1
ATOM 286 C ? 30.938 21.245 22.818 1.00 16.46 ? 37 SER A C 1
ATOM 287 O ? 31.488 20.320 23.406 1.00 18.23 ? 37 SER A O 1
ATOM 288 C ? 31.145 20.689 20.388 1.00 16.93 ? 37 SER A CB 1
ATOM 289 O ? 32.100 21.729 20.293 1.00 21.65 ? 37 SER A OG 1
ATOM 290 N ? 30.957 22.496 23.272 1.00 16.91 ? 38 LYS A N 1
ATOM 291 C ? 31.657 22.869 24.502 1.00 18.36 ? 38 LYS A CA 1
ATOM 292 C ? 30.817 23.809 25.382 1.00 15.90 ? 38 LYS A C 1
ATOM 293 O ? 31.175 24.975 25.591 1.00 16.72 ? 38 LYS A O 1
ATOM 294 C ? 33.004 23.539 24.156 1.00 23.99 ? 38 LYS A CB 1
ATOM 295 C ? 32.907 24.607 23.046 1.00 30.97 ? 38 LYS A CG 1
ATOM 296 C ? 34.250 25.320 22.792 1.00 36.44 ? 38 LYS A CD 1
ATOM 297 C ? 34.266 26.098 21.456 1.00 38.70 ? 38 LYS A CE 1
ATOM 298 N ? 33.193 27.131 21.321 1.00 39.37 ? 38 LYS A NZ 1
ATOM 299 N ? 29.669 23.321 25.906 1.00 13.53 ? 39 PRO A N 1
ATOM 300 C ? 28.851 24.201 26.747 1.00 11.87 ? 39 PRO A CA 1
ATOM 301 C ? 29.292 24.248 28.211 1.00 12.05 ? 39 PRO A C 1
ATOM 302 O ? 30.027 23.380 28.676 1.00 12.12 ? 39 PRO A O 1
ATOM 303 C ? 27.469 23.560 26.649 1.00 9.34 ? 39 PRO A CB 1
ATOM 304 C ? 27.779 22.131 26.593 1.00 10.32 ? 39 PRO A CG 1
ATOM 305 C ? 29.009 22.020 25.703 1.00 10.86 ? 39 PRO A CD 1
ATOM 306 N ? 28.921 25.316 28.898 1.00 11.52 ? 40 ALA A N 1
ATOM 307 C ? 29.192 25.423 30.329 1.00 11.84 ? 40 ALA A CA 1
ATOM 308 C ? 27.773 25.329 30.894 1.00 10.23 ? 40 ALA A C 1
ATOM 309 O ? 26.894 26.080 30.478 1.00 10.42 ? 40 ALA A O 1
ATOM 310 C ? 29.830 26.767 30.673 1.00 11.40 ? 40 ALA A CB 1
ATOM 311 N ? 27.518 24.345 31.750 1.00 10.73 ? 41 VAL A N 1
ATOM 312 C ? 26.185 24.169 32.333 1.00 9.92 ? 41 VAL A CA 1
ATOM 313 C ? 26.226 24.295 33.854 1.00 11.64 ? 41 VAL A C 1
ATOM 314 O ? 27.026 23.627 34.514 1.00 11.40 ? 41 VAL A O 1
ATOM 315 C ? 25.594 22.772 31.987 1.00 10.67 ? 41 VAL A CB 1
ATOM 316 C ? 24.204 22.596 32.612 1.00 11.34 ? 41 VAL A CG1 1
ATOM 317 C ? 25.507 22.583 30.475 1.00 11.31 ? 41 VAL A CG2 1
ATOM 318 N ? 25.364 25.147 34.399 1.00 10.94 ? 42 GLU A N 1
ATOM 319 C ? 25.271 25.327 35.845 1.00 12.40 ? 42 GLU A CA 1
ATOM 320 C ? 23.837 25.095 36.316 1.00 11.42 ? 42 GLU A C 1
ATOM 321 O ? 22.898 25.720 35.825 1.00 10.46 ? 42 GLU A O 1
ATOM 322 C ? 25.711 26.721 36.270 1.00 16.26 ? 42 GLU A CB 1
ATOM 323 C ? 25.495 26.947 37.768 1.00 23.78 ? 42 GLU A CG 1
ATOM 324 C ? 25.944 28.311 38.242 1.00 27.94 ? 42 GLU A CD 1
ATOM 325 O ? 25.308 29.329 37.872 1.00 29.92 ? 42 GLU A OE1 1
ATOM 326 O ? 26.935 28.351 39.002 1.00 32.64 ? 42 GLU A OE2 1
ATOM 327 N ? 23.673 24.176 37.261 1.00 10.55 ? 43 ILE A N 1
ATOM 328 C ? 22.362 23.864 37.794 1.00 10.69 ? 43 ILE A CA 1
ATOM 329 C ? 22.360 24.120 39.300 1.00 11.07 ? 43 ILE A C 1
ATOM 330 O ? 23.307 23.764 39.992 1.00 10.83 ? 43 ILE A O 1
ATOM 331 C ? 21.996 22.374 37.552 1.00 10.47 ? 43 ILE A CB 1
ATOM 332 C ? 21.974 22.072 36.056 1.00 10.46 ? 43 ILE A CG1 1
ATOM 333 C ? 20.636 22.031 38.186 1.00 10.34 ? 43 ILE A CG2 1
ATOM 334 C ? 21.607 20.639 35.726 1.00 9.00 ? 43 ILE A CD1 1
ATOM 335 N ? 21.315 24.784 39.778 1.00 12.26 ? 44 LYS A N 1
ATOM 336 C ? 21.127 25.051 41.201 1.00 13.96 ? 44 LYS A CA 1
ATOM 337 C ? 19.729 24.528 41.516 1.00 14.16 ? 44 LYS A C 1
ATOM 338 O ? 18.749 24.920 40.873 1.00 14.12 ? 44 LYS A O 1
ATOM 339 C ? 21.220 26.545 41.503 1.00 16.58 ? 44 LYS A CB 1
ATOM 340 C ? 22.580 27.150 41.170 1.00 22.90 ? 44 LYS A CG 1
ATOM 341 C ? 22.571 28.654 41.385 1.00 29.01 ? 44 LYS A CD 1
ATOM 342 C ? 23.890 29.293 40.982 1.00 31.56 ? 44 LYS A CE 1
ATOM 343 N ? 23.818 30.781 41.111 1.00 34.70 ? 44 LYS A NZ 1
ATOM 344 N ? 19.649 23.594 42.460 1.00 15.66 ? 45 GLN A N 1
ATOM 345 C ? 18.377 22.993 42.852 1.00 16.03 ? 45 GLN A CA 1
ATOM 346 C ? 18.098 23.182 44.342 1.00 17.60 ? 45 GLN A C 1
ATOM 347 O ? 18.989 23.024 45.164 1.00 17.17 ? 45 GLN A O 1
ATOM 348 C ? 18.397 21.498 42.544 1.00 15.51 ? 45 GLN A CB 1
ATOM 349 C ? 17.168 20.744 43.015 1.00 13.62 ? 45 GLN A CG 1
ATOM 350 C ? 17.312 19.256 42.838 1.00 15.68 ? 45 GLN A CD 1
ATOM 351 O ? 18.348 18.769 42.397 1.00 18.84 ? 45 GLN A OE1 1
ATOM 352 N ? 16.276 18.521 43.177 1.00 16.73 ? 45 GLN A NE2 1
ATOM 353 N ? 16.868 23.551 44.670 1.00 18.48 ? 46 GLU A N 1
ATOM 354 C ? 16.441 23.718 46.062 1.00 21.26 ? 46 GLU A CA 1
ATOM 355 C ? 15.108 23.004 46.105 1.00 19.06 ? 46 GLU A C 1
ATOM 356 O ? 14.080 23.589 45.784 1.00 20.08 ? 46 GLU A O 1
ATOM 357 C ? 16.239 25.194 46.408 1.00 26.45 ? 46 GLU A CB 1
ATOM 358 C ? 17.284 25.787 47.361 1.00 37.46 ? 46 GLU A CG 1
ATOM 359 C ? 17.093 25.374 48.832 1.00 42.24 ? 46 GLU A CD 1
ATOM 360 O ? 16.192 25.944 49.501 1.00 44.05 ? 46 GLU A OE1 1
ATOM 361 O ? 17.867 24.507 49.320 1.00 44.14 ? 46 GLU A OE2 1
ATOM 362 N ? 15.131 21.720 46.429 1.00 18.35 ? 47 GLY A N 1
ATOM 363 C ? 13.893 20.970 46.463 1.00 18.96 ? 47 GLY A CA 1
ATOM 364 C ? 13.382 20.755 45.053 1.00 18.27 ? 47 GLY A C 1
ATOM 365 O ? 14.067 20.157 44.238 1.00 18.05 ? 47 GLY A O 1
ATOM 366 N ? 12.194 21.262 44.755 1.00 16.66 ? 48 ASP A N 1
ATOM 367 C ? 11.617 21.107 43.420 1.00 16.86 ? 48 ASP A CA 1
ATOM 368 C ? 11.771 22.378 42.566 1.00 15.92 ? 48 ASP A C 1
ATOM 369 O ? 11.139 22.511 41.504 1.00 14.50 ? 48 ASP A O 1
ATOM 370 C ? 10.136 20.694 43.513 1.00 19.00 ? 48 ASP A CB 1
ATOM 371 C ? 9.943 19.221 43.897 1.00 21.49 ? 48 ASP A CG 1
ATOM 372 O ? 10.901 18.406 43.840 1.00 23.51 ? 48 ASP A OD1 1
ATOM 373 O ? 8.802 18.868 44.243 1.00 25.04 ? 48 ASP A OD2 1
ATOM 374 N ? 12.610 23.299 43.042 1.00 13.75 ? 49 THR A N 1
ATOM 375 C ? 12.870 24.551 42.348 1.00 13.82 ? 49 THR A CA 1
ATOM 376 C ? 14.231 24.460 41.678 1.00 13.22 ? 49 THR A C 1
ATOM 377 O ? 15.235 24.152 42.322 1.00 12.56 ? 49 THR A O 1
ATOM 378 C ? 12.847 25.741 43.316 1.00 16.10 ? 49 THR A CB 1
ATOM 379 O ? 11.556 25.815 43.941 1.00 17.94 ? 49 THR A OG1 1
ATOM 380 C ? 13.100 27.037 42.571 1.00 16.15 ? 49 THR A CG2 1
ATOM 381 N ? 14.266 24.794 40.392 1.00 12.20 ? 50 PHE A N 1
ATOM 382 C ? 15.485 24.704 39.602 1.00 10.82 ? 50 PHE A CA 1
ATOM 383 C ? 15.842 25.979 38.855 1.00 10.40 ? 50 PHE A C 1
ATOM 384 O ? 14.968 26.758 38.460 1.00 9.90 ? 50 PHE A O 1
ATOM 385 C ? 15.338 23.591 38.547 1.00 10.78 ? 50 PHE A CB 1
ATOM 386 C ? 15.316 22.192 39.107 1.00 13.13 ? 50 PHE A CG 1
ATOM 387 C ? 14.146 21.653 39.634 1.00 11.97 ? 50 PHE A CD1 1
ATOM 388 C ? 16.464 21.401 39.079 1.00 14.34 ? 50 PHE A CD2 1
ATOM 389 C ? 14.113 20.367 40.120 1.00 12.69 ? 50 PHE A CE1 1
ATOM 390 C ? 16.439 20.098 39.569 1.00 14.64 ? 50 PHE A CE2 1
ATOM 391 C ? 15.258 19.582 40.092 1.00 13.15 ? 50 PHE A CZ 1
ATOM 392 N ? 17.147 26.165 38.678 1.00 10.37 ? 51 TYR A N 1
ATOM 393 C ? 17.709 27.258 37.910 1.00 10.95 ? 51 TYR A CA 1
ATOM 394 C ? 18.714 26.513 37.039 1.00 9.84 ? 51 TYR A C 1
ATOM 395 O ? 19.540 25.761 37.547 1.00 9.78 ? 51 TYR A O 1
ATOM 396 C ? 18.436 28.284 38.790 1.00 12.57 ? 51 TYR A CB 1
ATOM 397 C ? 19.396 29.178 38.014 1.00 12.91 ? 51 TYR A CG 1
ATOM 398 C ? 18.939 30.302 37.327 1.00 15.83 ? 51 TYR A CD1 1
ATOM 399 C ? 20.762 28.896 37.974 1.00 14.05 ? 51 TYR A CD2 1
ATOM 400 C ? 19.822 31.126 36.621 1.00 16.52 ? 51 TYR A CE1 1
ATOM 401 C ? 21.655 29.705 37.275 1.00 14.62 ? 51 TYR A CE2 1
ATOM 402 C ? 21.179 30.818 36.604 1.00 16.59 ? 51 TYR A CZ 1
ATOM 403 O ? 22.060 31.633 35.932 1.00 17.52 ? 51 TYR A OH 1
ATOM 404 N ? 18.610 26.676 35.726 1.00 10.57 ? 52 ILE A N 1
ATOM 405 C ? 19.520 26.004 34.801 1.00 9.09 ? 52 ILE A CA 1
ATOM 406 C ? 20.066 27.020 33.801 1.00 8.55 ? 52 ILE A C 1
ATOM 407 O ? 19.296 27.652 33.086 1.00 10.49 ? 52 ILE A O 1
ATOM 408 C ? 18.807 24.859 34.026 1.00 8.96 ? 52 ILE A CB 1
ATOM 409 C ? 18.242 23.814 35.013 1.00 9.15 ? 52 ILE A CG1 1
ATOM 410 C ? 19.792 24.189 33.070 1.00 10.39 ? 52 ILE A CG2 1
ATOM 411 C ? 17.585 22.616 34.366 1.00 8.10 ? 52 ILE A CD1 1
ATOM 412 N ? 21.388 27.197 33.791 1.00 8.61 ? 53 LYS A N 1
ATOM 413 C ? 22.049 28.115 32.868 1.00 9.66 ? 53 LYS A CA 1
ATOM 414 C ? 22.939 27.319 31.924 1.00 8.71 ? 53 LYS A C 1
ATOM 415 O ? 23.815 26.583 32.362 1.00 7.58 ? 53 LYS A O 1
ATOM 416 C ? 22.909 29.120 33.611 1.00 10.60 ? 53 LYS A CB 1
ATOM 417 C ? 23.580 30.135 32.688 1.00 14.21 ? 53 LYS A CG 1
ATOM 418 C ? 24.496 31.006 33.505 1.00 20.27 ? 53 LYS A CD 1
ATOM 419 C ? 24.831 32.319 32.828 1.00 26.91 ? 53 LYS A CE 1
ATOM 420 N ? 25.878 33.009 33.659 1.00 29.12 ? 53 LYS A NZ 1
ATOM 421 N ? 22.686 27.445 30.625 1.00 8.49 ? 54 THR A N 1
ATOM 422 C ? 23.478 26.747 29.628 1.00 7.98 ? 54 THR A CA 1
ATOM 423 C ? 24.118 27.820 28.764 1.00 8.23 ? 54 THR A C 1
ATOM 424 O ? 23.433 28.584 28.087 1.00 8.40 ? 54 THR A O 1
ATOM 425 C ? 22.621 25.817 28.789 1.00 8.33 ? 54 THR A CB 1
ATOM 426 O ? 21.896 24.946 29.660 1.00 9.95 ? 54 THR A OG1 1
ATOM 427 C ? 23.505 24.976 27.873 1.00 4.95 ? 54 THR A CG2 1
ATOM 428 N ? 25.444 27.840 28.758 1.00 8.75 ? 55 SER A N 1
ATOM 429 C ? 26.171 28.865 28.047 1.00 10.50 ? 55 SER A CA 1
ATOM 430 C ? 27.116 28.382 26.950 1.00 9.24 ? 55 SER A C 1
ATOM 431 O ? 27.802 27.370 27.101 1.00 8.98 ? 55 SER A O 1
ATOM 432 C ? 26.934 29.694 29.082 1.00 13.09 ? 55 SER A CB 1
ATOM 433 O ? 27.781 30.646 28.473 1.00 23.11 ? 55 SER A OG 1
ATOM 434 N ? 27.091 29.094 25.825 1.00 8.86 ? 56 THR A N 1
ATOM 435 C ? 27.978 28.831 24.684 1.00 8.05 ? 56 THR A CA 1
ATOM 436 C ? 28.393 30.215 24.138 1.00 8.09 ? 56 THR A C 1
ATOM 437 O ? 27.834 31.237 24.525 1.00 7.17 ? 56 THR A O 1
ATOM 438 C ? 27.296 28.024 23.534 1.00 6.70 ? 56 THR A CB 1
ATOM 439 O ? 26.294 28.829 22.909 1.00 9.76 ? 56 THR A OG1 1
ATOM 440 C ? 26.653 26.751 24.049 1.00 7.76 ? 56 THR A CG2 1
ATOM 441 N ? 29.381 30.242 23.249 1.00 9.17 ? 57 THR A N 1
ATOM 442 C ? 29.871 31.485 22.644 1.00 8.49 ? 57 THR A CA 1
ATOM 443 C ? 28.820 32.222 21.802 1.00 7.50 ? 57 THR A C 1
ATOM 444 O ? 28.952 33.412 21.565 1.00 9.40 ? 57 THR A O 1
ATOM 445 C ? 31.091 31.205 21.716 1.00 9.12 ? 57 THR A CB 1
ATOM 446 O ? 30.758 30.171 20.786 1.00 9.41 ? 57 THR A OG1 1
ATOM 447 C ? 32.297 30.775 22.516 1.00 11.48 ? 57 THR A CG2 1
ATOM 448 N ? 27.786 31.510 21.356 1.00 8.04 ? 58 VAL A N 1
ATOM 449 C ? 26.733 32.090 20.500 1.00 9.09 ? 58 VAL A CA 1
ATOM 450 C ? 25.328 32.224 21.102 1.00 8.67 ? 58 VAL A C 1
ATOM 451 O ? 24.466 32.892 20.531 1.00 6.97 ? 58 VAL A O 1
ATOM 452 C ? 26.602 31.287 19.155 1.00 9.96 ? 58 VAL A CB 1
ATOM 453 C ? 27.976 31.161 18.454 1.00 11.08 ? 58 VAL A CG1 1
ATOM 454 C ? 26.010 29.890 19.404 1.00 9.41 ? 58 VAL A CG2 1
ATOM 455 N ? 25.100 31.620 22.266 1.00 8.88 ? 59 ARG A N 1
ATOM 456 C ? 23.783 31.655 22.882 1.00 9.95 ? 59 ARG A CA 1
ATOM 457 C ? 23.843 31.140 24.303 1.00 10.14 ? 59 ARG A C 1
ATOM 458 O ? 24.440 30.108 24.556 1.00 10.10 ? 59 ARG A O 1
ATOM 459 C ? 22.837 30.751 22.074 1.00 13.11 ? 59 ARG A CB 1
ATOM 460 C ? 21.417 30.569 22.623 1.00 16.80 ? 59 ARG A CG 1
ATOM 461 C ? 20.521 29.961 21.535 1.00 18.74 ? 59 ARG A CD 1
ATOM 462 N ? 19.250 29.440 22.032 1.00 20.63 ? 59 ARG A NE 1
ATOM 463 C ? 18.147 30.165 22.193 1.00 22.94 ? 59 ARG A CZ 1
ATOM 464 N ? 18.138 31.462 21.894 1.00 22.55 ? 59 ARG A NH1 1
ATOM 465 N ? 17.051 29.594 22.686 1.00 23.68 ? 59 ARG A NH2 1
ATOM 466 N ? 23.183 31.849 25.211 1.00 11.23 ? 60 THR A N 1
ATOM 467 C ? 23.120 31.458 26.611 1.00 11.84 ? 60 THR A CA 1
ATOM 468 C ? 21.650 31.500 27.005 1.00 11.73 ? 60 THR A C 1
ATOM 469 O ? 20.934 32.423 26.620 1.00 13.69 ? 60 THR A O 1
ATOM 470 C ? 23.916 32.451 27.519 1.00 10.13 ? 60 THR A CB 1
ATOM 471 O ? 25.320 32.302 27.276 1.00 10.55 ? 60 THR A OG1 1
ATOM 472 C ? 23.632 32.181 29.003 1.00 11.01 ? 60 THR A CG2 1
ATOM 473 N ? 21.183 30.470 27.706 1.00 11.78 ? 61 THR A N 1
ATOM 474 C ? 19.797 30.413 28.175 1.00 11.54 ? 61 THR A CA 1
ATOM 475 C ? 19.831 30.214 29.686 1.00 10.88 ? 61 THR A C 1
ATOM 476 O ? 20.734 29.570 30.205 1.00 9.63 ? 61 THR A O 1
ATOM 477 C ? 18.965 29.229 27.539 1.00 12.65 ? 61 THR A CB 1
ATOM 478 O ? 19.563 27.976 27.874 1.00 14.13 ? 61 THR A OG1 1
ATOM 479 C ? 18.889 29.336 26.012 1.00 14.15 ? 61 THR A CG2 1
ATOM 480 N ? 18.878 30.828 30.382 1.00 12.14 ? 62 GLU A N 1
ATOM 481 C ? 18.749 30.698 31.833 1.00 12.88 ? 62 GLU A CA 1
ATOM 482 C ? 17.283 30.444 32.100 1.00 12.21 ? 62 GLU A C 1
ATOM 483 O ? 16.450 31.270 31.745 1.00 13.95 ? 62 GLU A O 1
ATOM 484 C ? 19.151 31.990 32.538 1.00 16.15 ? 62 GLU A CB 1
ATOM 485 C ? 20.585 32.344 32.326 1.00 23.65 ? 62 GLU A CG 1
ATOM 486 C ? 20.961 33.649 32.979 1.00 29.90 ? 62 GLU A CD 1
ATOM 487 O ? 20.969 33.703 34.229 1.00 31.84 ? 62 GLU A OE1 1
ATOM 488 O ? 21.258 34.616 32.236 1.00 33.89 ? 62 GLU A OE2 1
ATOM 489 N ? 16.943 29.292 32.657 1.00 10.43 ? 63 ILE A N 1
ATOM 490 C ? 15.548 29.021 32.946 1.00 11.02 ? 63 ILE A CA 1
ATOM 491 C ? 15.352 28.816 34.446 1.00 11.60 ? 63 ILE A C 1
ATOM 492 O ? 16.286 28.434 35.144 1.00 9.20 ? 63 ILE A O 1
ATOM 493 C ? 14.976 27.816 32.125 1.00 11.28 ? 63 ILE A CB 1
ATOM 494 C ? 15.717 26.519 32.431 1.00 10.60 ? 63 ILE A CG1 1
ATOM 495 C ? 15.020 28.129 30.638 1.00 11.62 ? 63 ILE A CG2 1
ATOM 496 C ? 15.126 25.293 31.720 1.00 13.40 ? 63 ILE A CD1 1
ATOM 497 N ? 14.184 29.219 34.933 1.00 12.13 ? 64 ASN A N 1
ATOM 498 C ? 13.824 29.083 36.343 1.00 14.79 ? 64 ASN A CA 1
ATOM 499 C ? 12.451 28.441 36.375 1.00 13.29 ? 64 ASN A C 1
ATOM 500 O ? 11.490 28.976 35.802 1.00 13.29 ? 64 ASN A O 1
ATOM 501 C ? 13.732 30.450 37.054 1.00 16.87 ? 64 ASN A CB 1
ATOM 502 C ? 15.079 31.089 37.279 1.00 20.91 ? 64 ASN A CG 1
ATOM 503 O ? 15.775 30.764 38.238 1.00 22.91 ? 64 ASN A OD1 1
ATOM 504 N ? 15.459 32.007 36.393 1.00 22.20 ? 64 ASN A ND2 1
ATOM 505 N ? 12.347 27.301 37.044 1.00 12.90 ? 65 PHE A N 1
ATOM 506 C ? 11.058 26.641 37.132 1.00 12.63 ? 65 PHE A CA 1
ATOM 507 C ? 10.858 25.841 38.410 1.00 13.07 ? 65 PHE A C 1
ATOM 508 O ? 11.811 25.531 39.121 1.00 12.50 ? 65 PHE A O 1
ATOM 509 C ? 10.829 25.731 35.922 1.00 11.31 ? 65 PHE A CB 1
ATOM 510 C ? 11.794 24.586 35.825 1.00 12.32 ? 65 PHE A CG 1
ATOM 511 C ? 11.549 23.386 36.494 1.00 10.31 ? 65 PHE A CD1 1
ATOM 512 C ? 12.947 24.706 35.070 1.00 11.23 ? 65 PHE A CD2 1
ATOM 513 C ? 12.441 22.329 36.413 1.00 11.00 ? 65 PHE A CE1 1
ATOM 514 C ? 13.847 23.645 34.984 1.00 11.69 ? 65 PHE A CE2 1
ATOM 515 C ? 13.593 22.461 35.655 1.00 12.20 ? 65 PHE A CZ 1
ATOM 516 N ? 9.599 25.560 38.713 1.00 13.15 ? 66 LYS A N 1
ATOM 517 C ? 9.251 24.735 39.849 1.00 13.41 ? 66 LYS A CA 1
ATOM 518 C ? 8.555 23.552 39.178 1.00 12.17 ? 66 LYS A C 1
ATOM 519 O ? 7.763 23.747 38.251 1.00 12.93 ? 66 LYS A O 1
ATOM 520 C ? 8.313 25.498 40.800 1.00 16.68 ? 66 LYS A CB 1
ATOM 521 C ? 7.722 24.639 41.907 1.00 24.60 ? 66 LYS A CG 1
ATOM 522 C ? 7.391 25.453 43.165 1.00 28.53 ? 66 LYS A CD 1
ATOM 523 C ? 6.664 24.585 44.213 1.00 32.17 ? 66 LYS A CE 1
ATOM 524 N ? 7.393 23.332 44.604 1.00 32.54 ? 66 LYS A NZ 1
ATOM 525 N ? 8.918 22.329 39.562 1.00 11.82 ? 67 VAL A N 1
ATOM 526 C ? 8.295 21.141 38.975 1.00 10.93 ? 67 VAL A CA 1
ATOM 527 C ? 6.783 21.174 39.226 1.00 11.97 ? 67 VAL A C 1
ATOM 528 O ? 6.343 21.480 40.342 1.00 13.54 ? 67 VAL A O 1
ATOM 529 C ? 8.908 19.827 39.541 1.00 10.09 ? 67 VAL A CB 1
ATOM 530 C ? 8.271 18.617 38.883 1.00 10.96 ? 67 VAL A CG1 1
ATOM 531 C ? 10.410 19.808 39.320 1.00 10.21 ? 67 VAL A CG2 1
ATOM 532 N ? 6.006 20.965 38.160 1.00 9.80 ? 68 GLY A N 1
ATOM 533 C ? 4.557 20.962 38.265 1.00 9.33 ? 68 GLY A CA 1
ATOM 534 C ? 3.887 22.298 38.031 1.00 10.60 ? 68 GLY A C 1
ATOM 535 O ? 2.653 22.389 38.039 1.00 11.93 ? 68 GLY A O 1
ATOM 536 N ? 4.688 23.337 37.809 1.00 11.12 ? 69 GLU A N 1
ATOM 537 C ? 4.165 24.682 37.553 1.00 12.64 ? 69 GLU A CA 1
ATOM 538 C ? 4.604 25.185 36.184 1.00 13.09 ? 69 GLU A C 1
ATOM 539 O ? 5.774 25.107 35.820 1.00 12.17 ? 69 GLU A O 1
ATOM 540 C ? 4.578 25.642 38.668 1.00 12.20 ? 69 GLU A CB 1
ATOM 541 C ? 3.857 25.282 39.964 1.00 17.44 ? 69 GLU A CG 1
ATOM 542 C ? 4.116 26.211 41.138 1.00 21.02 ? 69 GLU A CD 1
ATOM 543 O ? 4.496 27.384 40.945 1.00 21.43 ? 69 GLU A OE1 1
ATOM 544 O ? 3.902 25.753 42.282 1.00 23.44 ? 69 GLU A OE2 1
ATOM 545 N ? 3.633 25.622 35.397 1.00 14.53 ? 70 GLU A N 1
ATOM 546 C ? 3.912 26.102 34.059 1.00 15.80 ? 70 GLU A CA 1
ATOM 547 C ? 4.816 27.329 34.007 1.00 13.72 ? 70 GLU A C 1
ATOM 548 O ? 4.761 28.208 34.863 1.00 13.66 ? 70 GLU A O 1
ATOM 549 C ? 2.606 26.359 33.320 1.00 19.99 ? 70 GLU A CB 1
ATOM 550 C ? 2.814 26.634 31.851 1.00 28.23 ? 70 GLU A CG 1
ATOM 551 C ? 1.518 26.678 31.097 1.00 32.73 ? 70 GLU A CD 1
ATOM 552 O ? 0.975 25.589 30.789 1.00 35.76 ? 70 GLU A OE1 1
ATOM 553 O ? 1.045 27.802 30.823 1.00 35.75 ? 70 GLU A OE2 1
ATOM 554 N ? 5.713 27.340 33.028 1.00 12.80 ? 71 PHE A N 1
ATOM 555 C ? 6.638 28.448 32.837 1.00 12.36 ? 71 PHE A CA 1
ATOM 556 C ? 6.856 28.678 31.350 1.00 12.97 ? 71 PHE A C 1
ATOM 557 O ? 6.382 27.917 30.516 1.00 12.54 ? 71 PHE A O 1
ATOM 558 C ? 7.975 28.243 33.589 1.00 10.02 ? 71 PHE A CB 1
ATOM 559 C ? 8.851 27.148 33.033 1.00 10.48 ? 71 PHE A CG 1
ATOM 560 C ? 8.549 25.815 33.256 1.00 9.95 ? 71 PHE A CD1 1
ATOM 561 C ? 10.006 27.459 32.331 1.00 9.29 ? 71 PHE A CD2 1
ATOM 562 C ? 9.380 24.811 32.793 1.00 9.74 ? 71 PHE A CE1 1
ATOM 563 C ? 10.832 26.464 31.868 1.00 9.51 ? 71 PHE A CE2 1
ATOM 564 C ? 10.518 25.136 32.102 1.00 8.47 ? 71 PHE A CZ 1
ATOM 565 N ? 7.581 29.733 31.028 1.00 15.04 ? 72 GLU A N 1
ATOM 566 C ? 7.826 30.063 29.644 1.00 17.19 ? 72 GLU A CA 1
ATOM 567 C ? 9.323 30.036 29.357 1.00 15.53 ? 72 GLU A C 1
ATOM 568 O ? 10.130 30.511 30.158 1.00 16.16 ? 72 GLU A O 1
ATOM 569 C ? 7.248 31.448 29.379 1.00 22.03 ? 72 GLU A CB 1
ATOM 570 C ? 6.700 31.658 28.002 1.00 30.80 ? 72 GLU A CG 1
ATOM 571 C ? 6.157 33.060 27.827 1.00 34.75 ? 72 GLU A CD 1
ATOM 572 O ? 5.014 33.309 28.276 1.00 35.88 ? 72 GLU A OE1 1
ATOM 573 O ? 6.885 33.912 27.255 1.00 38.91 ? 72 GLU A OE2 1
ATOM 574 N ? 9.691 29.378 28.263 1.00 13.46 ? 73 GLU A N 1
ATOM 575 C ? 11.088 29.302 27.836 1.00 13.89 ? 73 GLU A CA 1
ATOM 576 C ? 11.083 29.318 26.301 1.00 13.70 ? 73 GLU A C 1
ATOM 577 O ? 10.159 29.859 25.690 1.00 13.63 ? 73 GLU A O 1
ATOM 578 C ? 11.780 28.032 28.379 1.00 12.63 ? 73 GLU A CB 1
ATOM 579 C ? 11.145 26.706 27.986 1.00 10.55 ? 73 GLU A CG 1
ATOM 580 C ? 11.997 25.499 28.366 1.00 8.94 ? 73 GLU A CD 1
ATOM 581 O ? 13.191 25.650 28.642 1.00 12.29 ? 73 GLU A OE1 1
ATOM 582 O ? 11.485 24.374 28.363 1.00 10.37 ? 73 GLU A OE2 1
ATOM 583 N ? 12.115 28.751 25.685 1.00 13.09 ? 74 GLN A N 1
ATOM 584 C ? 12.187 28.691 24.239 1.00 13.16 ? 74 GLN A CA 1
ATOM 585 C ? 12.618 27.315 23.806 1.00 12.86 ? 74 GLN A C 1
ATOM 586 O ? 13.290 26.596 24.552 1.00 13.17 ? 74 GLN A O 1
ATOM 587 C ? 13.218 29.685 23.706 1.00 15.91 ? 74 GLN A CB 1
ATOM 588 C ? 12.803 31.133 23.779 1.00 19.68 ? 74 GLN A CG 1
ATOM 589 C ? 13.827 32.066 23.159 1.00 21.00 ? 74 GLN A CD 1
ATOM 590 O ? 15.010 31.730 23.024 1.00 22.37 ? 74 GLN A OE1 1
ATOM 591 N ? 13.373 33.247 22.774 1.00 24.07 ? 74 GLN A NE2 1
ATOM 592 N ? 12.229 26.935 22.600 1.00 10.98 ? 75 THR A N 1
ATOM 593 C ? 12.664 25.656 22.056 1.00 11.83 ? 75 THR A CA 1
ATOM 594 C ? 14.162 25.828 21.729 1.00 11.24 ? 75 THR A C 1
ATOM 595 O ? 14.681 26.951 21.764 1.00 9.95 ? 75 THR A O 1
ATOM 596 C ? 11.895 25.325 20.757 1.00 11.93 ? 75 THR A CB 1
ATOM 597 O ? 12.123 26.366 19.795 1.00 13.31 ? 75 THR A OG1 1
ATOM 598 C ? 10.396 25.202 21.042 1.00 13.29 ? 75 THR A CG2 1
ATOM 599 N ? 14.841 24.731 21.377 1.00 13.77 ? 76 VAL A N 1
ATOM 600 C ? 16.278 24.762 21.049 1.00 14.39 ? 76 VAL A CA 1
ATOM 601 C ? 16.612 25.734 19.914 1.00 12.97 ? 76 VAL A C 1
ATOM 602 O ? 17.639 26.407 19.956 1.00 13.75 ? 76 VAL A O 1
ATOM 603 C ? 16.827 23.351 20.680 1.00 15.44 ? 76 VAL A CB 1
ATOM 604 C ? 18.332 23.314 20.844 1.00 17.74 ? 76 VAL A CG1 1
ATOM 605 C ? 16.218 22.293 21.548 1.00 19.99 ? 76 VAL A CG2 1
ATOM 606 N ? 15.730 25.824 18.921 1.00 13.67 ? 77 ASP A N 1
ATOM 607 C ? 15.933 26.727 17.789 1.00 14.47 ? 77 ASP A CA 1
ATOM 608 C ? 15.486 28.172 18.061 1.00 15.23 ? 77 ASP A C 1
ATOM 609 O ? 15.461 29.002 17.153 1.00 14.90 ? 77 ASP A O 1
ATOM 610 C ? 15.301 26.158 16.503 1.00 15.63 ? 77 ASP A CB 1
ATOM 611 C ? 13.790 26.007 16.585 1.00 15.92 ? 77 ASP A CG 1
ATOM 612 O ? 13.260 25.470 17.586 1.00 14.64 ? 77 ASP A OD1 1
ATOM 613 O ? 13.123 26.409 15.613 1.00 17.79 ? 77 ASP A OD2 1
ATOM 614 N ? 15.095 28.445 19.312 1.00 15.17 ? 78 GLY A N 1
ATOM 615 C ? 14.709 29.790 19.726 1.00 15.90 ? 78 GLY A CA 1
ATOM 616 C ? 13.268 30.281 19.701 1.00 16.89 ? 78 GLY A C 1
ATOM 617 O ? 13.038 31.489 19.790 1.00 19.37 ? 78 GLY A O 1
ATOM 618 N ? 12.292 29.389 19.620 1.00 16.76 ? 79 ARG A N 1
ATOM 619 C ? 10.896 29.822 19.587 1.00 18.08 ? 79 ARG A CA 1
ATOM 620 C ? 10.229 29.768 20.961 1.00 16.55 ? 79 ARG A C 1
ATOM 621 O ? 10.379 28.787 21.680 1.00 16.57 ? 79 ARG A O 1
ATOM 622 C ? 10.112 28.961 18.604 1.00 20.74 ? 79 ARG A CB 1
ATOM 623 C ? 10.667 28.997 17.194 1.00 25.89 ? 79 ARG A CG 1
ATOM 624 C ? 9.986 27.976 16.310 1.00 29.77 ? 79 ARG A CD 1
ATOM 625 N ? 10.144 26.626 16.842 1.00 34.52 ? 79 ARG A NE 1
ATOM 626 C ? 10.128 25.516 16.109 1.00 35.90 ? 79 ARG A CZ 1
ATOM 627 N ? 9.971 25.580 14.789 1.00 37.70 ? 79 ARG A NH1 1
ATOM 628 N ? 10.266 24.337 16.702 1.00 35.58 ? 79 ARG A NH2 1
ATOM 629 N ? 9.501 30.830 21.352 1.00 15.98 ? 80 PRO A N 1
ATOM 630 C ? 8.819 30.867 22.651 1.00 15.47 ? 80 PRO A CA 1
ATOM 631 C ? 7.825 29.725 22.833 1.00 14.23 ? 80 PRO A C 1
ATOM 632 O ? 7.058 29.393 21.926 1.00 14.56 ? 80 PRO A O 1
ATOM 633 C ? 8.100 32.220 22.628 1.00 15.48 ? 80 PRO A CB 1
ATOM 634 C ? 9.010 33.057 21.846 1.00 18.18 ? 80 PRO A CG 1
ATOM 635 C ? 9.418 32.145 20.696 1.00 17.08 ? 80 PRO A CD 1
ATOM 636 N ? 7.817 29.148 24.028 1.00 13.52 ? 81 CYS A N 1
ATOM 637 C ? 6.914 28.055 24.331 1.00 12.41 ? 81 CYS A CA 1
ATOM 638 C ? 6.548 28.054 25.811 1.00 12.52 ? 81 CYS A C 1
ATOM 639 O ? 7.202 28.718 26.624 1.00 11.74 ? 81 CYS A O 1
ATOM 640 C ? 7.563 26.705 23.950 1.00 11.59 ? 81 CYS A CB 1
ATOM 641 S ? 9.063 26.255 24.894 1.00 12.86 ? 81 CYS A SG 1
ATOM 642 N ? 5.448 27.379 26.121 1.00 13.86 ? 82 LYS A N 1
ATOM 643 C ? 4.988 27.197 27.492 1.00 14.38 ? 82 LYS A CA 1
ATOM 644 C ? 5.436 25.779 27.839 1.00 13.51 ? 82 LYS A C 1
ATOM 645 O ? 5.227 24.842 27.063 1.00 12.69 ? 82 LYS A O 1
ATOM 646 C ? 3.473 27.299 27.589 1.00 18.36 ? 82 LYS A CB 1
ATOM 647 C ? 2.940 28.716 27.584 1.00 26.02 ? 82 LYS A CG 1
ATOM 648 C ? 3.353 29.506 28.826 1.00 31.13 ? 82 LYS A CD 1
ATOM 649 C ? 2.686 30.894 28.832 1.00 35.39 ? 82 LYS A CE 1
ATOM 650 N ? 2.868 31.652 30.120 1.00 37.63 ? 82 LYS A NZ 1
ATOM 651 N ? 6.110 25.638 28.974 1.00 11.15 ? 83 SER A N 1
ATOM 652 C ? 6.624 24.352 29.397 1.00 10.10 ? 83 SER A CA 1
ATOM 653 C ? 6.083 23.931 30.752 1.00 11.16 ? 83 SER A C 1
ATOM 654 O ? 5.721 24.769 31.575 1.00 10.21 ? 83 SER A O 1
ATOM 655 C ? 8.149 24.418 29.446 1.00 10.30 ? 83 SER A CB 1
ATOM 656 O ? 8.686 24.518 28.132 1.00 11.50 ? 83 SER A OG 1
ATOM 657 N ? 6.028 22.620 30.954 1.00 11.17 ? 84 LEU A N 1
ATOM 658 C ? 5.557 22.016 32.192 1.00 11.84 ? 84 LEU A CA 1
ATOM 659 C ? 6.427 20.793 32.470 1.00 10.42 ? 84 LEU A C 1
ATOM 660 O ? 6.444 19.846 31.684 1.00 11.20 ? 84 LEU A O 1
ATOM 661 C ? 4.091 21.576 32.067 1.00 13.44 ? 84 LEU A CB 1
ATOM 662 C ? 3.552 20.784 33.270 1.00 15.74 ? 84 LEU A CG 1
ATOM 663 C ? 3.515 21.683 34.484 1.00 16.96 ? 84 LEU A CD1 1
ATOM 664 C ? 2.178 20.231 32.982 1.00 18.76 ? 84 LEU A CD2 1
ATOM 665 N ? 7.146 20.828 33.589 1.00 9.60 ? 85 VAL A N 1
ATOM 666 C ? 8.028 19.738 34.006 1.00 9.50 ? 85 VAL A CA 1
ATOM 667 C ? 7.344 18.878 35.082 1.00 9.74 ? 85 VAL A C 1
ATOM 668 O ? 6.680 19.404 35.985 1.00 9.28 ? 85 VAL A O 1
ATOM 669 C ? 9.384 20.291 34.598 1.00 8.89 ? 85 VAL A CB 1
ATOM 670 C ? 10.327 19.140 34.970 1.00 8.20 ? 85 VAL A CG1 1
ATOM 671 C ? 10.062 21.227 33.612 1.00 8.48 ? 85 VAL A CG2 1
ATOM 672 N ? 7.504 17.563 34.971 1.00 9.96 ? 86 LYS A N 1
ATOM 673 C ? 6.946 16.621 35.945 1.00 11.92 ? 86 LYS A CA 1
ATOM 674 C ? 8.003 15.558 36.247 1.00 11.88 ? 86 LYS A C 1
ATOM 675 O ? 8.917 15.340 35.453 1.00 11.00 ? 86 LYS A O 1
ATOM 676 C ? 5.700 15.911 35.385 1.00 12.40 ? 86 LYS A CB 1
ATOM 677 C ? 4.538 16.819 35.058 1.00 16.01 ? 86 LYS A CG 1
ATOM 678 C ? 3.333 16.017 34.559 1.00 21.36 ? 86 LYS A CD 1
ATOM 679 C ? 2.140 16.939 34.345 1.00 23.23 ? 86 LYS A CE 1
ATOM 680 N ? 0.919 16.212 33.929 1.00 28.41 ? 86 LYS A NZ 1
ATOM 681 N ? 7.868 14.889 37.386 1.00 10.75 ? 87 TRP A N 1
ATOM 682 C ? 8.775 13.811 37.738 1.00 9.53 ? 87 TRP A CA 1
ATOM 683 C ? 8.238 12.559 37.052 1.00 9.89 ? 87 TRP A C 1
ATOM 684 O ? 7.144 12.107 37.370 1.00 11.80 ? 87 TRP A O 1
ATOM 685 C ? 8.791 13.569 39.268 1.00 8.76 ? 87 TRP A CB 1
ATOM 686 C ? 9.494 14.641 40.062 1.00 8.86 ? 87 TRP A CG 1
ATOM 687 C ? 8.923 15.525 40.939 1.00 8.80 ? 87 TRP A CD1 1
ATOM 688 C ? 10.889 14.990 39.992 1.00 9.42 ? 87 TRP A CD2 1
ATOM 689 N ? 9.872 16.410 41.400 1.00 8.01 ? 87 TRP A NE1 1
ATOM 690 C ? 11.086 16.103 40.835 1.00 10.85 ? 87 TRP A CE2 1
ATOM 691 C ? 11.985 14.475 39.283 1.00 9.60 ? 87 TRP A CE3 1
ATOM 692 C ? 12.340 16.716 40.994 1.00 11.45 ? 87 TRP A CZ2 1
ATOM 693 C ? 13.230 15.084 39.438 1.00 10.72 ? 87 TRP A CZ3 1
ATOM 694 C ? 13.395 16.192 40.289 1.00 11.78 ? 87 TRP A CH2 1
ATOM 695 N ? 8.954 12.040 36.064 1.00 9.93 ? 88 GLU A N 1
ATOM 696 C ? 8.526 10.807 35.416 1.00 11.30 ? 88 GLU A CA 1
ATOM 697 C ? 8.826 9.726 36.448 1.00 11.75 ? 88 GLU A C 1
ATOM 698 O ? 8.068 8.784 36.623 1.00 12.78 ? 88 GLU A O 1
ATOM 699 C ? 9.337 10.541 34.156 1.00 13.50 ? 88 GLU A CB 1
ATOM 700 C ? 8.917 9.261 33.454 1.00 18.67 ? 88 GLU A CG 1
ATOM 701 C ? 9.756 8.958 32.226 1.00 23.49 ? 88 GLU A CD 1
ATOM 702 O ? 9.581 9.650 31.205 1.00 26.53 ? 88 GLU A OE1 1
ATOM 703 O ? 10.587 8.025 32.276 1.00 26.54 ? 88 GLU A OE2 1
ATOM 704 N ? 9.972 9.870 37.103 1.00 11.49 ? 89 SER A N 1
ATOM 705 C ? 10.402 8.954 38.158 1.00 11.10 ? 89 SER A CA 1
ATOM 706 C ? 11.206 9.776 39.163 1.00 11.14 ? 89 SER A C 1
ATOM 707 O ? 11.397 10.983 38.979 1.00 9.92 ? 89 SER A O 1
ATOM 708 C ? 11.221 7.778 37.604 1.00 12.43 ? 89 SER A CB 1
ATOM 709 O ? 12.396 8.215 36.947 1.00 14.39 ? 89 SER A OG 1
ATOM 710 N ? 11.674 9.130 40.227 1.00 10.17 ? 90 GLU A N 1
ATOM 711 C ? 12.433 9.826 41.254 1.00 10.83 ? 90 GLU A CA 1
ATOM 712 C ? 13.657 10.629 40.772 1.00 9.86 ? 90 GLU A C 1
ATOM 713 O ? 13.932 11.715 41.289 1.00 10.30 ? 90 GLU A O 1
ATOM 714 C ? 12.858 8.846 42.348 1.00 11.92 ? 90 GLU A CB 1
ATOM 715 C ? 13.536 9.572 43.487 1.00 16.53 ? 90 GLU A CG 1
ATOM 716 C ? 13.912 8.671 44.644 1.00 19.80 ? 90 GLU A CD 1
ATOM 717 O ? 14.122 7.464 44.426 1.00 21.18 ? 90 GLU A OE1 1
ATOM 718 O ? 14.012 9.187 45.774 1.00 22.91 ? 90 GLU A OE2 1
ATOM 719 N ? 14.376 10.102 39.783 1.00 8.79 ? 91 ASN A N 1
ATOM 720 C ? 15.578 10.767 39.274 1.00 10.50 ? 91 ASN A CA 1
ATOM 721 C ? 15.455 11.289 37.855 1.00 9.69 ? 91 ASN A C 1
ATOM 722 O ? 16.467 11.627 37.246 1.00 7.10 ? 91 ASN A O 1
ATOM 723 C ? 16.760 9.798 39.305 1.00 14.33 ? 91 ASN A CB 1
ATOM 724 C ? 17.064 9.307 40.693 1.00 17.71 ? 91 ASN A CG 1
ATOM 725 O ? 17.445 10.087 41.560 1.00 20.87 ? 91 ASN A OD1 1
ATOM 726 N ? 16.855 8.016 40.928 1.00 19.39 ? 91 ASN A ND2 1
ATOM 727 N ? 14.230 11.387 37.352 1.00 8.60 ? 92 LYS A N 1
ATOM 728 C ? 14.016 11.835 35.981 1.00 8.88 ? 92 LYS A CA 1
ATOM 729 C ? 12.861 12.812 35.807 1.00 8.61 ? 92 LYS A C 1
ATOM 730 O ? 11.721 12.511 36.168 1.00 8.95 ? 92 LYS A O 1
ATOM 731 C ? 13.781 10.626 35.078 1.00 9.10 ? 92 LYS A CB 1
ATOM 732 C ? 13.566 10.996 33.618 1.00 11.95 ? 92 LYS A CG 1
ATOM 733 C ? 13.467 9.762 32.759 1.00 14.04 ? 92 LYS A CD 1
ATOM 734 C ? 13.333 10.124 31.299 1.00 16.33 ? 92 LYS A CE 1
ATOM 735 N ? 13.129 8.884 30.506 1.00 17.37 ? 92 LYS A NZ 1
ATOM 736 N ? 13.172 13.988 35.268 1.00 7.58 ? 93 MET A N 1
ATOM 737 C ? 12.159 14.985 34.995 1.00 8.21 ? 93 MET A CA 1
ATOM 738 C ? 11.915 15.038 33.496 1.00 9.18 ? 93 MET A C 1
ATOM 739 O ? 12.833 14.838 32.690 1.00 7.74 ? 93 MET A O 1
ATOM 740 C ? 12.565 16.359 35.523 1.00 9.68 ? 93 MET A CB 1
ATOM 741 C ? 13.826 16.925 34.937 1.00 13.16 ? 93 MET A CG 1
ATOM 742 S ? 14.238 18.543 35.628 1.00 17.49 ? 93 MET A SD 1
ATOM 743 C ? 15.009 18.106 37.076 1.00 18.53 ? 93 MET A CE 1
ATOM 744 N ? 10.658 15.239 33.128 1.00 9.48 ? 94 VAL A N 1
ATOM 745 C ? 10.266 15.334 31.726 1.00 9.55 ? 94 VAL A CA 1
ATOM 746 C ? 9.516 16.639 31.528 1.00 10.10 ? 94 VAL A C 1
ATOM 747 O ? 8.683 17.024 32.364 1.00 9.47 ? 94 VAL A O 1
ATOM 748 C ? 9.371 14.164 31.315 1.00 11.05 ? 94 VAL A CB 1
ATOM 749 C ? 8.878 14.354 29.878 1.00 12.88 ? 94 VAL A CG1 1
ATOM 750 C ? 10.147 12.866 31.420 1.00 14.00 ? 94 VAL A CG2 1
ATOM 751 N ? 9.802 17.312 30.413 1.00 9.49 ? 95 CYS A N 1
ATOM 752 C ? 9.169 18.582 30.094 1.00 8.82 ? 95 CYS A CA 1
ATOM 753 C ? 8.431 18.559 28.758 1.00 11.70 ? 95 CYS A C 1
ATOM 754 O ? 9.014 18.215 27.723 1.00 12.29 ? 95 CYS A O 1
ATOM 755 C ? 10.229 19.679 30.059 1.00 8.79 ? 95 CYS A CB 1
ATOM 756 S ? 9.620 21.322 29.690 1.00 10.97 ? 95 CYS A SG 1
ATOM 757 N ? 7.149 18.902 28.791 1.00 10.87 ? 96 GLU A N 1
ATOM 758 C ? 6.342 18.962 27.587 1.00 14.78 ? 96 GLU A CA 1
ATOM 759 C ? 6.267 20.439 27.182 1.00 13.83 ? 96 GLU A C 1
ATOM 760 O ? 6.044 21.311 28.030 1.00 12.79 ? 96 GLU A O 1
ATOM 761 C ? 4.957 18.397 27.885 1.00 20.21 ? 96 GLU A CB 1
ATOM 762 C ? 3.981 18.432 26.726 1.00 32.46 ? 96 GLU A CG 1
ATOM 763 C ? 2.646 17.765 27.065 1.00 38.97 ? 96 GLU A CD 1
ATOM 764 O ? 2.053 18.108 28.128 1.00 42.61 ? 96 GLU A OE1 1
ATOM 765 O ? 2.201 16.892 26.271 1.00 42.17 ? 96 GLU A OE2 1
ATOM 766 N ? 6.513 20.725 25.903 1.00 13.39 ? 97 GLN A N 1
ATOM 767 C ? 6.489 22.100 25.402 1.00 13.55 ? 97 GLN A CA 1
ATOM 768 C ? 5.357 22.334 24.400 1.00 15.88 ? 97 GLN A C 1
ATOM 769 O ? 5.013 21.455 23.591 1.00 16.25 ? 97 GLN A O 1
ATOM 770 C ? 7.823 22.465 24.747 1.00 12.20 ? 97 GLN A CB 1
ATOM 771 C ? 9.033 22.324 25.650 1.00 12.55 ? 97 GLN A CG 1
ATOM 772 C ? 10.321 22.613 24.927 1.00 14.20 ? 97 GLN A CD 1
ATOM 773 O ? 10.478 22.288 23.749 1.00 12.94 ? 97 GLN A OE1 1
ATOM 774 N ? 11.260 23.235 25.627 1.00 14.75 ? 97 GLN A NE2 1
ATOM 775 N ? 4.801 23.541 24.450 1.00 17.30 ? 98 LYS A N 1
ATOM 776 C ? 3.696 23.952 23.582 1.00 19.78 ? 98 LYS A CA 1
ATOM 777 C ? 3.990 25.340 23.019 1.00 18.56 ? 98 LYS A C 1
ATOM 778 O ? 4.162 26.293 23.771 1.00 17.70 ? 98 LYS A O 1
ATOM 779 C ? 2.389 23.953 24.389 1.00 23.30 ? 98 LYS A CB 1
ATOM 780 C ? 1.294 24.857 23.867 1.00 30.94 ? 98 LYS A CG 1
ATOM 781 C ? 0.210 25.047 24.934 1.00 37.10 ? 98 LYS A CD 1
ATOM 782 C ? -0.849 26.072 24.520 1.00 39.73 ? 98 LYS A CE 1
ATOM 783 N ? -0.326 27.476 24.541 1.00 42.46 ? 98 LYS A NZ 1
ATOM 784 N ? 4.073 25.445 21.696 1.00 19.35 ? 99 LEU A N 1
ATOM 785 C ? 4.357 26.721 21.041 1.00 21.32 ? 99 LEU A CA 1
ATOM 786 C ? 3.307 27.770 21.351 1.00 22.86 ? 99 LEU A C 1
ATOM 787 O ? 2.108 27.496 21.261 1.00 23.41 ? 99 LEU A O 1
ATOM 788 C ? 4.466 26.542 19.526 1.00 22.09 ? 99 LEU A CB 1
ATOM 789 C ? 5.692 25.792 18.997 1.00 22.72 ? 99 LEU A CG 1
ATOM 790 C ? 5.585 25.639 17.490 1.00 23.04 ? 99 LEU A CD1 1
ATOM 791 C ? 6.951 26.548 19.372 1.00 23.61 ? 99 LEU A CD2 1
ATOM 792 N ? 3.767 28.962 21.722 1.00 24.11 ? 100 LEU A N 1
ATOM 793 C ? 2.879 30.070 22.051 1.00 27.59 ? 100 LEU A CA 1
ATOM 794 C ? 2.130 30.545 20.815 1.00 30.94 ? 100 LEU A C 1
ATOM 795 O ? 0.951 30.908 20.877 1.00 31.34 ? 100 LEU A O 1
ATOM 796 C ? 3.680 31.227 22.640 1.00 25.50 ? 100 LEU A CB 1
ATOM 797 C ? 4.254 30.947 24.020 1.00 24.80 ? 100 LEU A CG 1
ATOM 798 C ? 4.960 32.171 24.542 1.00 26.59 ? 100 LEU A CD1 1
ATOM 799 C ? 3.141 30.554 24.935 1.00 24.80 ? 100 LEU A CD2 1
ATOM 800 N ? 2.835 30.531 19.689 1.00 34.60 ? 101 LYS A N 1
ATOM 801 C ? 2.282 30.961 18.413 1.00 37.81 ? 101 LYS A CA 1
ATOM 802 C ? 2.847 30.088 17.292 1.00 37.39 ? 101 LYS A C 1
ATOM 803 O ? 4.019 29.687 17.319 1.00 37.22 ? 101 LYS A O 1
ATOM 804 C ? 2.653 32.429 18.147 1.00 40.57 ? 101 LYS A CB 1
ATOM 805 C ? 2.182 33.426 19.212 1.00 45.13 ? 101 LYS A CG 1
ATOM 806 C ? 2.955 34.741 19.125 1.00 48.57 ? 101 LYS A CD 1
ATOM 807 C ? 4.479 34.527 19.248 1.00 51.31 ? 101 LYS A CE 1
ATOM 808 N ? 4.917 33.952 20.559 1.00 51.14 ? 101 LYS A NZ 1
ATOM 809 N ? 1.997 29.786 16.318 1.00 37.21 ? 102 GLY A N 1
ATOM 810 C ? 2.423 28.993 15.184 1.00 36.82 ? 102 GLY A CA 1
ATOM 811 C ? 2.333 27.494 15.344 1.00 36.36 ? 102 GLY A C 1
ATOM 812 O ? 1.690 26.977 16.265 1.00 35.74 ? 102 GLY A O 1
ATOM 813 N ? 2.954 26.803 14.395 1.00 35.74 ? 103 GLU A N 1
ATOM 814 C ? 2.988 25.348 14.377 1.00 35.50 ? 103 GLU A CA 1
ATOM 815 C ? 4.418 24.880 14.140 1.00 31.92 ? 103 GLU A C 1
ATOM 816 O ? 5.281 25.654 13.723 1.00 31.61 ? 103 GLU A O 1
ATOM 817 C ? 2.077 24.784 13.274 1.00 39.37 ? 103 GLU A CB 1
ATOM 818 C ? 0.652 24.422 13.712 1.00 45.52 ? 103 GLU A CG 1
ATOM 819 C ? -0.383 25.503 13.395 1.00 50.23 ? 103 GLU A CD 1
ATOM 820 O ? -0.130 26.346 12.499 1.00 53.12 ? 103 GLU A OE1 1
ATOM 821 O ? -1.464 25.500 14.036 1.00 52.16 ? 103 GLU A OE2 1
ATOM 822 N ? 4.653 23.604 14.414 1.00 28.97 ? 104 GLY A N 1
ATOM 823 C ? 5.967 23.024 14.231 1.00 25.41 ? 104 GLY A CA 1
ATOM 824 C ? 6.012 21.648 14.863 1.00 22.09 ? 104 GLY A C 1
ATOM 825 O ? 4.987 21.160 15.347 1.00 21.89 ? 104 GLY A O 1
ATOM 826 N ? 7.176 20.976 14.832 1.00 19.50 ? 105 PRO A N 1
ATOM 827 C ? 7.338 19.640 15.418 1.00 17.92 ? 105 PRO A CA 1
ATOM 828 C ? 7.020 19.664 16.914 1.00 15.61 ? 105 PRO A C 1
ATOM 829 O ? 7.170 20.696 17.567 1.00 14.42 ? 105 PRO A O 1
ATOM 830 C ? 8.828 19.348 15.202 1.00 18.86 ? 105 PRO A CB 1
ATOM 831 C ? 9.188 20.164 14.005 1.00 18.76 ? 105 PRO A CG 1
ATOM 832 C ? 8.423 21.440 14.199 1.00 18.40 ? 105 PRO A CD 1
ATOM 833 N ? 6.552 18.541 17.444 1.00 16.02 ? 106 LYS A N 1
ATOM 834 C ? 6.255 18.453 18.868 1.00 16.93 ? 106 LYS A CA 1
ATOM 835 C ? 7.609 18.305 19.554 1.00 15.49 ? 106 LYS A C 1
ATOM 836 O ? 8.397 17.437 19.183 1.00 14.76 ? 106 LYS A O 1
ATOM 837 C ? 5.387 17.229 19.174 1.00 20.98 ? 106 LYS A CB 1
ATOM 838 C ? 5.015 17.097 20.662 1.00 27.98 ? 106 LYS A CG 1
ATOM 839 C ? 4.463 18.433 21.229 1.00 33.23 ? 106 LYS A CD 1
ATOM 840 C ? 4.250 18.417 22.764 1.00 35.21 ? 106 LYS A CE 1
ATOM 841 N ? 5.519 18.251 23.566 1.00 33.75 ? 106 LYS A NZ 1
ATOM 842 N ? 7.907 19.167 20.515 1.00 13.91 ? 107 THR A N 1
ATOM 843 C ? 9.203 19.086 21.190 1.00 12.14 ? 107 THR A CA 1
ATOM 844 C ? 9.083 18.819 22.681 1.00 11.66 ? 107 THR A C 1
ATOM 845 O ? 8.061 19.120 23.295 1.00 10.59 ? 107 THR A O 1
ATOM 846 C ? 10.012 20.382 21.016 1.00 12.37 ? 107 THR A CB 1
ATOM 847 O ? 9.263 21.480 21.547 1.00 12.36 ? 107 THR A OG1 1
ATOM 848 C ? 10.327 20.643 19.544 1.00 12.62 ? 107 THR A CG2 1
ATOM 849 N ? 10.140 18.249 23.250 1.00 10.16 ? 108 SER A N 1
ATOM 850 C ? 10.192 17.975 24.681 1.00 9.98 ? 108 SER A CA 1
ATOM 851 C ? 11.649 17.774 25.081 1.00 9.90 ? 108 SER A C 1
ATOM 852 O ? 12.549 17.774 24.227 1.00 8.48 ? 108 SER A O 1
ATOM 853 C ? 9.370 16.729 25.024 1.00 9.84 ? 108 SER A CB 1
ATOM 854 O ? 9.844 15.601 24.313 1.00 13.87 ? 108 SER A OG 1
ATOM 855 N ? 11.890 17.708 26.386 1.00 7.96 ? 109 TRP A N 1
ATOM 856 C ? 13.233 17.446 26.894 1.00 7.85 ? 109 TRP A CA 1
ATOM 857 C ? 13.109 16.693 28.209 1.00 7.56 ? 109 TRP A C 1
ATOM 858 O ? 12.053 16.728 28.837 1.00 8.14 ? 109 TRP A O 1
ATOM 859 C ? 14.094 18.722 27.051 1.00 8.25 ? 109 TRP A CB 1
ATOM 860 C ? 13.627 19.829 28.007 1.00 8.07 ? 109 TRP A CG 1
ATOM 861 C ? 13.120 21.046 27.648 1.00 9.28 ? 109 TRP A CD1 1
ATOM 862 C ? 13.745 19.865 29.450 1.00 9.31 ? 109 TRP A CD2 1
ATOM 863 N ? 12.929 21.836 28.760 1.00 9.69 ? 109 TRP A NE1 1
ATOM 864 C ? 13.306 21.136 29.878 1.00 9.04 ? 109 TRP A CE2 1
ATOM 865 C ? 14.186 18.939 30.416 1.00 9.92 ? 109 TRP A CE3 1
ATOM 866 C ? 13.286 21.515 31.228 1.00 9.72 ? 109 TRP A CZ2 1
ATOM 867 C ? 14.163 19.316 31.758 1.00 10.25 ? 109 TRP A CZ3 1
ATOM 868 C ? 13.717 20.593 32.149 1.00 10.11 ? 109 TRP A CH2 1
ATOM 869 N ? 14.136 15.924 28.549 1.00 7.39 ? 110 THR A N 1
ATOM 870 C ? 14.168 15.176 29.808 1.00 6.23 ? 110 THR A CA 1
ATOM 871 C ? 15.577 15.334 30.395 1.00 7.40 ? 110 THR A C 1
ATOM 872 O ? 16.558 15.563 29.652 1.00 6.43 ? 110 THR A O 1
ATOM 873 C ? 13.887 13.633 29.626 1.00 7.17 ? 110 THR A CB 1
ATOM 874 O ? 15.000 13.002 28.973 1.00 7.49 ? 110 THR A OG1 1
ATOM 875 C ? 12.616 13.377 28.803 1.00 6.64 ? 110 THR A CG2 1
ATOM 876 N ? 15.669 15.293 31.727 1.00 6.72 ? 111 ARG A N 1
ATOM 877 C ? 16.966 15.356 32.425 1.00 6.27 ? 111 ARG A CA 1
ATOM 878 C ? 16.924 14.287 33.483 1.00 7.89 ? 111 ARG A C 1
ATOM 879 O ? 15.928 14.156 34.193 1.00 8.35 ? 111 ARG A O 1
ATOM 880 C ? 17.240 16.722 33.068 1.00 6.20 ? 111 ARG A CB 1
ATOM 881 C ? 17.703 17.765 32.060 1.00 7.38 ? 111 ARG A CG 1
ATOM 882 C ? 18.100 19.072 32.727 1.00 8.70 ? 111 ARG A CD 1
ATOM 883 N ? 18.783 19.965 31.784 1.00 9.83 ? 111 ARG A NE 1
ATOM 884 C ? 18.158 20.804 30.963 1.00 10.23 ? 111 ARG A CZ 1
ATOM 885 N ? 16.840 20.869 30.966 1.00 10.89 ? 111 ARG A NH1 1
ATOM 886 N ? 18.847 21.590 30.144 1.00 11.56 ? 111 ARG A NH2 1
ATOM 887 N ? 17.957 13.464 33.534 1.00 7.64 ? 112 GLU A N 1
ATOM 888 C ? 17.977 12.402 34.527 1.00 10.31 ? 112 GLU A CA 1
ATOM 889 C ? 19.356 12.142 35.113 1.00 9.93 ? 112 GLU A C 1
ATOM 890 O ? 20.367 12.273 34.425 1.00 7.92 ? 112 GLU A O 1
ATOM 891 C ? 17.401 11.118 33.940 1.00 14.05 ? 112 GLU A CB 1
ATOM 892 C ? 18.213 10.489 32.836 1.00 20.37 ? 112 GLU A CG 1
ATOM 893 C ? 17.484 9.325 32.177 1.00 25.09 ? 112 GLU A CD 1
ATOM 894 O ? 17.223 8.308 32.883 1.00 22.36 ? 112 GLU A OE1 1
ATOM 895 O ? 17.175 9.443 30.955 1.00 25.10 ? 112 GLU A OE2 1
ATOM 896 N ? 19.387 11.816 36.401 1.00 8.96 ? 113 LEU A N 1
ATOM 897 C ? 20.634 11.503 37.091 1.00 12.04 ? 113 LEU A CA 1
ATOM 898 C ? 20.789 9.991 37.081 1.00 12.06 ? 113 LEU A C 1
ATOM 899 O ? 19.906 9.270 37.559 1.00 12.08 ? 113 LEU A O 1
ATOM 900 C ? 20.575 11.983 38.532 1.00 14.38 ? 113 LEU A CB 1
ATOM 901 C ? 20.768 13.465 38.799 1.00 17.46 ? 113 LEU A CG 1
ATOM 902 C ? 20.709 13.656 40.298 1.00 19.61 ? 113 LEU A CD1 1
ATOM 903 C ? 22.128 13.945 38.266 1.00 18.46 ? 113 LEU A CD2 1
ATOM 904 N ? 21.895 9.502 36.535 1.00 11.06 ? 114 THR A N 1
ATOM 905 C ? 22.110 8.062 36.452 1.00 11.74 ? 114 THR A CA 1
ATOM 906 C ? 22.816 7.522 37.686 1.00 11.41 ? 114 THR A C 1
ATOM 907 O ? 23.327 8.282 38.501 1.00 11.47 ? 114 THR A O 1
ATOM 908 C ? 22.894 7.700 35.188 1.00 12.89 ? 114 THR A CB 1
ATOM 909 O ? 24.109 8.451 35.164 1.00 15.50 ? 114 THR A OG1 1
ATOM 910 C ? 22.075 8.037 33.951 1.00 14.75 ? 114 THR A CG2 1
ATOM 911 N ? 22.834 6.202 37.808 1.00 13.23 ? 115 ASN A N 1
ATOM 912 C ? 23.441 5.538 38.951 1.00 16.19 ? 115 ASN A CA 1
ATOM 913 C ? 24.930 5.761 39.139 1.00 14.24 ? 115 ASN A C 1
ATOM 914 O ? 25.432 5.626 40.256 1.00 14.74 ? 115 ASN A O 1
ATOM 915 C ? 23.123 4.047 38.918 1.00 21.89 ? 115 ASN A CB 1
ATOM 916 C ? 21.703 3.754 39.357 1.00 29.77 ? 115 ASN A CG 1
ATOM 917 O ? 20.955 3.046 38.669 1.00 34.83 ? 115 ASN A OD1 1
ATOM 918 N ? 21.313 4.310 40.516 1.00 32.90 ? 115 ASN A ND2 1
ATOM 919 N ? 25.626 6.095 38.055 1.00 12.05 ? 116 ASP A N 1
ATOM 920 C ? 27.061 6.364 38.094 1.00 11.99 ? 116 ASP A CA 1
ATOM 921 C ? 27.424 7.821 38.397 1.00 11.45 ? 116 ASP A C 1
ATOM 922 O ? 28.592 8.184 38.393 1.00 12.23 ? 116 ASP A O 1
ATOM 923 C ? 27.764 5.875 36.806 1.00 13.89 ? 116 ASP A CB 1
ATOM 924 C ? 27.177 6.474 35.512 1.00 16.58 ? 116 ASP A CG 1
ATOM 925 O ? 26.263 7.303 35.569 1.00 19.66 ? 116 ASP A OD1 1
ATOM 926 O ? 27.651 6.113 34.422 1.00 20.14 ? 116 ASP A OD2 1
ATOM 927 N ? 26.420 8.647 38.675 1.00 10.58 ? 117 GLY A N 1
ATOM 928 C ? 26.669 10.042 38.997 1.00 9.83 ? 117 GLY A CA 1
ATOM 929 C ? 26.652 11.019 37.831 1.00 9.97 ? 117 GLY A C 1
ATOM 930 O ? 26.945 12.192 38.019 1.00 10.45 ? 117 GLY A O 1
ATOM 931 N ? 26.289 10.550 36.638 1.00 9.43 ? 118 GLU A N 1
ATOM 932 C ? 26.242 11.413 35.458 1.00 7.79 ? 118 GLU A CA 1
ATOM 933 C ? 24.834 11.955 35.213 1.00 7.60 ? 118 GLU A C 1
ATOM 934 O ? 23.872 11.565 35.885 1.00 8.05 ? 118 GLU A O 1
ATOM 935 C ? 26.776 10.653 34.241 1.00 8.86 ? 118 GLU A CB 1
ATOM 936 C ? 28.227 10.234 34.427 1.00 9.64 ? 118 GLU A CG 1
ATOM 937 C ? 28.770 9.370 33.310 1.00 13.39 ? 118 GLU A CD 1
ATOM 938 O ? 28.036 9.043 32.355 1.00 11.90 ? 118 GLU A OE1 1
ATOM 939 O ? 29.956 8.998 33.405 1.00 16.59 ? 118 GLU A OE2 1
ATOM 940 N ? 24.732 12.884 34.269 1.00 7.57 ? 119 LEU A N 1
ATOM 941 C ? 23.467 13.513 33.917 1.00 6.94 ? 119 LEU A CA 1
ATOM 942 C ? 23.189 13.277 32.431 1.00 8.29 ? 119 LEU A C 1
ATOM 943 O ? 24.070 13.506 31.593 1.00 8.23 ? 119 LEU A O 1
ATOM 944 C ? 23.556 15.023 34.184 1.00 7.83 ? 119 LEU A CB 1
ATOM 945 C ? 22.417 15.972 33.810 1.00 9.54 ? 119 LEU A CG 1
ATOM 946 C ? 21.213 15.661 34.618 1.00 11.05 ? 119 LEU A CD1 1
ATOM 947 C ? 22.822 17.421 34.066 1.00 12.54 ? 119 LEU A CD2 1
ATOM 948 N ? 22.010 12.743 32.119 1.00 6.17 ? 120 ILE A N 1
ATOM 949 C ? 21.638 12.529 30.730 1.00 6.22 ? 120 ILE A CA 1
ATOM 950 C ? 20.527 13.511 30.354 1.00 7.47 ? 120 ILE A C 1
ATOM 951 O ? 19.493 13.580 31.036 1.00 6.54 ? 120 ILE A O 1
ATOM 952 C ? 21.103 11.118 30.485 1.00 7.19 ? 120 ILE A CB 1
ATOM 953 C ? 22.171 10.070 30.801 1.00 8.26 ? 120 ILE A CG1 1
ATOM 954 C ? 20.556 11.003 29.047 1.00 6.54 ? 120 ILE A CG2 1
ATOM 955 C ? 21.668 8.658 30.600 1.00 9.35 ? 120 ILE A CD1 1
ATOM 956 N ? 20.771 14.301 29.306 1.00 6.41 ? 121 LEU A N 1
ATOM 957 C ? 19.783 15.236 28.779 1.00 6.25 ? 121 LEU A CA 1
ATOM 958 C ? 19.299 14.693 27.426 1.00 7.41 ? 121 LEU A C 1
ATOM 959 O ? 20.115 14.242 26.619 1.00 6.01 ? 121 LEU A O 1
ATOM 960 C ? 20.400 16.624 28.526 1.00 7.37 ? 121 LEU A CB 1
ATOM 961 C ? 19.607 17.580 27.597 1.00 7.96 ? 121 LEU A CG 1
ATOM 962 C ? 18.340 18.117 28.290 1.00 7.91 ? 121 LEU A CD1 1
ATOM 963 C ? 20.501 18.739 27.151 1.00 7.96 ? 121 LEU A CD2 1
ATOM 964 N ? 17.988 14.607 27.222 1.00 6.71 ? 122 THR A N 1
ATOM 965 C ? 17.514 14.205 25.898 1.00 7.80 ? 122 THR A CA 1
ATOM 966 C ? 16.633 15.334 25.402 1.00 8.58 ? 122 THR A C 1
ATOM 967 O ? 15.988 16.034 26.194 1.00 7.21 ? 122 THR A O 1
ATOM 968 C ? 16.754 12.843 25.832 1.00 7.51 ? 122 THR A CB 1
ATOM 969 O ? 15.422 12.992 26.313 1.00 9.27 ? 122 THR A OG1 1
ATOM 970 C ? 17.484 11.759 26.622 1.00 7.86 ? 122 THR A CG2 1
ATOM 971 N ? 16.732 15.613 24.110 1.00 7.87 ? 123 MET A N 1
ATOM 972 C ? 15.904 16.643 23.494 1.00 9.22 ? 123 MET A CA 1
ATOM 973 C ? 15.194 15.950 22.337 1.00 8.66 ? 123 MET A C 1
ATOM 974 O ? 15.828 15.189 21.601 1.00 8.09 ? 123 MET A O 1
ATOM 975 C ? 16.760 17.818 23.019 1.00 9.37 ? 123 MET A CB 1
ATOM 976 C ? 17.359 18.612 24.171 1.00 11.81 ? 123 MET A CG 1
ATOM 977 S ? 18.325 20.048 23.658 1.00 16.59 ? 123 MET A SD 1
ATOM 978 C ? 19.871 19.278 23.173 1.00 14.10 ? 123 MET A CE 1
ATOM 979 N ? 13.895 16.195 22.186 1.00 7.20 ? 124 THR A N 1
ATOM 980 C ? 13.133 15.534 21.134 1.00 9.54 ? 124 THR A CA 1
ATOM 981 C ? 12.407 16.513 20.222 1.00 10.12 ? 124 THR A C 1
ATOM 982 O ? 11.941 17.563 20.665 1.00 9.54 ? 124 THR A O 1
ATOM 983 C ? 12.073 14.552 21.756 1.00 10.74 ? 124 THR A CB 1
ATOM 984 O ? 12.740 13.544 22.535 1.00 11.99 ? 124 THR A OG1 1
ATOM 985 C ? 11.247 13.865 20.679 1.00 11.66 ? 124 THR A CG2 1
ATOM 986 N ? 12.346 16.167 18.935 1.00 11.06 ? 125 ALA A N 1
ATOM 987 C ? 11.634 16.962 17.923 1.00 11.63 ? 125 ALA A CA 1
ATOM 988 C ? 10.981 15.878 17.078 1.00 13.46 ? 125 ALA A C 1
ATOM 989 O ? 11.669 15.144 16.352 1.00 13.11 ? 125 ALA A O 1
ATOM 990 C ? 12.603 17.786 17.091 1.00 13.16 ? 125 ALA A CB 1
ATOM 991 N ? 9.664 15.754 17.216 1.00 14.63 ? 126 ASP A N 1
ATOM 992 C ? 8.901 14.721 16.536 1.00 17.86 ? 126 ASP A CA 1
ATOM 993 C ? 9.512 13.364 16.905 1.00 18.66 ? 126 ASP A C 1
ATOM 994 O ? 9.519 13.006 18.080 1.00 19.38 ? 126 ASP A O 1
ATOM 995 C ? 8.835 14.982 15.023 1.00 18.40 ? 126 ASP A CB 1
ATOM 996 C ? 7.786 16.032 14.660 1.00 22.34 ? 126 ASP A CG 1
ATOM 997 O ? 6.800 16.198 15.422 1.00 23.23 ? 126 ASP A OD1 1
ATOM 998 O ? 7.940 16.702 13.621 1.00 24.32 ? 126 ASP A OD2 1
ATOM 999 N ? 10.064 12.629 15.945 1.00 20.19 ? 127 ASP A N 1
ATOM 1000 C ? 10.656 11.333 16.271 1.00 21.56 ? 127 ASP A CA 1
ATOM 1001 C ? 12.175 11.279 16.416 1.00 18.85 ? 127 ASP A C 1
ATOM 1002 O ? 12.732 10.219 16.657 1.00 20.67 ? 127 ASP A O 1
ATOM 1003 C ? 10.178 10.263 15.303 1.00 26.47 ? 127 ASP A CB 1
ATOM 1004 C ? 9.043 9.450 15.880 1.00 33.21 ? 127 ASP A CG 1
ATOM 1005 O ? 7.892 9.959 15.934 1.00 36.08 ? 127 ASP A OD1 1
ATOM 1006 O ? 9.318 8.308 16.318 1.00 38.35 ? 127 ASP A OD2 1
ATOM 1007 N ? 12.836 12.418 16.281 1.00 15.22 ? 128 VAL A N 1
ATOM 1008 C ? 14.286 12.486 16.407 1.00 12.83 ? 128 VAL A CA 1
ATOM 1009 C ? 14.681 12.843 17.835 1.00 11.58 ? 128 VAL A C 1
ATOM 1010 O ? 14.176 13.811 18.408 1.00 9.74 ? 128 VAL A O 1
ATOM 1011 C ? 14.864 13.503 15.423 1.00 12.79 ? 128 VAL A CB 1
ATOM 1012 C ? 16.338 13.757 15.706 1.00 12.93 ? 128 VAL A CG1 1
ATOM 1013 C ? 14.677 12.968 14.005 1.00 14.30 ? 128 VAL A CG2 1
ATOM 1014 N ? 15.586 12.051 18.397 1.00 9.29 ? 129 VAL A N 1
ATOM 1015 C ? 16.054 12.257 19.761 1.00 7.95 ? 129 VAL A CA 1
ATOM 1016 C ? 17.558 12.546 19.842 1.00 7.49 ? 129 VAL A C 1
ATOM 1017 O ? 18.374 11.816 19.276 1.00 8.73 ? 129 VAL A O 1
ATOM 1018 C ? 15.764 11.007 20.617 1.00 9.43 ? 129 VAL A CB 1
ATOM 1019 C ? 16.153 11.253 22.076 1.00 9.09 ? 129 VAL A CG1 1
ATOM 1020 C ? 14.293 10.610 20.495 1.00 9.45 ? 129 VAL A CG2 1
ATOM 1021 N ? 17.912 13.630 20.534 1.00 7.54 ? 130 CYS A N 1
ATOM 1022 C ? 19.305 14.010 20.756 1.00 6.47 ? 130 CYS A CA 1
ATOM 1023 C ? 19.670 13.627 22.200 1.00 6.61 ? 130 CYS A C 1
ATOM 1024 O ? 18.955 13.992 23.135 1.00 7.53 ? 130 CYS A O 1
ATOM 1025 C ? 19.485 15.517 20.544 1.00 6.05 ? 130 CYS A CB 1
ATOM 1026 S ? 21.063 16.183 21.077 1.00 8.82 ? 130 CYS A SG 1
ATOM 1027 N ? 20.786 12.925 22.372 1.00 6.58 ? 131 THR A N 1
ATOM 1028 C ? 21.241 12.462 23.693 1.00 5.93 ? 131 THR A CA 1
ATOM 1029 C ? 22.569 13.102 24.054 1.00 6.18 ? 131 THR A C 1
ATOM 1030 O ? 23.528 13.003 23.294 1.00 5.77 ? 131 THR A O 1
ATOM 1031 C ? 21.419 10.914 23.699 1.00 6.63 ? 131 THR A CB 1
ATOM 1032 O ? 20.199 10.299 23.289 1.00 7.60 ? 131 THR A OG1 1
ATOM 1033 C ? 21.763 10.399 25.091 1.00 7.76 ? 131 THR A CG2 1
ATOM 1034 N ? 22.624 13.780 25.202 1.00 6.29 ? 132 ARG A N 1
ATOM 1035 C ? 23.853 14.429 25.660 1.00 7.67 ? 132 ARG A CA 1
ATOM 1036 C ? 24.108 13.960 27.093 1.00 7.19 ? 132 ARG A C 1
ATOM 1037 O ? 23.184 13.895 27.902 1.00 8.65 ? 132 ARG A O 1
ATOM 1038 C ? 23.719 15.957 25.621 1.00 9.67 ? 132 ARG A CB 1
ATOM 1039 C ? 22.945 16.470 24.429 1.00 15.02 ? 132 ARG A CG 1
ATOM 1040 C ? 23.781 17.260 23.476 1.00 16.80 ? 132 ARG A CD 1
ATOM 1041 N ? 24.140 18.580 23.984 1.00 12.48 ? 132 ARG A NE 1
ATOM 1042 C ? 25.030 19.377 23.395 1.00 12.93 ? 132 ARG A CZ 1
ATOM 1043 N ? 25.641 19.005 22.279 1.00 13.84 ? 132 ARG A NH1 1
ATOM 1044 N ? 25.398 20.506 23.973 1.00 11.57 ? 132 ARG A NH2 1
ATOM 1045 N ? 25.359 13.633 27.397 1.00 5.99 ? 133 VAL A N 1
ATOM 1046 C ? 25.739 13.124 28.719 1.00 5.92 ? 133 VAL A CA 1
ATOM 1047 C ? 26.773 14.055 29.345 1.00 5.85 ? 133 VAL A C 1
ATOM 1048 O ? 27.713 14.492 28.681 1.00 5.50 ? 133 VAL A O 1
ATOM 1049 C ? 26.333 11.698 28.608 1.00 6.37 ? 133 VAL A CB 1
ATOM 1050 C ? 26.609 11.120 29.988 1.00 7.95 ? 133 VAL A CG1 1
ATOM 1051 C ? 25.385 10.782 27.832 1.00 6.46 ? 133 VAL A CG2 1
ATOM 1052 N ? 26.619 14.337 30.635 1.00 5.35 ? 134 TYR A N 1
ATOM 1053 C ? 27.538 15.228 31.322 1.00 4.57 ? 134 TYR A CA 1
ATOM 1054 C ? 28.014 14.611 32.617 1.00 5.30 ? 134 TYR A C 1
ATOM 1055 O ? 27.371 13.712 33.165 1.00 3.92 ? 134 TYR A O 1
ATOM 1056 C ? 26.846 16.550 31.686 1.00 6.84 ? 134 TYR A CB 1
ATOM 1057 C ? 26.118 17.251 30.574 1.00 8.89 ? 134 TYR A CG 1
ATOM 1058 C ? 24.901 16.762 30.122 1.00 10.29 ? 134 TYR A CD1 1
ATOM 1059 C ? 26.628 18.406 29.992 1.00 10.49 ? 134 TYR A CD2 1
ATOM 1060 C ? 24.212 17.386 29.133 1.00 13.03 ? 134 TYR A CE1 1
ATOM 1061 C ? 25.930 19.051 28.982 1.00 12.15 ? 134 TYR A CE2 1
ATOM 1062 C ? 24.723 18.517 28.567 1.00 12.80 ? 134 TYR A CZ 1
ATOM 1063 O ? 23.991 19.082 27.567 1.00 18.07 ? 134 TYR A OH 1
ATOM 1064 N ? 29.113 15.158 33.119 1.00 6.63 ? 135 VAL A N 1
ATOM 1065 C ? 29.697 14.762 34.394 1.00 8.42 ? 135 VAL A CA 1
ATOM 1066 C ? 30.100 16.086 35.064 1.00 9.05 ? 135 VAL A C 1
ATOM 1067 O ? 30.340 17.086 34.385 1.00 9.02 ? 135 VAL A O 1
ATOM 1068 C ? 30.925 13.815 34.204 1.00 8.05 ? 135 VAL A CB 1
ATOM 1069 C ? 32.109 14.556 33.596 1.00 9.27 ? 135 VAL A CG1 1
ATOM 1070 C ? 31.304 13.151 35.533 1.00 10.37 ? 135 VAL A CG2 1
ATOM 1071 N ? 30.117 16.133 36.390 1.00 9.57 ? 136 ARG A N 1
ATOM 1072 C ? 30.498 17.375 37.040 1.00 10.86 ? 136 ARG A CA 1
ATOM 1073 C ? 31.964 17.676 36.776 1.00 11.68 ? 136 ARG A C 1
ATOM 1074 O ? 32.782 16.765 36.686 1.00 11.35 ? 136 ARG A O 1
ATOM 1075 C ? 30.221 17.319 38.536 1.00 11.99 ? 136 ARG A CB 1
ATOM 1076 C ? 28.746 17.454 38.885 1.00 13.89 ? 136 ARG A CG 1
ATOM 1077 C ? 28.576 17.533 40.382 1.00 15.85 ? 136 ARG A CD 1
ATOM 1078 N ? 27.185 17.407 40.754 1.00 17.08 ? 136 ARG A NE 1
ATOM 1079 C ? 26.561 16.245 40.926 1.00 21.69 ? 136 ARG A CZ 1
ATOM 1080 N ? 27.217 15.102 40.754 1.00 23.26 ? 136 ARG A NH1 1
ATOM 1081 N ? 25.278 16.227 41.283 1.00 22.60 ? 136 ARG A NH2 1
ATOM 1082 N ? 32.282 18.963 36.663 1.00 15.12 ? 137 GLU A N 1
ATOM 1083 C ? 33.641 19.430 36.400 1.00 18.00 ? 137 GLU A CA 1
ATOM 1084 C ? 34.615 19.038 37.493 1.00 18.96 ? 137 GLU A C 1
ATOM 1085 O ? 34.221 19.175 38.659 1.00 17.37 ? 137 GLU A O 1
ATOM 1086 C ? 33.661 20.943 36.293 1.00 19.89 ? 137 GLU A CB 1
ATOM 1087 C ? 33.092 21.492 35.035 1.00 28.03 ? 137 GLU A CG 1
ATOM 1088 C ? 33.469 22.953 34.865 1.00 33.22 ? 137 GLU A CD 1
ATOM 1089 O ? 34.630 23.217 34.473 1.00 37.31 ? 137 GLU A OE1 1
ATOM 1090 O ? 32.636 23.836 35.164 1.00 36.38 ? 137 GLU A OE2 1
ATOM 1091 O ? 35.776 18.680 37.173 1.00 22.23 ? 137 GLU A OXT 1
HETATM 1092 C ? 21.972 29.831 16.739 1.00 15.25 ? 200 REA B C1 1
HETATM 1093 C ? 20.921 30.524 15.841 1.00 15.61 ? 200 REA B C2 1
HETATM 1094 C ? 20.245 29.635 14.848 1.00 16.19 ? 200 REA B C3 1
HETATM 1095 C ? 19.555 28.479 15.488 1.00 14.59 ? 200 REA B C4 1
HETATM 1096 C ? 20.389 27.812 16.587 1.00 14.10 ? 200 REA B C5 1
HETATM 1097 C ? 21.425 28.446 17.218 1.00 14.42 ? 200 REA B C6 1
HETATM 1098 C ? 22.242 27.851 18.297 1.00 13.89 ? 200 REA B C7 1
HETATM 1099 C ? 21.868 26.977 19.240 1.00 11.86 ? 200 REA B C8 1
HETATM 1100 C ? 22.705 26.434 20.286 1.00 10.87 ? 200 REA B C9 1
HETATM 1101 C ? 22.159 25.536 21.131 1.00 9.19 ? 200 REA B C10 1
HETATM 1102 C ? 22.875 24.924 22.234 1.00 10.35 ? 200 REA B C11 1
HETATM 1103 C ? 22.237 24.026 22.990 1.00 10.53 ? 200 REA B C12 1
HETATM 1104 C ? 22.856 23.377 24.125 1.00 10.91 ? 200 REA B C13 1
HETATM 1105 C ? 22.135 22.473 24.834 1.00 11.88 ? 200 REA B C14 1
HETATM 1106 C ? 22.563 21.710 26.016 1.00 14.86 ? 200 REA B C15 1
HETATM 1107 C ? 22.238 30.737 17.948 1.00 15.47 ? 200 REA B C16 1
HETATM 1108 C ? 23.292 29.620 15.948 1.00 13.42 ? 200 REA B C17 1
HETATM 1109 C ? 19.791 26.449 16.947 1.00 12.61 ? 200 REA B C18 1
HETATM 1110 C ? 24.181 26.841 20.385 1.00 10.08 ? 200 REA B C19 1
HETATM 1111 C ? 24.303 23.747 24.489 1.00 10.10 ? 200 REA B C20 1
HETATM 1112 O ? 23.640 21.075 25.978 1.00 13.29 ? 200 REA B O1 1
HETATM 1113 O ? 21.840 21.712 27.037 1.00 10.99 ? 200 REA B O2 1
HETATM 1114 O ? 21.817 19.604 31.169 1.00 17.43 ? 300 HOH C O 1
HETATM 1115 O ? 7.617 26.892 37.107 1.00 12.66 ? 301 HOH C O 1
HETATM 1116 O ? 22.885 27.835 25.056 1.00 18.86 ? 302 HOH C O 1
HETATM 1117 O ? 30.685 27.402 22.818 1.00 14.12 ? 303 HOH C O 1
HETATM 1118 O ? 29.930 20.839 40.398 1.00 16.48 ? 304 HOH C O 1
HETATM 1119 O ? 31.492 21.096 28.452 1.00 16.65 ? 305 HOH C O 1
HETATM 1120 O ? 19.459 26.601 30.320 1.00 9.81 ? 306 HOH C O 1
HETATM 1121 O ? 19.116 26.759 22.930 1.00 22.33 ? 307 HOH C O 1
HETATM 1122 O ? 16.356 22.299 28.453 1.00 35.46 ? 308 HOH C O 1
HETATM 1123 O ? 21.823 21.939 29.734 1.00 13.95 ? 309 HOH C O 1
HETATM 1124 O ? 13.206 22.267 22.102 1.00 20.07 ? 310 HOH C O 1
HETATM 1125 O ? 30.300 22.803 12.740 1.00 24.70 ? 311 HOH C O 1
HETATM 1126 O ? 7.344 23.059 35.600 1.00 8.82 ? 312 HOH C O 1
HETATM 1127 O ? 6.876 22.668 20.375 1.00 29.74 ? 313 HOH C O 1
HETATM 1128 O ? 17.917 24.800 29.159 1.00 23.69 ? 314 HOH C O 1
HETATM 1129 O ? 37.101 16.714 38.714 1.00 19.84 ? 315 HOH C O 1
HETATM 1130 O ? 28.721 7.425 30.043 1.00 14.94 ? 316 HOH C O 1
HETATM 1131 O ? 13.212 14.450 25.193 1.00 18.03 ? 317 HOH C O 1
HETATM 1132 O ? 6.094 9.777 39.151 1.00 13.98 ? 318 HOH C O 1
HETATM 1133 O ? 19.296 10.379 13.144 1.00 27.20 ? 319 HOH C O 1
HETATM 1134 O ? 25.337 10.931 16.577 1.00 18.41 ? 320 HOH C O 1
HETATM 1135 O ? 25.244 34.269 18.193 1.00 9.65 ? 321 HOH C O 1
HETATM 1136 O ? 23.567 10.727 14.429 1.00 11.13 ? 322 HOH C O 1
HETATM 1137 O ? 17.151 12.178 30.238 1.00 11.53 ? 323 HOH C O 1
HETATM 1138 O ? 27.768 11.967 42.077 1.00 23.33 ? 324 HOH C O 1
HETATM 1139 O ? 30.270 12.554 21.386 1.00 25.05 ? 325 HOH C O 1
HETATM 1140 O ? 25.662 15.488 18.515 1.00 10.80 ? 326 HOH C O 1
HETATM 1141 O ? 4.514 21.426 18.685 1.00 45.94 ? 327 HOH C O 1
HETATM 1142 O ? 8.081 23.201 17.690 1.00 30.16 ? 328 HOH C O 1
HETATM 1143 O ? 13.242 29.389 14.924 1.00 39.93 ? 329 HOH C O 1
HETATM 1144 O ? 10.514 18.772 10.176 1.00 33.65 ? 330 HOH C O 1
HETATM 1145 O ? 10.555 13.666 26.313 1.00 32.55 ? 331 HOH C O 1
HETATM 1146 O ? 5.189 16.418 31.375 1.00 35.78 ? 332 HOH C O 1
HETATM 1147 O ? 0.738 25.633 36.349 1.00 29.00 ? 333 HOH C O 1
HETATM 1148 O ? 2.976 28.966 37.321 1.00 40.14 ? 334 HOH C O 1
HETATM 1149 O ? 6.424 28.750 38.849 1.00 32.17 ? 335 HOH C O 1
HETATM 1150 O ? 12.503 30.488 31.704 1.00 41.11 ? 336 HOH C O 1
HETATM 1151 O ? 14.979 30.157 27.559 1.00 23.78 ? 337 HOH C O 1
HETATM 1152 O ? 17.312 32.981 28.812 1.00 20.84 ? 338 HOH C O 1
HETATM 1153 O ? 29.473 25.946 34.693 1.00 29.05 ? 339 HOH C O 1
HETATM 1154 O ? 30.328 23.817 33.494 1.00 24.17 ? 340 HOH C O 1
HETATM 1155 O ? 31.158 28.144 26.433 1.00 42.66 ? 341 HOH C O 1
HETATM 1156 O ? 30.276 28.397 16.400 1.00 21.90 ? 342 HOH C O 1
HETATM 1157 O ? 19.533 23.600 26.857 1.00 21.12 ? 343 HOH C O 1
HETATM 1158 O ? 17.892 24.675 24.549 1.00 48.11 ? 344 HOH C O 1
HETATM 1159 O ? 14.211 24.152 25.435 1.00 21.09 ? 345 HOH C O 1
HETATM 1160 O ? 15.223 27.626 27.056 1.00 27.16 ? 346 HOH C O 1
HETATM 1161 O ? 3.502 22.911 43.083 1.00 30.15 ? 347 HOH C O 1
HETATM 1162 O ? 20.610 7.668 40.212 1.00 49.06 ? 348 HOH C O 1
HETATM 1163 O ? 24.813 2.899 36.403 1.00 48.98 ? 349 HOH C O 1
HETATM 1164 O ? 29.900 5.163 26.918 1.00 23.60 ? 350 HOH C O 1
HETATM 1165 O ? 14.333 5.466 42.757 1.00 22.90 ? 351 HOH C O 1
HETATM 1166 O ? 8.914 5.771 35.515 1.00 35.92 ? 352 HOH C O 1
HETATM 1167 O ? 14.519 28.906 40.193 1.00 28.73 ? 353 HOH C O 1
HETATM 1168 O ? 17.573 20.203 47.080 1.00 37.63 ? 354 HOH C O 1
HETATM 1169 O ? 13.324 32.251 34.152 1.00 47.79 ? 355 HOH C O 1
HETATM 1170 O ? 12.491 24.840 7.594 1.00 39.45 ? 356 HOH C O 1
HETATM 1171 O ? 25.066 15.777 15.214 1.00 27.39 ? 357 HOH C O 1
HETATM 1172 O ? 27.138 17.638 17.834 1.00 45.12 ? 358 HOH C O 1
HETATM 1173 O ? 27.611 19.792 19.503 1.00 24.45 ? 359 HOH C O 1
HETATM 1174 O ? 11.358 8.880 19.119 1.00 24.31 ? 360 HOH C O 1
HETATM 1175 O ? 16.252 27.169 24.557 1.00 25.40 ? 361 HOH C O 1
HETATM 1176 O ? 22.049 27.870 4.565 1.00 25.37 ? 362 HOH C O 1
HETATM 1177 O ? 11.533 6.689 34.501 1.00 29.92 ? 363 HOH C O 1
HETATM 1178 O ? 13.269 4.551 36.338 1.00 45.75 ? 364 HOH C O 1
HETATM 1179 O ? 23.149 9.493 41.173 1.00 30.10 ? 365 HOH C O 1
HETATM 1180 O ? 21.090 12.171 43.973 1.00 27.97 ? 366 HOH C O 1
HETATM 1181 O ? 11.884 13.399 42.560 1.00 23.28 ? 367 HOH C O 1
HETATM 1182 O ? 29.542 17.520 20.025 1.00 38.32 ? 368 HOH C O 1
HETATM 1183 O ? 31.058 17.427 22.538 1.00 37.85 ? 369 HOH C O 1
HETATM 1184 O ? 31.928 9.444 23.294 1.00 46.07 ? 370 HOH C O 1
HETATM 1185 O ? 25.699 10.933 9.557 1.00 44.12 ? 371 HOH C O 1
HETATM 1186 O ? 26.533 13.428 16.334 1.00 45.21 ? 372 HOH C O 1
HETATM 1187 O ? 27.078 16.850 13.245 1.00 39.52 ? 373 HOH C O 1
HETATM 1188 O ? 20.596 32.070 6.807 1.00 36.38 ? 374 HOH C O 1
HETATM 1189 O ? 17.126 28.421 9.515 1.00 23.81 ? 375 HOH C O 1
HETATM 1190 O ? 16.626 32.383 11.231 1.00 20.11 ? 376 HOH C O 1
HETATM 1191 O ? 6.046 30.510 19.639 1.00 29.02 ? 377 HOH C O 1
HETATM 1192 O ? 9.543 16.072 11.145 1.00 50.91 ? 378 HOH C O 1
HETATM 1193 O ? 8.174 14.289 20.240 1.00 54.21 ? 379 HOH C O 1
HETATM 1194 O ? 11.561 10.834 22.873 1.00 43.23 ? 380 HOH C O 1
HETATM 1195 O ? 5.486 15.385 24.922 1.00 50.19 ? 381 HOH C O 1
HETATM 1196 O ? 6.038 21.424 43.276 1.00 46.64 ? 382 HOH C O 1
HETATM 1197 O ? 34.144 19.165 27.284 1.00 41.41 ? 383 HOH C O 1
HETATM 1198 O ? 16.916 27.142 42.621 1.00 29.32 ? 384 HOH C O 1
HETATM 1199 O ? 25.509 24.918 41.520 1.00 32.12 ? 385 HOH C O 1
HETATM 1200 O ? 31.446 7.504 31.389 1.00 28.93 ? 386 HOH C O 1
HETATM 1201 O ? 18.212 20.893 5.892 1.00 29.90 ? 387 HOH C O 1
HETATM 1202 O ? 15.148 27.608 7.685 1.00 30.91 ? 388 HOH C O 1
HETATM 1203 O ? 2.656 23.148 20.117 1.00 35.98 ? 389 HOH C O 1
HETATM 1204 O ? 3.100 22.690 28.640 1.00 31.31 ? 390 HOH C O 1
HETATM 1205 O ? 13.699 19.720 21.819 1.00 26.56 ? 391 HOH C O 1
HETATM 1206 O ? 26.833 28.283 32.272 1.00 31.48 ? 392 HOH C O 1
HETATM 1207 O ? 20.458 26.214 25.811 1.00 24.39 ? 393 HOH C O 1
HETATM 1208 O ? 32.304 27.731 18.152 1.00 41.66 ? 394 HOH C O 1
HETATM 1209 O ? 24.283 13.868 42.687 1.00 35.59 ? 395 HOH C O 1
HETATM 1210 O ? 11.833 12.657 45.160 1.00 38.30 ? 396 HOH C O 1
HETATM 1211 O ? 1.988 27.992 43.589 1.00 33.97 ? 397 HOH C O 1
HETATM 1212 O ? 32.913 22.982 40.176 1.00 39.26 ? 398 HOH C O 1
HETATM 1213 O ? 32.435 20.043 40.169 1.00 33.87 ? 399 HOH C O 1
#
data_1CBS
#
_entry.id 1CBS
#
loop_
_atom_site.group_PDB
_atom_site.id
_atom_site.type_symbol
_atom_site.pdbx_PDB_ins_code
_atom_site.Cartn_x
_atom_site.Cartn_y
_atom_site.Cartn_z
_atom_site.occupancy
_atom_site.B_iso_or_equiv
_atom_site.pdbx_formal_charge
_atom_site.auth_seq_id
_atom_site.auth_comp_id
_atom_site.auth_asym_id
_atom_site.auth_atom_id
_atom_site.pdbx_PDB_model_num
ATOM 1 N ? 16.979 13.301 44.555 1.00 30.05 ? 1 PRO A N 1
ATOM 2 C ? 18.150 13.525 43.680 1.00 28.82 ? 1 PRO A CA 1
ATOM 3 C ? 18.656 14.966 43.784 1.00 26.59 ? 1 PRO A C 1
ATOM 4 O ? 17.890 15.889 44.078 1.00 26.84 ? 1 PRO A O 1
ATOM 5 C ? 17.678 13.270 42.255 1.00 29.24 ? 1 PRO A CB 1
ATOM 6 C ? 16.248 13.734 42.347 1.00 29.29 ? 1 PRO A CG 1
ATOM 7 C ? 15.762 13.216 43.724 1.00 30.71 ? 1 PRO A CD 1
ATOM 8 N ? 19.957 15.139 43.558 1.00 24.04 ? 2 ASN A N 1
ATOM 9 C ? 20.576 16.457 43.578 1.00 20.79 ? 2 ASN A CA 1
ATOM 10 C ? 21.301 16.714 42.262 1.00 16.75 ? 2 ASN A C 1
ATOM 11 O ? 22.402 16.215 42.028 1.00 15.23 ? 2 ASN A O 1
ATOM 12 C ? 21.559 16.620 44.724 1.00 22.81 ? 2 ASN A CB 1
ATOM 13 C ? 22.240 17.968 44.685 1.00 24.29 ? 2 ASN A CG 1
ATOM 14 O ? 21.612 18.984 44.358 1.00 21.87 ? 2 ASN A OD1 1
ATOM 15 N ? 23.537 17.983 44.966 1.00 27.94 ? 2 ASN A ND2 1
ATOM 16 N ? 20.637 17.477 41.402 1.00 14.69 ? 3 PHE A N 1
ATOM 17 C ? 21.144 17.838 40.087 1.00 12.62 ? 3 PHE A CA 1
ATOM 18 C ? 22.152 18.987 40.140 1.00 12.43 ? 3 PHE A C 1
ATOM 19 O ? 22.796 19.289 39.136 1.00 12.12 ? 3 PHE A O 1
ATOM 20 C ? 19.970 18.262 39.188 1.00 10.74 ? 3 PHE A CB 1
ATOM 21 C ? 19.073 17.128 38.750 1.00 11.85 ? 3 PHE A CG 1
ATOM 22 C ? 18.066 16.646 39.581 1.00 10.90 ? 3 PHE A CD1 1
ATOM 23 C ? 19.189 16.588 37.475 1.00 13.26 ? 3 PHE A CD2 1
ATOM 24 C ? 17.200 15.662 39.149 1.00 9.12 ? 3 PHE A CE1 1
ATOM 25 C ? 18.312 15.594 37.041 1.00 11.76 ? 3 PHE A CE2 1
ATOM 26 C ? 17.324 15.137 37.878 1.00 10.30 ? 3 PHE A CZ 1
ATOM 27 N ? 22.282 19.630 41.299 1.00 11.24 ? 4 SER A N 1
ATOM 28 C ? 23.170 20.780 41.464 1.00 11.30 ? 4 SER A CA 1
ATOM 29 C ? 24.627 20.568 41.091 1.00 10.39 ? 4 SER A C 1
ATOM 30 O ? 25.201 19.532 41.384 1.00 10.24 ? 4 SER A O 1
ATOM 31 C ? 23.112 21.301 42.906 1.00 13.53 ? 4 SER A CB 1
ATOM 32 O ? 21.821 21.787 43.240 1.00 16.76 ? 4 SER A OG 1
ATOM 33 N ? 25.224 21.572 40.460 1.00 9.87 ? 5 GLY A N 1
ATOM 34 C ? 26.628 21.486 40.103 1.00 10.86 ? 5 GLY A CA 1
ATOM 35 C ? 26.985 22.158 38.794 1.00 11.21 ? 5 GLY A C 1
ATOM 36 O ? 26.123 22.761 38.142 1.00 9.91 ? 5 GLY A O 1
ATOM 37 N ? 28.277 22.142 38.475 1.00 10.41 ? 6 ASN A N 1
ATOM 38 C ? 28.796 22.676 37.211 1.00 11.06 ? 6 ASN A CA 1
ATOM 39 C ? 29.117 21.435 36.378 1.00 10.33 ? 6 ASN A C 1
ATOM 40 O ? 29.947 20.603 36.754 1.00 11.28 ? 6 ASN A O 1
ATOM 41 C ? 30.023 23.548 37.445 1.00 12.95 ? 6 ASN A CB 1
ATOM 42 C ? 29.675 24.816 38.200 1.00 18.08 ? 6 ASN A CG 1
ATOM 43 O ? 29.022 25.708 37.665 1.00 19.52 ? 6 ASN A OD1 1
ATOM 44 N ? 30.047 24.872 39.467 1.00 21.23 ? 6 ASN A ND2 1
ATOM 45 N ? 28.399 21.289 35.272 1.00 8.66 ? 7 TRP A N 1
ATOM 46 C ? 28.518 20.119 34.424 1.00 8.74 ? 7 TRP A CA 1
ATOM 47 C ? 29.246 20.352 33.092 1.00 9.63 ? 7 TRP A C 1
ATOM 48 O ? 29.064 21.389 32.440 1.00 9.45 ? 7 TRP A O 1
ATOM 49 C ? 27.115 19.563 34.152 1.00 8.00 ? 7 TRP A CB 1
ATOM 50 C ? 26.325 19.198 35.391 1.00 8.01 ? 7 TRP A CG 1
ATOM 51 C ? 25.556 20.031 36.159 1.00 8.29 ? 7 TRP A CD1 1
ATOM 52 C ? 26.174 17.885 35.947 1.00 7.60 ? 7 TRP A CD2 1
ATOM 53 N ? 24.922 19.308 37.156 1.00 9.20 ? 7 TRP A NE1 1
ATOM 54 C ? 25.286 17.987 37.046 1.00 8.73 ? 7 TRP A CE2 1
ATOM 55 C ? 26.694 16.625 35.618 1.00 6.99 ? 7 TRP A CE3 1
ATOM 56 C ? 24.909 16.876 37.815 1.00 7.67 ? 7 TRP A CZ2 1
ATOM 57 C ? 26.320 15.527 36.380 1.00 7.58 ? 7 TRP A CZ3 1
ATOM 58 C ? 25.433 15.663 37.468 1.00 5.92 ? 7 TRP A CH2 1
ATOM 59 N ? 30.052 19.368 32.702 1.00 9.39 ? 8 LYS A N 1
ATOM 60 C ? 30.802 19.424 31.450 1.00 11.56 ? 8 LYS A CA 1
ATOM 61 C ? 30.342 18.243 30.611 1.00 10.56 ? 8 LYS A C 1
ATOM 62 O ? 30.091 17.158 31.138 1.00 10.14 ? 8 LYS A O 1
ATOM 63 C ? 32.308 19.360 31.710 1.00 15.20 ? 8 LYS A CB 1
ATOM 64 C ? 32.785 18.080 32.313 1.00 18.52 ? 8 LYS A CG 1
ATOM 65 C ? 34.263 18.182 32.618 1.00 26.26 ? 8 LYS A CD 1
ATOM 66 C ? 35.091 18.499 31.378 1.00 29.22 ? 8 LYS A CE 1
ATOM 67 N ? 35.067 17.393 30.369 1.00 32.48 ? 8 LYS A NZ 1
ATOM 68 N ? 30.222 18.447 29.308 1.00 8.21 ? 9 ILE A N 1
ATOM 69 C ? 29.739 17.384 28.441 1.00 8.08 ? 9 ILE A CA 1
ATOM 70 C ? 30.798 16.325 28.117 1.00 7.86 ? 9 ILE A C 1
ATOM 71 O ? 31.990 16.635 28.028 1.00 8.38 ? 9 ILE A O 1
ATOM 72 C ? 29.148 17.997 27.144 1.00 10.70 ? 9 ILE A CB 1
ATOM 73 C ? 28.285 16.981 26.401 1.00 10.95 ? 9 ILE A CG1 1
ATOM 74 C ? 30.261 18.500 26.243 1.00 10.70 ? 9 ILE A CG2 1
ATOM 75 C ? 27.586 17.597 25.207 1.00 13.23 ? 9 ILE A CD1 1
ATOM 76 N ? 30.373 15.067 27.995 1.00 7.08 ? 10 ILE A N 1
ATOM 77 C ? 31.288 13.988 27.656 1.00 7.45 ? 10 ILE A CA 1
ATOM 78 C ? 30.812 13.201 26.441 1.00 8.49 ? 10 ILE A C 1
ATOM 79 O ? 31.561 12.397 25.892 1.00 9.49 ? 10 ILE A O 1
ATOM 80 C ? 31.586 13.023 28.847 1.00 10.28 ? 10 ILE A CB 1
ATOM 81 C ? 30.304 12.393 29.382 1.00 10.51 ? 10 ILE A CG1 1
ATOM 82 C ? 32.349 13.756 29.963 1.00 10.10 ? 10 ILE A CG2 1
ATOM 83 C ? 30.578 11.242 30.325 1.00 12.18 ? 10 ILE A CD1 1
ATOM 84 N ? 29.566 13.419 26.030 1.00 7.59 ? 11 ARG A N 1
ATOM 85 C ? 29.015 12.742 24.851 1.00 8.70 ? 11 ARG A CA 1
ATOM 86 C ? 27.821 13.500 24.290 1.00 9.41 ? 11 ARG A C 1
ATOM 87 O ? 26.990 14.004 25.043 1.00 9.84 ? 11 ARG A O 1
ATOM 88 C ? 28.563 11.316 25.184 1.00 8.07 ? 11 ARG A CB 1
ATOM 89 C ? 27.912 10.616 23.998 1.00 12.26 ? 11 ARG A CG 1
ATOM 90 C ? 27.234 9.340 24.394 1.00 13.46 ? 11 ARG A CD 1
ATOM 91 N ? 28.157 8.304 24.847 1.00 15.44 ? 11 ARG A NE 1
ATOM 92 C ? 28.815 7.470 24.037 1.00 19.59 ? 11 ARG A CZ 1
ATOM 93 N ? 28.677 7.559 22.714 1.00 19.40 ? 11 ARG A NH1 1
ATOM 94 N ? 29.521 6.467 24.547 1.00 17.50 ? 11 ARG A NH2 1
ATOM 95 N ? 27.748 13.594 22.965 1.00 8.84 ? 12 SER A N 1
ATOM 96 C ? 26.621 14.245 22.310 1.00 8.61 ? 12 SER A CA 1
ATOM 97 C ? 26.278 13.431 21.063 1.00 9.48 ? 12 SER A C 1
ATOM 98 O ? 27.159 13.147 20.250 1.00 9.84 ? 12 SER A O 1
ATOM 99 C ? 26.966 15.676 21.925 1.00 9.02 ? 12 SER A CB 1
ATOM 100 O ? 25.863 16.285 21.273 1.00 11.97 ? 12 SER A OG 1
ATOM 101 N ? 25.016 13.038 20.924 1.00 7.59 ? 13 GLU A N 1
ATOM 102 C ? 24.586 12.258 19.768 1.00 9.67 ? 13 GLU A CA 1
ATOM 103 C ? 23.368 12.887 19.118 1.00 9.06 ? 13 GLU A C 1
ATOM 104 O ? 22.457 13.343 19.815 1.00 7.34 ? 13 GLU A O 1
ATOM 105 C ? 24.185 10.833 20.184 1.00 9.72 ? 13 GLU A CB 1
ATOM 106 C ? 25.257 10.018 20.895 1.00 15.17 ? 13 GLU A CG 1
ATOM 107 C ? 26.262 9.340 19.954 1.00 18.75 ? 13 GLU A CD 1
ATOM 108 O ? 26.031 9.310 18.726 1.00 18.53 ? 13 GLU A OE1 1
ATOM 109 O ? 27.286 8.822 20.457 1.00 19.23 ? 13 GLU A OE2 1
ATOM 110 N ? 23.363 12.919 17.786 1.00 8.79 ? 14 ASN A N 1
ATOM 111 C ? 22.202 13.408 17.025 1.00 8.29 ? 14 ASN A CA 1
ATOM 112 C ? 21.813 14.896 17.153 1.00 7.35 ? 14 ASN A C 1
ATOM 113 O ? 20.681 15.245 16.860 1.00 7.00 ? 14 ASN A O 1
ATOM 114 C ? 20.989 12.522 17.383 1.00 7.23 ? 14 ASN A CB 1
ATOM 115 C ? 20.358 11.833 16.172 1.00 9.38 ? 14 ASN A CG 1
ATOM 116 O ? 20.996 11.670 15.128 1.00 10.37 ? 14 ASN A OD1 1
ATOM 117 N ? 19.106 11.436 16.310 1.00 6.35 ? 14 ASN A ND2 1
ATOM 118 N ? 22.734 15.777 17.536 1.00 7.26 ? 15 PHE A N 1
ATOM 119 C ? 22.385 17.198 17.681 1.00 9.06 ? 15 PHE A CA 1
ATOM 120 C ? 22.041 17.878 16.358 1.00 9.15 ? 15 PHE A C 1
ATOM 121 O ? 21.041 18.578 16.265 1.00 8.64 ? 15 PHE A O 1
ATOM 122 C ? 23.497 17.990 18.379 1.00 10.05 ? 15 PHE A CB 1
ATOM 123 C ? 23.102 19.397 18.746 1.00 10.57 ? 15 PHE A CG 1
ATOM 124 C ? 22.032 19.633 19.605 1.00 13.39 ? 15 PHE A CD1 1
ATOM 125 C ? 23.813 20.485 18.254 1.00 11.47 ? 15 PHE A CD2 1
ATOM 126 C ? 21.678 20.929 19.968 1.00 13.52 ? 15 PHE A CE1 1
ATOM 127 C ? 23.467 21.784 18.609 1.00 11.60 ? 15 PHE A CE2 1
ATOM 128 C ? 22.399 22.006 19.469 1.00 13.52 ? 15 PHE A CZ 1
ATOM 129 N ? 22.878 17.699 15.342 1.00 11.17 ? 16 GLU A N 1
ATOM 130 C ? 22.583 18.313 14.053 1.00 12.58 ? 16 GLU A CA 1
ATOM 131 C ? 21.271 17.797 13.468 1.00 11.71 ? 16 GLU A C 1
ATOM 132 O ? 20.503 18.567 12.888 1.00 12.66 ? 16 GLU A O 1
ATOM 133 C ? 23.711 18.081 13.060 1.00 15.91 ? 16 GLU A CB 1
ATOM 134 C ? 23.274 18.337 11.626 1.00 21.31 ? 16 GLU A CG 1
ATOM 135 C ? 24.376 18.878 10.757 1.00 25.39 ? 16 GLU A CD 1
ATOM 136 O ? 25.526 18.984 11.240 1.00 27.92 ? 16 GLU A OE1 1
ATOM 137 O ? 24.084 19.213 9.588 1.00 28.60 ? 16 GLU A OE2 1
ATOM 138 N ? 21.018 16.497 13.619 1.00 11.67 ? 17 GLU A N 1
ATOM 139 C ? 19.785 15.878 13.116 1.00 13.65 ? 17 GLU A CA 1
ATOM 140 C ? 18.529 16.490 13.767 1.00 13.48 ? 17 GLU A C 1
ATOM 141 O ? 17.490 16.662 13.115 1.00 11.68 ? 17 GLU A O 1
ATOM 142 C ? 19.811 14.361 13.325 1.00 17.06 ? 17 GLU A CB 1
ATOM 143 C ? 20.806 13.602 12.430 1.00 23.45 ? 17 GLU A CG 1
ATOM 144 C ? 22.279 13.624 12.909 1.00 27.80 ? 17 GLU A CD 1
ATOM 145 O ? 22.637 14.338 13.881 1.00 26.52 ? 17 GLU A OE1 1
ATOM 146 O ? 23.097 12.897 12.291 1.00 31.80 ? 17 GLU A OE2 1
ATOM 147 N ? 18.640 16.834 15.048 1.00 10.82 ? 18 LEU A N 1
ATOM 148 C ? 17.547 17.468 15.777 1.00 9.45 ? 18 LEU A CA 1
ATOM 149 C ? 17.302 18.849 15.155 1.00 9.27 ? 18 LEU A C 1
ATOM 150 O ? 16.153 19.246 14.927 1.00 9.04 ? 18 LEU A O 1
ATOM 151 C ? 17.931 17.644 17.253 1.00 9.77 ? 18 LEU A CB 1
ATOM 152 C ? 16.921 18.358 18.163 1.00 11.36 ? 18 LEU A CG 1
ATOM 153 C ? 15.817 17.402 18.554 1.00 13.85 ? 18 LEU A CD1 1
ATOM 154 C ? 17.616 18.876 19.409 1.00 12.69 ? 18 LEU A CD2 1
ATOM 155 N ? 18.387 19.568 14.864 1.00 10.75 ? 19 LEU A N 1
ATOM 156 C ? 18.275 20.906 14.276 1.00 11.15 ? 19 LEU A CA 1
ATOM 157 C ? 17.671 20.873 12.874 1.00 12.52 ? 19 LEU A C 1
ATOM 158 O ? 16.932 21.777 12.485 1.00 10.05 ? 19 LEU A O 1
ATOM 159 C ? 19.631 21.616 14.263 1.00 12.01 ? 19 LEU A CB 1
ATOM 160 C ? 20.282 21.963 15.614 1.00 10.42 ? 19 LEU A CG 1
ATOM 161 C ? 21.560 22.763 15.369 1.00 13.01 ? 19 LEU A CD1 1
ATOM 162 C ? 19.312 22.742 16.513 1.00 11.45 ? 19 LEU A CD2 1
ATOM 163 N ? 17.944 19.795 12.150 1.00 14.41 ? 20 LYS A N 1
ATOM 164 C ? 17.427 19.628 10.800 1.00 16.54 ? 20 LYS A CA 1
ATOM 165 C ? 15.902 19.512 10.832 1.00 16.17 ? 20 LYS A C 1
ATOM 166 O ? 15.201 20.164 10.053 1.00 15.90 ? 20 LYS A O 1
ATOM 167 C ? 18.048 18.390 10.157 1.00 20.07 ? 20 LYS A CB 1
ATOM 168 C ? 18.592 18.643 8.765 1.00 26.61 ? 20 LYS A CG 1
ATOM 169 C ? 18.960 17.349 8.027 1.00 30.95 ? 20 LYS A CD 1
ATOM 170 C ? 20.226 16.690 8.579 1.00 35.68 ? 20 LYS A CE 1
ATOM 171 N ? 21.485 17.466 8.342 1.00 39.27 ? 20 LYS A NZ 1
ATOM 172 N ? 15.395 18.700 11.759 1.00 15.31 ? 21 VAL A N 1
ATOM 173 C ? 13.958 18.508 11.927 1.00 14.41 ? 21 VAL A CA 1
ATOM 174 C ? 13.275 19.831 12.316 1.00 15.02 ? 21 VAL A C 1
ATOM 175 O ? 12.150 20.119 11.878 1.00 13.59 ? 21 VAL A O 1
ATOM 176 C ? 13.674 17.422 12.998 1.00 14.93 ? 21 VAL A CB 1
ATOM 177 C ? 12.194 17.383 13.364 1.00 17.29 ? 21 VAL A CG1 1
ATOM 178 C ? 14.115 16.082 12.482 1.00 15.09 ? 21 VAL A CG2 1
ATOM 179 N ? 13.966 20.643 13.119 1.00 14.52 ? 22 LEU A N 1
ATOM 180 C ? 13.432 21.938 13.569 1.00 14.42 ? 22 LEU A CA 1
ATOM 181 C ? 13.478 22.984 12.467 1.00 15.49 ? 22 LEU A C 1
ATOM 182 O ? 13.038 24.115 12.666 1.00 16.81 ? 22 LEU A O 1
ATOM 183 C ? 14.180 22.440 14.818 1.00 13.61 ? 22 LEU A CB 1
ATOM 184 C ? 13.986 21.565 16.069 1.00 13.97 ? 22 LEU A CG 1
ATOM 185 C ? 14.852 22.047 17.225 1.00 13.25 ? 22 LEU A CD1 1
ATOM 186 C ? 12.525 21.580 16.467 1.00 14.62 ? 22 LEU A CD2 1
ATOM 187 N ? 14.062 22.618 11.328 1.00 16.41 ? 23 GLY A N 1
ATOM 188 C ? 14.123 23.516 10.183 1.00 17.05 ? 23 GLY A CA 1
ATOM 189 C ? 15.241 24.539 10.125 1.00 18.00 ? 23 GLY A C 1
ATOM 190 O ? 15.112 25.545 9.425 1.00 19.45 ? 23 GLY A O 1
ATOM 191 N ? 16.320 24.315 10.869 1.00 14.78 ? 24 VAL A N 1
ATOM 192 C ? 17.440 25.241 10.860 1.00 13.71 ? 24 VAL A CA 1
ATOM 193 C ? 18.289 24.983 9.607 1.00 15.09 ? 24 VAL A C 1
ATOM 194 O ? 18.679 23.840 9.334 1.00 14.12 ? 24 VAL A O 1
ATOM 195 C ? 18.297 25.081 12.139 1.00 12.19 ? 24 VAL A CB 1
ATOM 196 C ? 19.465 26.054 12.109 1.00 8.69 ? 24 VAL A CG1 1
ATOM 197 C ? 17.416 25.294 13.388 1.00 11.37 ? 24 VAL A CG2 1
ATOM 198 N ? 18.595 26.047 8.866 1.00 15.37 ? 25 ASN A N 1
ATOM 199 C ? 19.360 25.914 7.635 1.00 17.74 ? 25 ASN A CA 1
ATOM 200 C ? 20.808 25.466 7.819 1.00 18.29 ? 25 ASN A C 1
ATOM 201 O ? 21.377 25.592 8.903 1.00 18.05 ? 25 ASN A O 1
ATOM 202 C ? 19.230 27.172 6.742 1.00 19.41 ? 25 ASN A CB 1
ATOM 203 C ? 20.090 28.351 7.200 1.00 22.35 ? 25 ASN A CG 1
ATOM 204 O ? 21.207 28.189 7.698 1.00 22.64 ? 25 ASN A OD1 1
ATOM 205 N ? 19.602 29.558 6.933 1.00 24.15 ? 25 ASN A ND2 1
ATOM 206 N ? 21.398 24.971 6.733 1.00 18.67 ? 26 VAL A N 1
ATOM 207 C ? 22.755 24.444 6.742 1.00 19.24 ? 26 VAL A CA 1
ATOM 208 C ? 23.825 25.280 7.421 1.00 18.39 ? 26 VAL A C 1
ATOM 209 O ? 24.558 24.764 8.261 1.00 18.50 ? 26 VAL A O 1
ATOM 210 C ? 23.223 24.088 5.320 1.00 20.77 ? 26 VAL A CB 1
ATOM 211 C ? 24.624 23.523 5.378 1.00 22.39 ? 26 VAL A CG1 1
ATOM 212 C ? 22.276 23.084 4.698 1.00 21.28 ? 26 VAL A CG2 1
ATOM 213 N ? 23.932 26.556 7.052 1.00 19.00 ? 27 MET A N 1
ATOM 214 C ? 24.948 27.433 7.628 1.00 19.54 ? 27 MET A CA 1
ATOM 215 C ? 24.734 27.741 9.099 1.00 19.04 ? 27 MET A C 1
ATOM 216 O ? 25.702 27.820 9.849 1.00 18.28 ? 27 MET A O 1
ATOM 217 C ? 25.104 28.736 6.830 1.00 23.31 ? 27 MET A CB 1
ATOM 218 C ? 25.955 28.602 5.552 1.00 29.99 ? 27 MET A CG 1
ATOM 219 S ? 24.975 28.527 4.010 1.00 37.48 ? 27 MET A SD 1
ATOM 220 C ? 26.198 29.150 2.776 1.00 35.24 ? 27 MET A CE 1
ATOM 221 N ? 23.480 27.932 9.507 1.00 16.74 ? 28 LEU A N 1
ATOM 222 C ? 23.190 28.209 10.912 1.00 16.39 ? 28 LEU A CA 1
ATOM 223 C ? 23.477 26.954 11.722 1.00 16.86 ? 28 LEU A C 1
ATOM 224 O ? 23.954 27.038 12.852 1.00 15.09 ? 28 LEU A O 1
ATOM 225 C ? 21.739 28.679 11.111 1.00 15.94 ? 28 LEU A CB 1
ATOM 226 C ? 21.490 30.154 10.741 1.00 16.72 ? 28 LEU A CG 1
ATOM 227 C ? 20.008 30.496 10.780 1.00 14.38 ? 28 LEU A CD1 1
ATOM 228 C ? 22.302 31.074 11.665 1.00 12.81 ? 28 LEU A CD2 1
ATOM 229 N ? 23.228 25.791 11.121 1.00 16.05 ? 29 ARG A N 1
ATOM 230 C ? 23.498 24.524 11.798 1.00 18.43 ? 29 ARG A CA 1
ATOM 231 C ? 24.980 24.377 12.076 1.00 19.22 ? 29 ARG A C 1
ATOM 232 O ? 25.383 23.987 13.171 1.00 17.97 ? 29 ARG A O 1
ATOM 233 C ? 23.030 23.334 10.969 1.00 18.63 ? 29 ARG A CB 1
ATOM 234 C ? 21.596 22.983 11.189 1.00 21.26 ? 29 ARG A CG 1
ATOM 235 C ? 21.339 21.572 10.739 1.00 24.71 ? 29 ARG A CD 1
ATOM 236 N ? 20.571 21.564 9.513 1.00 29.88 ? 29 ARG A NE 1
ATOM 237 C ? 21.019 21.147 8.340 1.00 29.19 ? 29 ARG A CZ 1
ATOM 238 N ? 22.248 20.682 8.205 1.00 30.52 ? 29 ARG A NH1 1
ATOM 239 N ? 20.232 21.233 7.295 1.00 31.61 ? 29 ARG A NH2 1
ATOM 240 N ? 25.790 24.709 11.078 1.00 19.76 ? 30 LYS A N 1
ATOM 241 C ? 27.235 24.619 11.198 1.00 21.96 ? 30 LYS A CA 1
ATOM 242 C ? 27.706 25.418 12.417 1.00 20.91 ? 30 LYS A C 1
ATOM 243 O ? 28.470 24.916 13.239 1.00 22.15 ? 30 LYS A O 1
ATOM 244 C ? 27.894 25.143 9.915 1.00 25.07 ? 30 LYS A CB 1
ATOM 245 C ? 29.404 25.031 9.905 1.00 30.48 ? 30 LYS A CG 1
ATOM 246 C ? 30.013 25.631 8.639 1.00 35.43 ? 30 LYS A CD 1
ATOM 247 C ? 31.533 25.759 8.778 1.00 37.96 ? 30 LYS A CE 1
ATOM 248 N ? 32.180 26.388 7.584 1.00 41.61 ? 30 LYS A NZ 1
ATOM 249 N ? 27.208 26.643 12.544 1.00 18.38 ? 31 ILE A N 1
ATOM 250 C ? 27.557 27.527 13.652 1.00 16.41 ? 31 ILE A CA 1
ATOM 251 C ? 27.105 26.932 14.989 1.00 15.39 ? 31 ILE A C 1
ATOM 252 O ? 27.888 26.855 15.930 1.00 14.90 ? 31 ILE A O 1
ATOM 253 C ? 26.881 28.920 13.471 1.00 16.63 ? 31 ILE A CB 1
ATOM 254 C ? 27.419 29.606 12.208 1.00 18.74 ? 31 ILE A CG1 1
ATOM 255 C ? 27.071 29.791 14.713 1.00 15.71 ? 31 ILE A CG2 1
ATOM 256 C ? 26.735 30.946 11.858 1.00 17.27 ? 31 ILE A CD1 1
ATOM 257 N ? 25.853 26.487 15.048 1.00 13.39 ? 32 ALA A N 1
ATOM 258 C ? 25.271 25.930 16.267 1.00 12.76 ? 32 ALA A CA 1
ATOM 259 C ? 25.994 24.685 16.775 1.00 12.11 ? 32 ALA A C 1
ATOM 260 O ? 26.325 24.598 17.946 1.00 10.54 ? 32 ALA A O 1
ATOM 261 C ? 23.790 25.638 16.040 1.00 12.45 ? 32 ALA A CB 1
ATOM 262 N ? 26.252 23.731 15.886 1.00 11.95 ? 33 VAL A N 1
ATOM 263 C ? 26.932 22.490 16.256 1.00 13.80 ? 33 VAL A CA 1
ATOM 264 C ? 28.328 22.701 16.855 1.00 14.00 ? 33 VAL A C 1
ATOM 265 O ? 28.693 22.048 17.832 1.00 14.07 ? 33 VAL A O 1
ATOM 266 C ? 27.016 21.504 15.044 1.00 13.56 ? 33 VAL A CB 1
ATOM 267 C ? 27.909 20.318 15.375 1.00 16.07 ? 33 VAL A CG1 1
ATOM 268 C ? 25.621 21.006 14.684 1.00 14.96 ? 33 VAL A CG2 1
ATOM 269 N ? 29.101 23.620 16.281 1.00 14.73 ? 34 ALA A N 1
ATOM 270 C ? 30.443 23.898 16.780 1.00 14.95 ? 34 ALA A CA 1
ATOM 271 C ? 30.381 24.505 18.178 1.00 15.59 ? 34 ALA A C 1
ATOM 272 O ? 31.120 24.085 19.065 1.00 16.65 ? 34 ALA A O 1
ATOM 273 C ? 31.191 24.844 15.833 1.00 16.10 ? 34 ALA A CB 1
ATOM 274 N ? 29.495 25.480 18.375 1.00 13.20 ? 35 ALA A N 1
ATOM 275 C ? 29.371 26.134 19.671 1.00 13.04 ? 35 ALA A CA 1
ATOM 276 C ? 28.807 25.200 20.749 1.00 12.91 ? 35 ALA A C 1
ATOM 277 O ? 29.245 25.239 21.895 1.00 12.32 ? 35 ALA A O 1
ATOM 278 C ? 28.517 27.387 19.552 1.00 12.14 ? 35 ALA A CB 1
ATOM 279 N ? 27.878 24.332 20.362 1.00 11.40 ? 36 ALA A N 1
ATOM 280 C ? 27.253 23.416 21.312 1.00 12.63 ? 36 ALA A CA 1
ATOM 281 C ? 28.128 22.256 21.770 1.00 13.40 ? 36 ALA A C 1
ATOM 282 O ? 27.743 21.512 22.668 1.00 13.47 ? 36 ALA A O 1
ATOM 283 C ? 25.952 22.883 20.744 1.00 11.79 ? 36 ALA A CB 1
ATOM 284 N ? 29.286 22.080 21.148 1.00 13.86 ? 37 SER A N 1
ATOM 285 C ? 30.169 20.983 21.520 1.00 15.95 ? 37 SER A CA 1
ATOM 286 C ? 30.938 21.245 22.818 1.00 16.46 ? 37 SER A C 1
ATOM 287 O ? 31.488 20.320 23.406 1.00 18.23 ? 37 SER A O 1
ATOM 288 C ? 31.145 20.689 20.388 1.00 16.93 ? 37 SER A CB 1
ATOM 289 O ? 32.100 21.729 20.293 1.00 21.65 ? 37 SER A OG 1
ATOM 290 N ? 30.957 22.496 23.272 1.00 16.91 ? 38 LYS A N 1
ATOM 291 C ? 31.657 22.869 24.502 1.00 18.36 ? 38 LYS A CA 1
ATOM 292 C ? 30.817 23.809 25.382 1.00 15.90 ? 38 LYS A C 1
ATOM 293 O ? 31.175 24.975 25.591 1.00 16.72 ? 38 LYS A O 1
ATOM 294 C ? 33.004 23.539 24.156 1.00 23.99 ? 38 LYS A CB 1
ATOM 295 C ? 32.907 24.607 23.046 1.00 30.97 ? 38 LYS A CG 1
ATOM 296 C ? 34.250 25.320 22.792 1.00 36.44 ? 38 LYS A CD 1
ATOM 297 C ? 34.266 26.098 21.456 1.00 38.70 ? 38 LYS A CE 1
ATOM 298 N ? 33.193 27.131 21.321 1.00 39.37 ? 38 LYS A NZ 1
ATOM 299 N ? 29.669 23.321 25.906 1.00 13.53 ? 39 PRO A N 1
ATOM 300 C ? 28.851 24.201 26.747 1.00 11.87 ? 39 PRO A CA 1
ATOM 301 C ? 29.292 24.248 28.211 1.00 12.05 ? 39 PRO A C 1
ATOM 302 O ? 30.027 23.380 28.676 1.00 12.12 ? 39 PRO A O 1
ATOM 303 C ? 27.469 23.560 26.649 1.00 9.34 ? 39 PRO A CB 1
ATOM 304 C ? 27.779 22.131 26.593 1.00 10.32 ? 39 PRO A CG 1
ATOM 305 C ? 29.009 22.020 25.703 1.00 10.86 ? 39 PRO A CD 1
ATOM 306 N ? 28.921 25.316 28.898 1.00 11.52 ? 40 ALA A N 1
ATOM 307 C ? 29.192 25.423 30.329 1.00 11.84 ? 40 ALA A CA 1
ATOM 308 C ? 27.773 25.329 30.894 1.00 10.23 ? 40 ALA A C 1
ATOM 309 O ? 26.894 26.080 30.478 1.00 10.42 ? 40 ALA A O 1
ATOM 310 C ? 29.830 26.767 30.673 1.00 11.40 ? 40 ALA A CB 1
ATOM 311 N ? 27.518 24.345 31.750 1.00 10.73 ? 41 VAL A N 1
ATOM 312 C ? 26.185 24.169 32.333 1.00 9.92 ? 41 VAL A CA 1
ATOM 313 C ? 26.226 24.295 33.854 1.00 11.64 ? 41 VAL A C 1
ATOM 314 O ? 27.026 23.627 34.514 1.00 11.40 ? 41 VAL A O 1
ATOM 315 C ? 25.594 22.772 31.987 1.00 10.67 ? 41 VAL A CB 1
ATOM 316 C ? 24.204 22.596 32.612 1.00 11.34 ? 41 VAL A CG1 1
ATOM 317 C ? 25.507 22.583 30.475 1.00 11.31 ? 41 VAL A CG2 1
ATOM 318 N ? 25.364 25.147 34.399 1.00 10.94 ? 42 GLU A N 1
ATOM 319 C ? 25.271 25.327 35.845 1.00 12.40 ? 42 GLU A CA 1
ATOM 320 C ? 23.837 25.095 36.316 1.00 11.42 ? 42 GLU A C 1
ATOM 321 O ? 22.898 25.720 35.825 1.00 10.46 ? 42 GLU A O 1
ATOM 322 C ? 25.711 26.721 36.270 1.00 16.26 ? 42 GLU A CB 1
ATOM 323 C ? 25.495 26.947 37.768 1.00 23.78 ? 42 GLU A CG 1
ATOM 324 C ? 25.944 28.311 38.242 1.00 27.94 ? 42 GLU A CD 1
ATOM 325 O ? 25.308 29.329 37.872 1.00 29.92 ? 42 GLU A OE1 1
ATOM 326 O ? 26.935 28.351 39.002 1.00 32.64 ? 42 GLU A OE2 1
ATOM 327 N ? 23.673 24.176 37.261 1.00 10.55 ? 43 ILE A N 1
ATOM 328 C ? 22.362 23.864 37.794 1.00 10.69 ? 43 ILE A CA 1
ATOM 329 C ? 22.360 24.120 39.300 1.00 11.07 ? 43 ILE A C 1
ATOM 330 O ? 23.307 23.764 39.992 1.00 10.83 ? 43 ILE A O 1
ATOM 331 C ? 21.996 22.374 37.552 1.00 10.47 ? 43 ILE A CB 1
ATOM 332 C ? 21.974 22.072 36.056 1.00 10.46 ? 43 ILE A CG1 1
ATOM 333 C ? 20.636 22.031 38.186 1.00 10.34 ? 43 ILE A CG2 1
ATOM 334 C ? 21.607 20.639 35.726 1.00 9.00 ? 43 ILE A CD1 1
ATOM 335 N ? 21.315 24.784 39.778 1.00 12.26 ? 44 LYS A N 1
ATOM 336 C ? 21.127 25.051 41.201 1.00 13.96 ? 44 LYS A CA 1
ATOM 337 C ? 19.729 24.528 41.516 1.00 14.16 ? 44 LYS A C 1
ATOM 338 O ? 18.749 24.920 40.873 1.00 14.12 ? 44 LYS A O 1
ATOM 339 C ? 21.220 26.545 41.503 1.00 16.58 ? 44 LYS A CB 1
ATOM 340 C ? 22.580 27.150 41.170 1.00 22.90 ? 44 LYS A CG 1
ATOM 341 C ? 22.571 28.654 41.385 1.00 29.01 ? 44 LYS A CD 1
ATOM 342 C ? 23.890 29.293 40.982 1.00 31.56 ? 44 LYS A CE 1
ATOM 343 N ? 23.818 30.781 41.111 1.00 34.70 ? 44 LYS A NZ 1
ATOM 344 N ? 19.649 23.594 42.460 1.00 15.66 ? 45 GLN A N 1
ATOM 345 C ? 18.377 22.993 42.852 1.00 16.03 ? 45 GLN A CA 1
ATOM 346 C ? 18.098 23.182 44.342 1.00 17.60 ? 45 GLN A C 1
ATOM 347 O ? 18.989 23.024 45.164 1.00 17.17 ? 45 GLN A O 1
ATOM 348 C ? 18.397 21.498 42.544 1.00 15.51 ? 45 GLN A CB 1
ATOM 349 C ? 17.168 20.744 43.015 1.00 13.62 ? 45 GLN A CG 1
ATOM 350 C ? 17.312 19.256 42.838 1.00 15.68 ? 45 GLN A CD 1
ATOM 351 O ? 18.348 18.769 42.397 1.00 18.84 ? 45 GLN A OE1 1
ATOM 352 N ? 16.276 18.521 43.177 1.00 16.73 ? 45 GLN A NE2 1
ATOM 353 N ? 16.868 23.551 44.670 1.00 18.48 ? 46 GLU A N 1
ATOM 354 C ? 16.441 23.718 46.062 1.00 21.26 ? 46 GLU A CA 1
ATOM 355 C ? 15.108 23.004 46.105 1.00 19.06 ? 46 GLU A C 1
ATOM 356 O ? 14.080 23.589 45.784 1.00 20.08 ? 46 GLU A O 1
ATOM 357 C ? 16.239 25.194 46.408 1.00 26.45 ? 46 GLU A CB 1
ATOM 358 C ? 17.284 25.787 47.361 1.00 37.46 ? 46 GLU A CG 1
ATOM 359 C ? 17.093 25.374 48.832 1.00 42.24 ? 46 GLU A CD 1
ATOM 360 O ? 16.192 25.944 49.501 1.00 44.05 ? 46 GLU A OE1 1
ATOM 361 O ? 17.867 24.507 49.320 1.00 44.14 ? 46 GLU A OE2 1
ATOM 362 N ? 15.131 21.720 46.429 1.00 18.35 ? 47 GLY A N 1
ATOM 363 C ? 13.893 20.970 46.463 1.00 18.96 ? 47 GLY A CA 1
ATOM 364 C ? 13.382 20.755 45.053 1.00 18.27 ? 47 GLY A C 1
ATOM 365 O ? 14.067 20.157 44.238 1.00 18.05 ? 47 GLY A O 1
ATOM 366 N ? 12.194 21.262 44.755 1.00 16.66 ? 48 ASP A N 1
ATOM 367 C ? 11.617 21.107 43.420 1.00 16.86 ? 48 ASP A CA 1
ATOM 368 C ? 11.771 22.378 42.566 1.00 15.92 ? 48 ASP A C 1
ATOM 369 O ? 11.139 22.511 41.504 1.00 14.50 ? 48 ASP A O 1
ATOM 370 C ? 10.136 20.694 43.513 1.00 19.00 ? 48 ASP A CB 1
ATOM 371 C ? 9.943 19.221 43.897 1.00 21.49 ? 48 ASP A CG 1
ATOM 372 O ? 10.901 18.406 43.840 1.00 23.51 ? 48 ASP A OD1 1
ATOM 373 O ? 8.802 18.868 44.243 1.00 25.04 ? 48 ASP A OD2 1
ATOM 374 N ? 12.610 23.299 43.042 1.00 13.75 ? 49 THR A N 1
ATOM 375 C ? 12.870 24.551 42.348 1.00 13.82 ? 49 THR A CA 1
ATOM 376 C ? 14.231 24.460 41.678 1.00 13.22 ? 49 THR A C 1
ATOM 377 O ? 15.235 24.152 42.322 1.00 12.56 ? 49 THR A O 1
ATOM 378 C ? 12.847 25.741 43.316 1.00 16.10 ? 49 THR A CB 1
ATOM 379 O ? 11.556 25.815 43.941 1.00 17.94 ? 49 THR A OG1 1
ATOM 380 C ? 13.100 27.037 42.571 1.00 16.15 ? 49 THR A CG2 1
ATOM 381 N ? 14.266 24.794 40.392 1.00 12.20 ? 50 PHE A N 1
ATOM 382 C ? 15.485 24.704 39.602 1.00 10.82 ? 50 PHE A CA 1
ATOM 383 C ? 15.842 25.979 38.855 1.00 10.40 ? 50 PHE A C 1
ATOM 384 O ? 14.968 26.758 38.460 1.00 9.90 ? 50 PHE A O 1
ATOM 385 C ? 15.338 23.591 38.547 1.00 10.78 ? 50 PHE A CB 1
ATOM 386 C ? 15.316 22.192 39.107 1.00 13.13 ? 50 PHE A CG 1
ATOM 387 C ? 14.146 21.653 39.634 1.00 11.97 ? 50 PHE A CD1 1
ATOM 388 C ? 16.464 21.401 39.079 1.00 14.34 ? 50 PHE A CD2 1
ATOM 389 C ? 14.113 20.367 40.120 1.00 12.69 ? 50 PHE A CE1 1
ATOM 390 C ? 16.439 20.098 39.569 1.00 14.64 ? 50 PHE A CE2 1
ATOM 391 C ? 15.258 19.582 40.092 1.00 13.15 ? 50 PHE A CZ 1
ATOM 392 N ? 17.147 26.165 38.678 1.00 10.37 ? 51 TYR A N 1
ATOM 393 C ? 17.709 27.258 37.910 1.00 10.95 ? 51 TYR A CA 1
ATOM 394 C ? 18.714 26.513 37.039 1.00 9.84 ? 51 TYR A C 1
ATOM 395 O ? 19.540 25.761 37.547 1.00 9.78 ? 51 TYR A O 1
ATOM 396 C ? 18.436 28.284 38.790 1.00 12.57 ? 51 TYR A CB 1
ATOM 397 C ? 19.396 29.178 38.014 1.00 12.91 ? 51 TYR A CG 1
ATOM 398 C ? 18.939 30.302 37.327 1.00 15.83 ? 51 TYR A CD1 1
ATOM 399 C ? 20.762 28.896 37.974 1.00 14.05 ? 51 TYR A CD2 1
ATOM 400 C ? 19.822 31.126 36.621 1.00 16.52 ? 51 TYR A CE1 1
ATOM 401 C ? 21.655 29.705 37.275 1.00 14.62 ? 51 TYR A CE2 1
ATOM 402 C ? 21.179 30.818 36.604 1.00 16.59 ? 51 TYR A CZ 1
ATOM 403 O ? 22.060 31.633 35.932 1.00 17.52 ? 51 TYR A OH 1
ATOM 404 N ? 18.610 26.676 35.726 1.00 10.57 ? 52 ILE A N 1
ATOM 405 C ? 19.520 26.004 34.801 1.00 9.09 ? 52 ILE A CA 1
ATOM 406 C ? 20.066 27.020 33.801 1.00 8.55 ? 52 ILE A C 1
ATOM 407 O ? 19.296 27.652 33.086 1.00 10.49 ? 52 ILE A O 1
ATOM 408 C ? 18.807 24.859 34.026 1.00 8.96 ? 52 ILE A CB 1
ATOM 409 C ? 18.242 23.814 35.013 1.00 9.15 ? 52 ILE A CG1 1
ATOM 410 C ? 19.792 24.189 33.070 1.00 10.39 ? 52 ILE A CG2 1
ATOM 411 C ? 17.585 22.616 34.366 1.00 8.10 ? 52 ILE A CD1 1
ATOM 412 N ? 21.388 27.197 33.791 1.00 8.61 ? 53 LYS A N 1
ATOM 413 C ? 22.049 28.115 32.868 1.00 9.66 ? 53 LYS A CA 1
ATOM 414 C ? 22.939 27.319 31.924 1.00 8.71 ? 53 LYS A C 1
ATOM 415 O ? 23.815 26.583 32.362 1.00 7.58 ? 53 LYS A O 1
ATOM 416 C ? 22.909 29.120 33.611 1.00 10.60 ? 53 LYS A CB 1
ATOM 417 C ? 23.580 30.135 32.688 1.00 14.21 ? 53 LYS A CG 1
ATOM 418 C ? 24.496 31.006 33.505 1.00 20.27 ? 53 LYS A CD 1
ATOM 419 C ? 24.831 32.319 32.828 1.00 26.91 ? 53 LYS A CE 1
ATOM 420 N ? 25.878 33.009 33.659 1.00 29.12 ? 53 LYS A NZ 1
ATOM 421 N ? 22.686 27.445 30.625 1.00 8.49 ? 54 THR A N 1
ATOM 422 C ? 23.478 26.747 29.628 1.00 7.98 ? 54 THR A CA 1
ATOM 423 C ? 24.118 27.820 28.764 1.00 8.23 ? 54 THR A C 1
ATOM 424 O ? 23.433 28.584 28.087 1.00 8.40 ? 54 THR A O 1
ATOM 425 C ? 22.621 25.817 28.789 1.00 8.33 ? 54 THR A CB 1
ATOM 426 O ? 21.896 24.946 29.660 1.00 9.95 ? 54 THR A OG1 1
ATOM 427 C ? 23.505 24.976 27.873 1.00 4.95 ? 54 THR A CG2 1
ATOM 428 N ? 25.444 27.840 28.758 1.00 8.75 ? 55 SER A N 1
ATOM 429 C ? 26.171 28.865 28.047 1.00 10.50 ? 55 SER A CA 1
ATOM 430 C ? 27.116 28.382 26.950 1.00 9.24 ? 55 SER A C 1
ATOM 431 O ? 27.802 27.370 27.101 1.00 8.98 ? 55 SER A O 1
ATOM 432 C ? 26.934 29.694 29.082 1.00 13.09 ? 55 SER A CB 1
ATOM 433 O ? 27.781 30.646 28.473 1.00 23.11 ? 55 SER A OG 1
ATOM 434 N ? 27.091 29.094 25.825 1.00 8.86 ? 56 THR A N 1
ATOM 435 C ? 27.978 28.831 24.684 1.00 8.05 ? 56 THR A CA 1
ATOM 436 C ? 28.393 30.215 24.138 1.00 8.09 ? 56 THR A C 1
ATOM 437 O ? 27.834 31.237 24.525 1.00 7.17 ? 56 THR A O 1
ATOM 438 C ? 27.296 28.024 23.534 1.00 6.70 ? 56 THR A CB 1
ATOM 439 O ? 26.294 28.829 22.909 1.00 9.76 ? 56 THR A OG1 1
ATOM 440 C ? 26.653 26.751 24.049 1.00 7.76 ? 56 THR A CG2 1
ATOM 441 N ? 29.381 30.242 23.249 1.00 9.17 ? 57 THR A N 1
ATOM 442 C ? 29.871 31.485 22.644 1.00 8.49 ? 57 THR A CA 1
ATOM 443 C ? 28.820 32.222 21.802 1.00 7.50 ? 57 THR A C 1
ATOM 444 O ? 28.952 33.412 21.565 1.00 9.40 ? 57 THR A O 1
ATOM 445 C ? 31.091 31.205 21.716 1.00 9.12 ? 57 THR A CB 1
ATOM 446 O ? 30.758 30.171 20.786 1.00 9.41 ? 57 THR A OG1 1
ATOM 447 C ? 32.297 30.775 22.516 1.00 11.48 ? 57 THR A CG2 1
ATOM 448 N ? 27.786 31.510 21.356 1.00 8.04 ? 58 VAL A N 1
ATOM 449 C ? 26.733 32.090 20.500 1.00 9.09 ? 58 VAL A CA 1
ATOM 450 C ? 25.328 32.224 21.102 1.00 8.67 ? 58 VAL A C 1
ATOM 451 O ? 24.466 32.892 20.531 1.00 6.97 ? 58 VAL A O 1
ATOM 452 C ? 26.602 31.287 19.155 1.00 9.96 ? 58 VAL A CB 1
ATOM 453 C ? 27.976 31.161 18.454 1.00 11.08 ? 58 VAL A CG1 1
ATOM 454 C ? 26.010 29.890 19.404 1.00 9.41 ? 58 VAL A CG2 1
ATOM 455 N ? 25.100 31.620 22.266 1.00 8.88 ? 59 ARG A N 1
ATOM 456 C ? 23.783 31.655 22.882 1.00 9.95 ? 59 ARG A CA 1
ATOM 457 C ? 23.843 31.140 24.303 1.00 10.14 ? 59 ARG A C 1
ATOM 458 O ? 24.440 30.108 24.556 1.00 10.10 ? 59 ARG A O 1
ATOM 459 C ? 22.837 30.751 22.074 1.00 13.11 ? 59 ARG A CB 1
ATOM 460 C ? 21.417 30.569 22.623 1.00 16.80 ? 59 ARG A CG 1
ATOM 461 C ? 20.521 29.961 21.535 1.00 18.74 ? 59 ARG A CD 1
ATOM 462 N ? 19.250 29.440 22.032 1.00 20.63 ? 59 ARG A NE 1
ATOM 463 C ? 18.147 30.165 22.193 1.00 22.94 ? 59 ARG A CZ 1
ATOM 464 N ? 18.138 31.462 21.894 1.00 22.55 ? 59 ARG A NH1 1
ATOM 465 N ? 17.051 29.594 22.686 1.00 23.68 ? 59 ARG A NH2 1
ATOM 466 N ? 23.183 31.849 25.211 1.00 11.23 ? 60 THR A N 1
ATOM 467 C ? 23.120 31.458 26.611 1.00 11.84 ? 60 THR A CA 1
ATOM 468 C ? 21.650 31.500 27.005 1.00 11.73 ? 60 THR A C 1
ATOM 469 O ? 20.934 32.423 26.620 1.00 13.69 ? 60 THR A O 1
ATOM 470 C ? 23.916 32.451 27.519 1.00 10.13 ? 60 THR A CB 1
ATOM 471 O ? 25.320 32.302 27.276 1.00 10.55 ? 60 THR A OG1 1
ATOM 472 C ? 23.632 32.181 29.003 1.00 11.01 ? 60 THR A CG2 1
ATOM 473 N ? 21.183 30.470 27.706 1.00 11.78 ? 61 THR A N 1
ATOM 474 C ? 19.797 30.413 28.175 1.00 11.54 ? 61 THR A CA 1
ATOM 475 C ? 19.831 30.214 29.686 1.00 10.88 ? 61 THR A C 1
ATOM 476 O ? 20.734 29.570 30.205 1.00 9.63 ? 61 THR A O 1
ATOM 477 C ? 18.965 29.229 27.539 1.00 12.65 ? 61 THR A CB 1
ATOM 478 O ? 19.563 27.976 27.874 1.00 14.13 ? 61 THR A OG1 1
ATOM 479 C ? 18.889 29.336 26.012 1.00 14.15 ? 61 THR A CG2 1
ATOM 480 N ? 18.878 30.828 30.382 1.00 12.14 ? 62 GLU A N 1
ATOM 481 C ? 18.749 30.698 31.833 1.00 12.88 ? 62 GLU A CA 1
ATOM 482 C ? 17.283 30.444 32.100 1.00 12.21 ? 62 GLU A C 1
ATOM 483 O ? 16.450 31.270 31.745 1.00 13.95 ? 62 GLU A O 1
ATOM 484 C ? 19.151 31.990 32.538 1.00 16.15 ? 62 GLU A CB 1
ATOM 485 C ? 20.585 32.344 32.326 1.00 23.65 ? 62 GLU A CG 1
ATOM 486 C ? 20.961 33.649 32.979 1.00 29.90 ? 62 GLU A CD 1
ATOM 487 O ? 20.969 33.703 34.229 1.00 31.84 ? 62 GLU A OE1 1
ATOM 488 O ? 21.258 34.616 32.236 1.00 33.89 ? 62 GLU A OE2 1
ATOM 489 N ? 16.943 29.292 32.657 1.00 10.43 ? 63 ILE A N 1
ATOM 490 C ? 15.548 29.021 32.946 1.00 11.02 ? 63 ILE A CA 1
ATOM 491 C ? 15.352 28.816 34.446 1.00 11.60 ? 63 ILE A C 1
ATOM 492 O ? 16.286 28.434 35.144 1.00 9.20 ? 63 ILE A O 1
ATOM 493 C ? 14.976 27.816 32.125 1.00 11.28 ? 63 ILE A CB 1
ATOM 494 C ? 15.717 26.519 32.431 1.00 10.60 ? 63 ILE A CG1 1
ATOM 495 C ? 15.020 28.129 30.638 1.00 11.62 ? 63 ILE A CG2 1
ATOM 496 C ? 15.126 25.293 31.720 1.00 13.40 ? 63 ILE A CD1 1
ATOM 497 N ? 14.184 29.219 34.933 1.00 12.13 ? 64 ASN A N 1
ATOM 498 C ? 13.824 29.083 36.343 1.00 14.79 ? 64 ASN A CA 1
ATOM 499 C ? 12.451 28.441 36.375 1.00 13.29 ? 64 ASN A C 1
ATOM 500 O ? 11.490 28.976 35.802 1.00 13.29 ? 64 ASN A O 1
ATOM 501 C ? 13.732 30.450 37.054 1.00 16.87 ? 64 ASN A CB 1
ATOM 502 C ? 15.079 31.089 37.279 1.00 20.91 ? 64 ASN A CG 1
ATOM 503 O ? 15.775 30.764 38.238 1.00 22.91 ? 64 ASN A OD1 1
ATOM 504 N ? 15.459 32.007 36.393 1.00 22.20 ? 64 ASN A ND2 1
ATOM 505 N ? 12.347 27.301 37.044 1.00 12.90 ? 65 PHE A N 1
ATOM 506 C ? 11.058 26.641 37.132 1.00 12.63 ? 65 PHE A CA 1
ATOM 507 C ? 10.858 25.841 38.410 1.00 13.07 ? 65 PHE A C 1
ATOM 508 O ? 11.811 25.531 39.121 1.00 12.50 ? 65 PHE A O 1
ATOM 509 C ? 10.829 25.731 35.922 1.00 11.31 ? 65 PHE A CB 1
ATOM 510 C ? 11.794 24.586 35.825 1.00 12.32 ? 65 PHE A CG 1
ATOM 511 C ? 11.549 23.386 36.494 1.00 10.31 ? 65 PHE A CD1 1
ATOM 512 C ? 12.947 24.706 35.070 1.00 11.23 ? 65 PHE A CD2 1
ATOM 513 C ? 12.441 22.329 36.413 1.00 11.00 ? 65 PHE A CE1 1
ATOM 514 C ? 13.847 23.645 34.984 1.00 11.69 ? 65 PHE A CE2 1
ATOM 515 C ? 13.593 22.461 35.655 1.00 12.20 ? 65 PHE A CZ 1
ATOM 516 N ? 9.599 25.560 38.713 1.00 13.15 ? 66 LYS A N 1
ATOM 517 C ? 9.251 24.735 39.849 1.00 13.41 ? 66 LYS A CA 1
ATOM 518 C ? 8.555 23.552 39.178 1.00 12.17 ? 66 LYS A C 1
ATOM 519 O ? 7.763 23.747 38.251 1.00 12.93 ? 66 LYS A O 1
ATOM 520 C ? 8.313 25.498 40.800 1.00 16.68 ? 66 LYS A CB 1
ATOM 521 C ? 7.722 24.639 41.907 1.00 24.60 ? 66 LYS A CG 1
ATOM 522 C ? 7.391 25.453 43.165 1.00 28.53 ? 66 LYS A CD 1
ATOM 523 C ? 6.664 24.585 44.213 1.00 32.17 ? 66 LYS A CE 1
ATOM 524 N ? 7.393 23.332 44.604 1.00 32.54 ? 66 LYS A NZ 1
ATOM 525 N ? 8.918 22.329 39.562 1.00 11.82 ? 67 VAL A N 1
ATOM 526 C ? 8.295 21.141 38.975 1.00 10.93 ? 67 VAL A CA 1
ATOM 527 C ? 6.783 21.174 39.226 1.00 11.97 ? 67 VAL A C 1
ATOM 528 O ? 6.343 21.480 40.342 1.00 13.54 ? 67 VAL A O 1
ATOM 529 C ? 8.908 19.827 39.541 1.00 10.09 ? 67 VAL A CB 1
ATOM 530 C ? 8.271 18.617 38.883 1.00 10.96 ? 67 VAL A CG1 1
ATOM 531 C ? 10.410 19.808 39.320 1.00 10.21 ? 67 VAL A CG2 1
ATOM 532 N ? 6.006 20.965 38.160 1.00 9.80 ? 68 GLY A N 1
ATOM 533 C ? 4.557 20.962 38.265 1.00 9.33 ? 68 GLY A CA 1
ATOM 534 C ? 3.887 22.298 38.031 1.00 10.60 ? 68 GLY A C 1
ATOM 535 O ? 2.653 22.389 38.039 1.00 11.93 ? 68 GLY A O 1
ATOM 536 N ? 4.688 23.337 37.809 1.00 11.12 ? 69 GLU A N 1
ATOM 537 C ? 4.165 24.682 37.553 1.00 12.64 ? 69 GLU A CA 1
ATOM 538 C ? 4.604 25.185 36.184 1.00 13.09 ? 69 GLU A C 1
ATOM 539 O ? 5.774 25.107 35.820 1.00 12.17 ? 69 GLU A O 1
ATOM 540 C ? 4.578 25.642 38.668 1.00 12.20 ? 69 GLU A CB 1
ATOM 541 C ? 3.857 25.282 39.964 1.00 17.44 ? 69 GLU A CG 1
ATOM 542 C ? 4.116 26.211 41.138 1.00 21.02 ? 69 GLU A CD 1
ATOM 543 O ? 4.496 27.384 40.945 1.00 21.43 ? 69 GLU A OE1 1
ATOM 544 O ? 3.902 25.753 42.282 1.00 23.44 ? 69 GLU A OE2 1
ATOM 545 N ? 3.633 25.622 35.397 1.00 14.53 ? 70 GLU A N 1
ATOM 546 C ? 3.912 26.102 34.059 1.00 15.80 ? 70 GLU A CA 1
ATOM 547 C ? 4.816 27.329 34.007 1.00 13.72 ? 70 GLU A C 1
ATOM 548 O ? 4.761 28.208 34.863 1.00 13.66 ? 70 GLU A O 1
ATOM 549 C ? 2.606 26.359 33.320 1.00 19.99 ? 70 GLU A CB 1
ATOM 550 C ? 2.814 26.634 31.851 1.00 28.23 ? 70 GLU A CG 1
ATOM 551 C ? 1.518 26.678 31.097 1.00 32.73 ? 70 GLU A CD 1
ATOM 552 O ? 0.975 25.589 30.789 1.00 35.76 ? 70 GLU A OE1 1
ATOM 553 O ? 1.045 27.802 30.823 1.00 35.75 ? 70 GLU A OE2 1
ATOM 554 N ? 5.713 27.340 33.028 1.00 12.80 ? 71 PHE A N 1
ATOM 555 C ? 6.638 28.448 32.837 1.00 12.36 ? 71 PHE A CA 1
ATOM 556 C ? 6.856 28.678 31.350 1.00 12.97 ? 71 PHE A C 1
ATOM 557 O ? 6.382 27.917 30.516 1.00 12.54 ? 71 PHE A O 1
ATOM 558 C ? 7.975 28.243 33.589 1.00 10.02 ? 71 PHE A CB 1
ATOM 559 C ? 8.851 27.148 33.033 1.00 10.48 ? 71 PHE A CG 1
ATOM 560 C ? 8.549 25.815 33.256 1.00 9.95 ? 71 PHE A CD1 1
ATOM 561 C ? 10.006 27.459 32.331 1.00 9.29 ? 71 PHE A CD2 1
ATOM 562 C ? 9.380 24.811 32.793 1.00 9.74 ? 71 PHE A CE1 1
ATOM 563 C ? 10.832 26.464 31.868 1.00 9.51 ? 71 PHE A CE2 1
ATOM 564 C ? 10.518 25.136 32.102 1.00 8.47 ? 71 PHE A CZ 1
ATOM 565 N ? 7.581 29.733 31.028 1.00 15.04 ? 72 GLU A N 1
ATOM 566 C ? 7.826 30.063 29.644 1.00 17.19 ? 72 GLU A CA 1
ATOM 567 C ? 9.323 30.036 29.357 1.00 15.53 ? 72 GLU A C 1
ATOM 568 O ? 10.130 30.511 30.158 1.00 16.16 ? 72 GLU A O 1
ATOM 569 C ? 7.248 31.448 29.379 1.00 22.03 ? 72 GLU A CB 1
ATOM 570 C ? 6.700 31.658 28.002 1.00 30.80 ? 72 GLU A CG 1
ATOM 571 C ? 6.157 33.060 27.827 1.00 34.75 ? 72 GLU A CD 1
ATOM 572 O ? 5.014 33.309 28.276 1.00 35.88 ? 72 GLU A OE1 1
ATOM 573 O ? 6.885 33.912 27.255 1.00 38.91 ? 72 GLU A OE2 1
ATOM 574 N ? 9.691 29.378 28.263 1.00 13.46 ? 73 GLU A N 1
ATOM 575 C ? 11.088 29.302 27.836 1.00 13.89 ? 73 GLU A CA 1
ATOM 576 C ? 11.083 29.318 26.301 1.00 13.70 ? 73 GLU A C 1
ATOM 577 O ? 10.159 29.859 25.690 1.00 13.63 ? 73 GLU A O 1
ATOM 578 C ? 11.780 28.032 28.379 1.00 12.63 ? 73 GLU A CB 1
ATOM 579 C ? 11.145 26.706 27.986 1.00 10.55 ? 73 GLU A CG 1
ATOM 580 C ? 11.997 25.499 28.366 1.00 8.94 ? 73 GLU A CD 1
ATOM 581 O ? 13.191 25.650 28.642 1.00 12.29 ? 73 GLU A OE1 1
ATOM 582 O ? 11.485 24.374 28.363 1.00 10.37 ? 73 GLU A OE2 1
ATOM 583 N ? 12.115 28.751 25.685 1.00 13.09 ? 74 GLN A N 1
ATOM 584 C ? 12.187 28.691 24.239 1.00 13.16 ? 74 GLN A CA 1
ATOM 585 C ? 12.618 27.315 23.806 1.00 12.86 ? 74 GLN A C 1
ATOM 586 O ? 13.290 26.596 24.552 1.00 13.17 ? 74 GLN A O 1
ATOM 587 C ? 13.218 29.685 23.706 1.00 15.91 ? 74 GLN A CB 1
ATOM 588 C ? 12.803 31.133 23.779 1.00 19.68 ? 74 GLN A CG 1
ATOM 589 C ? 13.827 32.066 23.159 1.00 21.00 ? 74 GLN A CD 1
ATOM 590 O ? 15.010 31.730 23.024 1.00 22.37 ? 74 GLN A OE1 1
ATOM 591 N ? 13.373 33.247 22.774 1.00 24.07 ? 74 GLN A NE2 1
ATOM 592 N ? 12.229 26.935 22.600 1.00 10.98 ? 75 THR A N 1
ATOM 593 C ? 12.664 25.656 22.056 1.00 11.83 ? 75 THR A CA 1
ATOM 594 C ? 14.162 25.828 21.729 1.00 11.24 ? 75 THR A C 1
ATOM 595 O ? 14.681 26.951 21.764 1.00 9.95 ? 75 THR A O 1
ATOM 596 C ? 11.895 25.325 20.757 1.00 11.93 ? 75 THR A CB 1
ATOM 597 O ? 12.123 26.366 19.795 1.00 13.31 ? 75 THR A OG1 1
ATOM 598 C ? 10.396 25.202 21.042 1.00 13.29 ? 75 THR A CG2 1
ATOM 599 N ? 14.841 24.731 21.377 1.00 13.77 ? 76 VAL A N 1
ATOM 600 C ? 16.278 24.762 21.049 1.00 14.39 ? 76 VAL A CA 1
ATOM 601 C ? 16.612 25.734 19.914 1.00 12.97 ? 76 VAL A C 1
ATOM 602 O ? 17.639 26.407 19.956 1.00 13.75 ? 76 VAL A O 1
ATOM 603 C ? 16.827 23.351 20.680 1.00 15.44 ? 76 VAL A CB 1
ATOM 604 C ? 18.332 23.314 20.844 1.00 17.74 ? 76 VAL A CG1 1
ATOM 605 C ? 16.218 22.293 21.548 1.00 19.99 ? 76 VAL A CG2 1
ATOM 606 N ? 15.730 25.824 18.921 1.00 13.67 ? 77 ASP A N 1
ATOM 607 C ? 15.933 26.727 17.789 1.00 14.47 ? 77 ASP A CA 1
ATOM 608 C ? 15.486 28.172 18.061 1.00 15.23 ? 77 ASP A C 1
ATOM 609 O ? 15.461 29.002 17.153 1.00 14.90 ? 77 ASP A O 1
ATOM 610 C ? 15.301 26.158 16.503 1.00 15.63 ? 77 ASP A CB 1
ATOM 611 C ? 13.790 26.007 16.585 1.00 15.92 ? 77 ASP A CG 1
ATOM 612 O ? 13.260 25.470 17.586 1.00 14.64 ? 77 ASP A OD1 1
ATOM 613 O ? 13.123 26.409 15.613 1.00 17.79 ? 77 ASP A OD2 1
ATOM 614 N ? 15.095 28.445 19.312 1.00 15.17 ? 78 GLY A N 1
ATOM 615 C ? 14.709 29.790 19.726 1.00 15.90 ? 78 GLY A CA 1
ATOM 616 C ? 13.268 30.281 19.701 1.00 16.89 ? 78 GLY A C 1
ATOM 617 O ? 13.038 31.489 19.790 1.00 19.37 ? 78 GLY A O 1
ATOM 618 N ? 12.292 29.389 19.620 1.00 16.76 ? 79 ARG A N 1
ATOM 619 C ? 10.896 29.822 19.587 1.00 18.08 ? 79 ARG A CA 1
ATOM 620 C ? 10.229 29.768 20.961 1.00 16.55 ? 79 ARG A C 1
ATOM 621 O ? 10.379 28.787 21.680 1.00 16.57 ? 79 ARG A O 1
ATOM 622 C ? 10.112 28.961 18.604 1.00 20.74 ? 79 ARG A CB 1
ATOM 623 C ? 10.667 28.997 17.194 1.00 25.89 ? 79 ARG A CG 1
ATOM 624 C ? 9.986 27.976 16.310 1.00 29.77 ? 79 ARG A CD 1
ATOM 625 N ? 10.144 26.626 16.842 1.00 34.52 ? 79 ARG A NE 1
ATOM 626 C ? 10.128 25.516 16.109 1.00 35.90 ? 79 ARG A CZ 1
ATOM 627 N ? 9.971 25.580 14.789 1.00 37.70 ? 79 ARG A NH1 1
ATOM 628 N ? 10.266 24.337 16.702 1.00 35.58 ? 79 ARG A NH2 1
ATOM 629 N ? 9.501 30.830 21.352 1.00 15.98 ? 80 PRO A N 1
ATOM 630 C ? 8.819 30.867 22.651 1.00 15.47 ? 80 PRO A CA 1
ATOM 631 C ? 7.825 29.725 22.833 1.00 14.23 ? 80 PRO A C 1
ATOM 632 O ? 7.058 29.393 21.926 1.00 14.56 ? 80 PRO A O 1
ATOM 633 C ? 8.100 32.220 22.628 1.00 15.48 ? 80 PRO A CB 1
ATOM 634 C ? 9.010 33.057 21.846 1.00 18.18 ? 80 PRO A CG 1
ATOM 635 C ? 9.418 32.145 20.696 1.00 17.08 ? 80 PRO A CD 1
ATOM 636 N ? 7.817 29.148 24.028 1.00 13.52 ? 81 CYS A N 1
ATOM 637 C ? 6.914 28.055 24.331 1.00 12.41 ? 81 CYS A CA 1
ATOM 638 C ? 6.548 28.054 25.811 1.00 12.52 ? 81 CYS A C 1
ATOM 639 O ? 7.202 28.718 26.624 1.00 11.74 ? 81 CYS A O 1
ATOM 640 C ? 7.563 26.705 23.950 1.00 11.59 ? 81 CYS A CB 1
ATOM 641 S ? 9.063 26.255 24.894 1.00 12.86 ? 81 CYS A SG 1
ATOM 642 N ? 5.448 27.379 26.121 1.00 13.86 ? 82 LYS A N 1
ATOM 643 C ? 4.988 27.197 27.492 1.00 14.38 ? 82 LYS A CA 1
ATOM 644 C ? 5.436 25.779 27.839 1.00 13.51 ? 82 LYS A C 1
ATOM 645 O ? 5.227 24.842 27.063 1.00 12.69 ? 82 LYS A O 1
ATOM 646 C ? 3.473 27.299 27.589 1.00 18.36 ? 82 LYS A CB 1
ATOM 647 C ? 2.940 28.716 27.584 1.00 26.02 ? 82 LYS A CG 1
ATOM 648 C ? 3.353 29.506 28.826 1.00 31.13 ? 82 LYS A CD 1
ATOM 649 C ? 2.686 30.894 28.832 1.00 35.39 ? 82 LYS A CE 1
ATOM 650 N ? 2.868 31.652 30.120 1.00 37.63 ? 82 LYS A NZ 1
ATOM 651 N ? 6.110 25.638 28.974 1.00 11.15 ? 83 SER A N 1
ATOM 652 C ? 6.624 24.352 29.397 1.00 10.10 ? 83 SER A CA 1
ATOM 653 C ? 6.083 23.931 30.752 1.00 11.16 ? 83 SER A C 1
ATOM 654 O ? 5.721 24.769 31.575 1.00 10.21 ? 83 SER A O 1
ATOM 655 C ? 8.149 24.418 29.446 1.00 10.30 ? 83 SER A CB 1
ATOM 656 O ? 8.686 24.518 28.132 1.00 11.50 ? 83 SER A OG 1
ATOM 657 N ? 6.028 22.620 30.954 1.00 11.17 ? 84 LEU A N 1
ATOM 658 C ? 5.557 22.016 32.192 1.00 11.84 ? 84 LEU A CA 1
ATOM 659 C ? 6.427 20.793 32.470 1.00 10.42 ? 84 LEU A C 1
ATOM 660 O ? 6.444 19.846 31.684 1.00 11.20 ? 84 LEU A O 1
ATOM 661 C ? 4.091 21.576 32.067 1.00 13.44 ? 84 LEU A CB 1
ATOM 662 C ? 3.552 20.784 33.270 1.00 15.74 ? 84 LEU A CG 1
ATOM 663 C ? 3.515 21.683 34.484 1.00 16.96 ? 84 LEU A CD1 1
ATOM 664 C ? 2.178 20.231 32.982 1.00 18.76 ? 84 LEU A CD2 1
ATOM 665 N ? 7.146 20.828 33.589 1.00 9.60 ? 85 VAL A N 1
ATOM 666 C ? 8.028 19.738 34.006 1.00 9.50 ? 85 VAL A CA 1
ATOM 667 C ? 7.344 18.878 35.082 1.00 9.74 ? 85 VAL A C 1
ATOM 668 O ? 6.680 19.404 35.985 1.00 9.28 ? 85 VAL A O 1
ATOM 669 C ? 9.384 20.291 34.598 1.00 8.89 ? 85 VAL A CB 1
ATOM 670 C ? 10.327 19.140 34.970 1.00 8.20 ? 85 VAL A CG1 1
ATOM 671 C ? 10.062 21.227 33.612 1.00 8.48 ? 85 VAL A CG2 1
ATOM 672 N ? 7.504 17.563 34.971 1.00 9.96 ? 86 LYS A N 1
ATOM 673 C ? 6.946 16.621 35.945 1.00 11.92 ? 86 LYS A CA 1
ATOM 674 C ? 8.003 15.558 36.247 1.00 11.88 ? 86 LYS A C 1
ATOM 675 O ? 8.917 15.340 35.453 1.00 11.00 ? 86 LYS A O 1
ATOM 676 C ? 5.700 15.911 35.385 1.00 12.40 ? 86 LYS A CB 1
ATOM 677 C ? 4.538 16.819 35.058 1.00 16.01 ? 86 LYS A CG 1
ATOM 678 C ? 3.333 16.017 34.559 1.00 21.36 ? 86 LYS A CD 1
ATOM 679 C ? 2.140 16.939 34.345 1.00 23.23 ? 86 LYS A CE 1
ATOM 680 N ? 0.919 16.212 33.929 1.00 28.41 ? 86 LYS A NZ 1
ATOM 681 N ? 7.868 14.889 37.386 1.00 10.75 ? 87 TRP A N 1
ATOM 682 C ? 8.775 13.811 37.738 1.00 9.53 ? 87 TRP A CA 1
ATOM 683 C ? 8.238 12.559 37.052 1.00 9.89 ? 87 TRP A C 1
ATOM 684 O ? 7.144 12.107 37.370 1.00 11.80 ? 87 TRP A O 1
ATOM 685 C ? 8.791 13.569 39.268 1.00 8.76 ? 87 TRP A CB 1
ATOM 686 C ? 9.494 14.641 40.062 1.00 8.86 ? 87 TRP A CG 1
ATOM 687 C ? 8.923 15.525 40.939 1.00 8.80 ? 87 TRP A CD1 1
ATOM 688 C ? 10.889 14.990 39.992 1.00 9.42 ? 87 TRP A CD2 1
ATOM 689 N ? 9.872 16.410 41.400 1.00 8.01 ? 87 TRP A NE1 1
ATOM 690 C ? 11.086 16.103 40.835 1.00 10.85 ? 87 TRP A CE2 1
ATOM 691 C ? 11.985 14.475 39.283 1.00 9.60 ? 87 TRP A CE3 1
ATOM 692 C ? 12.340 16.716 40.994 1.00 11.45 ? 87 TRP A CZ2 1
ATOM 693 C ? 13.230 15.084 39.438 1.00 10.72 ? 87 TRP A CZ3 1
ATOM 694 C ? 13.395 16.192 40.289 1.00 11.78 ? 87 TRP A CH2 1
ATOM 695 N ? 8.954 12.040 36.064 1.00 9.93 ? 88 GLU A N 1
ATOM 696 C ? 8.526 10.807 35.416 1.00 11.30 ? 88 GLU A CA 1
ATOM 697 C ? 8.826 9.726 36.448 1.00 11.75 ? 88 GLU A C 1
ATOM 698 O ? 8.068 8.784 36.623 1.00 12.78 ? 88 GLU A O 1
ATOM 699 C ? 9.337 10.541 34.156 1.00 13.50 ? 88 GLU A CB 1
ATOM 700 C ? 8.917 9.261 33.454 1.00 18.67 ? 88 GLU A CG 1
ATOM 701 C ? 9.756 8.958 32.226 1.00 23.49 ? 88 GLU A CD 1
ATOM 702 O ? 9.581 9.650 31.205 1.00 26.53 ? 88 GLU A OE1 1
ATOM 703 O ? 10.587 8.025 32.276 1.00 26.54 ? 88 GLU A OE2 1
ATOM 704 N ? 9.972 9.870 37.103 1.00 11.49 ? 89 SER A N 1
ATOM 705 C ? 10.402 8.954 38.158 1.00 11.10 ? 89 SER A CA 1
ATOM 706 C ? 11.206 9.776 39.163 1.00 11.14 ? 89 SER A C 1
ATOM 707 O ? 11.397 10.983 38.979 1.00 9.92 ? 89 SER A O 1
ATOM 708 C ? 11.221 7.778 37.604 1.00 12.43 ? 89 SER A CB 1
ATOM 709 O ? 12.396 8.215 36.947 1.00 14.39 ? 89 SER A OG 1
ATOM 710 N ? 11.674 9.130 40.227 1.00 10.17 ? 90 GLU A N 1
ATOM 711 C ? 12.433 9.826 41.254 1.00 10.83 ? 90 GLU A CA 1
ATOM 712 C ? 13.657 10.629 40.772 1.00 9.86 ? 90 GLU A C 1
ATOM 713 O ? 13.932 11.715 41.289 1.00 10.30 ? 90 GLU A O 1
ATOM 714 C ? 12.858 8.846 42.348 1.00 11.92 ? 90 GLU A CB 1
ATOM 715 C ? 13.536 9.572 43.487 1.00 16.53 ? 90 GLU A CG 1
ATOM 716 C ? 13.912 8.671 44.644 1.00 19.80 ? 90 GLU A CD 1
ATOM 717 O ? 14.122 7.464 44.426 1.00 21.18 ? 90 GLU A OE1 1
ATOM 718 O ? 14.012 9.187 45.774 1.00 22.91 ? 90 GLU A OE2 1
ATOM 719 N ? 14.376 10.102 39.783 1.00 8.79 ? 91 ASN A N 1
ATOM 720 C ? 15.578 10.767 39.274 1.00 10.50 ? 91 ASN A CA 1
ATOM 721 C ? 15.455 11.289 37.855 1.00 9.69 ? 91 ASN A C 1
ATOM 722 O ? 16.467 11.627 37.246 1.00 7.10 ? 91 ASN A O 1
ATOM 723 C ? 16.760 9.798 39.305 1.00 14.33 ? 91 ASN A CB 1
ATOM 724 C ? 17.064 9.307 40.693 1.00 17.71 ? 91 ASN A CG 1
ATOM 725 O ? 17.445 10.087 41.560 1.00 20.87 ? 91 ASN A OD1 1
ATOM 726 N ? 16.855 8.016 40.928 1.00 19.39 ? 91 ASN A ND2 1
ATOM 727 N ? 14.230 11.387 37.352 1.00 8.60 ? 92 LYS A N 1
ATOM 728 C ? 14.016 11.835 35.981 1.00 8.88 ? 92 LYS A CA 1
ATOM 729 C ? 12.861 12.812 35.807 1.00 8.61 ? 92 LYS A C 1
ATOM 730 O ? 11.721 12.511 36.168 1.00 8.95 ? 92 LYS A O 1
ATOM 731 C ? 13.781 10.626 35.078 1.00 9.10 ? 92 LYS A CB 1
ATOM 732 C ? 13.566 10.996 33.618 1.00 11.95 ? 92 LYS A CG 1
ATOM 733 C ? 13.467 9.762 32.759 1.00 14.04 ? 92 LYS A CD 1
ATOM 734 C ? 13.333 10.124 31.299 1.00 16.33 ? 92 LYS A CE 1
ATOM 735 N ? 13.129 8.884 30.506 1.00 17.37 ? 92 LYS A NZ 1
ATOM 736 N ? 13.172 13.988 35.268 1.00 7.58 ? 93 MET A N 1
ATOM 737 C ? 12.159 14.985 34.995 1.00 8.21 ? 93 MET A CA 1
ATOM 738 C ? 11.915 15.038 33.496 1.00 9.18 ? 93 MET A C 1
ATOM 739 O ? 12.833 14.838 32.690 1.00 7.74 ? 93 MET A O 1
ATOM 740 C ? 12.565 16.359 35.523 1.00 9.68 ? 93 MET A CB 1
ATOM 741 C ? 13.826 16.925 34.937 1.00 13.16 ? 93 MET A CG 1
ATOM 742 S ? 14.238 18.543 35.628 1.00 17.49 ? 93 MET A SD 1
ATOM 743 C ? 15.009 18.106 37.076 1.00 18.53 ? 93 MET A CE 1
ATOM 744 N ? 10.658 15.239 33.128 1.00 9.48 ? 94 VAL A N 1
ATOM 745 C ? 10.266 15.334 31.726 1.00 9.55 ? 94 VAL A CA 1
ATOM 746 C ? 9.516 16.639 31.528 1.00 10.10 ? 94 VAL A C 1
ATOM 747 O ? 8.683 17.024 32.364 1.00 9.47 ? 94 VAL A O 1
ATOM 748 C ? 9.371 14.164 31.315 1.00 11.05 ? 94 VAL A CB 1
ATOM 749 C ? 8.878 14.354 29.878 1.00 12.88 ? 94 VAL A CG1 1
ATOM 750 C ? 10.147 12.866 31.420 1.00 14.00 ? 94 VAL A CG2 1
ATOM 751 N ? 9.802 17.312 30.413 1.00 9.49 ? 95 CYS A N 1
ATOM 752 C ? 9.169 18.582 30.094 1.00 8.82 ? 95 CYS A CA 1
ATOM 753 C ? 8.431 18.559 28.758 1.00 11.70 ? 95 CYS A C 1
ATOM 754 O ? 9.014 18.215 27.723 1.00 12.29 ? 95 CYS A O 1
ATOM 755 C ? 10.229 19.679 30.059 1.00 8.79 ? 95 CYS A CB 1
ATOM 756 S ? 9.620 21.322 29.690 1.00 10.97 ? 95 CYS A SG 1
ATOM 757 N ? 7.149 18.902 28.791 1.00 10.87 ? 96 GLU A N 1
ATOM 758 C ? 6.342 18.962 27.587 1.00 14.78 ? 96 GLU A CA 1
ATOM 759 C ? 6.267 20.439 27.182 1.00 13.83 ? 96 GLU A C 1
ATOM 760 O ? 6.044 21.311 28.030 1.00 12.79 ? 96 GLU A O 1
ATOM 761 C ? 4.957 18.397 27.885 1.00 20.21 ? 96 GLU A CB 1
ATOM 762 C ? 3.981 18.432 26.726 1.00 32.46 ? 96 GLU A CG 1
ATOM 763 C ? 2.646 17.765 27.065 1.00 38.97 ? 96 GLU A CD 1
ATOM 764 O ? 2.053 18.108 28.128 1.00 42.61 ? 96 GLU A OE1 1
ATOM 765 O ? 2.201 16.892 26.271 1.00 42.17 ? 96 GLU A OE2 1
ATOM 766 N ? 6.513 20.725 25.903 1.00 13.39 ? 97 GLN A N 1
ATOM 767 C ? 6.489 22.100 25.402 1.00 13.55 ? 97 GLN A CA 1
ATOM 768 C ? 5.357 22.334 24.400 1.00 15.88 ? 97 GLN A C 1
ATOM 769 O ? 5.013 21.455 23.591 1.00 16.25 ? 97 GLN A O 1
ATOM 770 C ? 7.823 22.465 24.747 1.00 12.20 ? 97 GLN A CB 1
ATOM 771 C ? 9.033 22.324 25.650 1.00 12.55 ? 97 GLN A CG 1
ATOM 772 C ? 10.321 22.613 24.927 1.00 14.20 ? 97 GLN A CD 1
ATOM 773 O ? 10.478 22.288 23.749 1.00 12.94 ? 97 GLN A OE1 1
ATOM 774 N ? 11.260 23.235 25.627 1.00 14.75 ? 97 GLN A NE2 1
ATOM 775 N ? 4.801 23.541 24.450 1.00 17.30 ? 98 LYS A N 1
ATOM 776 C ? 3.696 23.952 23.582 1.00 19.78 ? 98 LYS A CA 1
ATOM 777 C ? 3.990 25.340 23.019 1.00 18.56 ? 98 LYS A C 1
ATOM 778 O ? 4.162 26.293 23.771 1.00 17.70 ? 98 LYS A O 1
ATOM 779 C ? 2.389 23.953 24.389 1.00 23.30 ? 98 LYS A CB 1
ATOM 780 C ? 1.294 24.857 23.867 1.00 30.94 ? 98 LYS A CG 1
ATOM 781 C ? 0.210 25.047 24.934 1.00 37.10 ? 98 LYS A CD 1
ATOM 782 C ? -0.849 26.072 24.520 1.00 39.73 ? 98 LYS A CE 1
ATOM 783 N ? -0.326 27.476 24.541 1.00 42.46 ? 98 LYS A NZ 1
ATOM 784 N ? 4.073 25.445 21.696 1.00 19.35 ? 99 LEU A N 1
ATOM 785 C ? 4.357 26.721 21.041 1.00 21.32 ? 99 LEU A CA 1
ATOM 786 C ? 3.307 27.770 21.351 1.00 22.86 ? 99 LEU A C 1
ATOM 787 O ? 2.108 27.496 21.261 1.00 23.41 ? 99 LEU A O 1
ATOM 788 C ? 4.466 26.542 19.526 1.00 22.09 ? 99 LEU A CB 1
ATOM 789 C ? 5.692 25.792 18.997 1.00 22.72 ? 99 LEU A CG 1
ATOM 790 C ? 5.585 25.639 17.490 1.00 23.04 ? 99 LEU A CD1 1
ATOM 791 C ? 6.951 26.548 19.372 1.00 23.61 ? 99 LEU A CD2 1
ATOM 792 N ? 3.767 28.962 21.722 1.00 24.11 ? 100 LEU A N 1
ATOM 793 C ? 2.879 30.070 22.051 1.00 27.59 ? 100 LEU A CA 1
ATOM 794 C ? 2.130 30.545 20.815 1.00 30.94 ? 100 LEU A C 1
ATOM 795 O ? 0.951 30.908 20.877 1.00 31.34 ? 100 LEU A O 1
ATOM 796 C ? 3.680 31.227 22.640 1.00 25.50 ? 100 LEU A CB 1
ATOM 797 C ? 4.254 30.947 24.020 1.00 24.80 ? 100 LEU A CG 1
ATOM 798 C ? 4.960 32.171 24.542 1.00 26.59 ? 100 LEU A CD1 1
ATOM 799 C ? 3.141 30.554 24.935 1.00 24.80 ? 100 LEU A CD2 1
ATOM 800 N ? 2.835 30.531 19.689 1.00 34.60 ? 101 LYS A N 1
ATOM 801 C ? 2.282 30.961 18.413 1.00 37.81 ? 101 LYS A CA 1
ATOM 802 C ? 2.847 30.088 17.292 1.00 37.39 ? 101 LYS A C 1
ATOM 803 O ? 4.019 29.687 17.319 1.00 37.22 ? 101 LYS A O 1
ATOM 804 C ? 2.653 32.429 18.147 1.00 40.57 ? 101 LYS A CB 1
ATOM 805 C ? 2.182 33.426 19.212 1.00 45.13 ? 101 LYS A CG 1
ATOM 806 C ? 2.955 34.741 19.125 1.00 48.57 ? 101 LYS A CD 1
ATOM 807 C ? 4.479 34.527 19.248 1.00 51.31 ? 101 LYS A CE 1
ATOM 808 N ? 4.917 33.952 20.559 1.00 51.14 ? 101 LYS A NZ 1
ATOM 809 N ? 1.997 29.786 16.318 1.00 37.21 ? 102 GLY A N 1
ATOM 810 C ? 2.423 28.993 15.184 1.00 36.82 ? 102 GLY A CA 1
ATOM 811 C ? 2.333 27.494 15.344 1.00 36.36 ? 102 GLY A C 1
ATOM 812 O ? 1.690 26.977 16.265 1.00 35.74 ? 102 GLY A O 1
ATOM 813 N ? 2.954 26.803 14.395 1.00 35.74 ? 103 GLU A N 1
ATOM 814 C ? 2.988 25.348 14.377 1.00 35.50 ? 103 GLU A CA 1
ATOM 815 C ? 4.418 24.880 14.140 1.00 31.92 ? 103 GLU A C 1
ATOM 816 O ? 5.281 25.654 13.723 1.00 31.61 ? 103 GLU A O 1
ATOM 817 C ? 2.077 24.784 13.274 1.00 39.37 ? 103 GLU A CB 1
ATOM 818 C ? 0.652 24.422 13.712 1.00 45.52 ? 103 GLU A CG 1
ATOM 819 C ? -0.383 25.503 13.395 1.00 50.23 ? 103 GLU A CD 1
ATOM 820 O ? -0.130 26.346 12.499 1.00 53.12 ? 103 GLU A OE1 1
ATOM 821 O ? -1.464 25.500 14.036 1.00 52.16 ? 103 GLU A OE2 1
ATOM 822 N ? 4.653 23.604 14.414 1.00 28.97 ? 104 GLY A N 1
ATOM 823 C ? 5.967 23.024 14.231 1.00 25.41 ? 104 GLY A CA 1
ATOM 824 C ? 6.012 21.648 14.863 1.00 22.09 ? 104 GLY A C 1
ATOM 825 O ? 4.987 21.160 15.347 1.00 21.89 ? 104 GLY A O 1
ATOM 826 N ? 7.176 20.976 14.832 1.00 19.50 ? 105 PRO A N 1
ATOM 827 C ? 7.338 19.640 15.418 1.00 17.92 ? 105 PRO A CA 1
ATOM 828 C ? 7.020 19.664 16.914 1.00 15.61 ? 105 PRO A C 1
ATOM 829 O ? 7.170 20.696 17.567 1.00 14.42 ? 105 PRO A O 1
ATOM 830 C ? 8.828 19.348 15.202 1.00 18.86 ? 105 PRO A CB 1
ATOM 831 C ? 9.188 20.164 14.005 1.00 18.76 ? 105 PRO A CG 1
ATOM 832 C ? 8.423 21.440 14.199 1.00 18.40 ? 105 PRO A CD 1
ATOM 833 N ? 6.552 18.541 17.444 1.00 16.02 ? 106 LYS A N 1
ATOM 834 C ? 6.255 18.453 18.868 1.00 16.93 ? 106 LYS A CA 1
ATOM 835 C ? 7.609 18.305 19.554 1.00 15.49 ? 106 LYS A C 1
ATOM 836 O ? 8.397 17.437 19.183 1.00 14.76 ? 106 LYS A O 1
ATOM 837 C ? 5.387 17.229 19.174 1.00 20.98 ? 106 LYS A CB 1
ATOM 838 C ? 5.015 17.097 20.662 1.00 27.98 ? 106 LYS A CG 1
ATOM 839 C ? 4.463 18.433 21.229 1.00 33.23 ? 106 LYS A CD 1
ATOM 840 C ? 4.250 18.417 22.764 1.00 35.21 ? 106 LYS A CE 1
ATOM 841 N ? 5.519 18.251 23.566 1.00 33.75 ? 106 LYS A NZ 1
ATOM 842 N ? 7.907 19.167 20.515 1.00 13.91 ? 107 THR A N 1
ATOM 843 C ? 9.203 19.086 21.190 1.00 12.14 ? 107 THR A CA 1
ATOM 844 C ? 9.083 18.819 22.681 1.00 11.66 ? 107 THR A C 1
ATOM 845 O ? 8.061 19.120 23.295 1.00 10.59 ? 107 THR A O 1
ATOM 846 C ? 10.012 20.382 21.016 1.00 12.37 ? 107 THR A CB 1
ATOM 847 O ? 9.263 21.480 21.547 1.00 12.36 ? 107 THR A OG1 1
ATOM 848 C ? 10.327 20.643 19.544 1.00 12.62 ? 107 THR A CG2 1
ATOM 849 N ? 10.140 18.249 23.250 1.00 10.16 ? 108 SER A N 1
ATOM 850 C ? 10.192 17.975 24.681 1.00 9.98 ? 108 SER A CA 1
ATOM 851 C ? 11.649 17.774 25.081 1.00 9.90 ? 108 SER A C 1
ATOM 852 O ? 12.549 17.774 24.227 1.00 8.48 ? 108 SER A O 1
ATOM 853 C ? 9.370 16.729 25.024 1.00 9.84 ? 108 SER A CB 1
ATOM 854 O ? 9.844 15.601 24.313 1.00 13.87 ? 108 SER A OG 1
ATOM 855 N ? 11.890 17.708 26.386 1.00 7.96 ? 109 TRP A N 1
ATOM 856 C ? 13.233 17.446 26.894 1.00 7.85 ? 109 TRP A CA 1
ATOM 857 C ? 13.109 16.693 28.209 1.00 7.56 ? 109 TRP A C 1
ATOM 858 O ? 12.053 16.728 28.837 1.00 8.14 ? 109 TRP A O 1
ATOM 859 C ? 14.094 18.722 27.051 1.00 8.25 ? 109 TRP A CB 1
ATOM 860 C ? 13.627 19.829 28.007 1.00 8.07 ? 109 TRP A CG 1
ATOM 861 C ? 13.120 21.046 27.648 1.00 9.28 ? 109 TRP A CD1 1
ATOM 862 C ? 13.745 19.865 29.450 1.00 9.31 ? 109 TRP A CD2 1
ATOM 863 N ? 12.929 21.836 28.760 1.00 9.69 ? 109 TRP A NE1 1
ATOM 864 C ? 13.306 21.136 29.878 1.00 9.04 ? 109 TRP A CE2 1
ATOM 865 C ? 14.186 18.939 30.416 1.00 9.92 ? 109 TRP A CE3 1
ATOM 866 C ? 13.286 21.515 31.228 1.00 9.72 ? 109 TRP A CZ2 1
ATOM 867 C ? 14.163 19.316 31.758 1.00 10.25 ? 109 TRP A CZ3 1
ATOM 868 C ? 13.717 20.593 32.149 1.00 10.11 ? 109 TRP A CH2 1
ATOM 869 N ? 14.136 15.924 28.549 1.00 7.39 ? 110 THR A N 1
ATOM 870 C ? 14.168 15.176 29.808 1.00 6.23 ? 110 THR A CA 1
ATOM 871 C ? 15.577 15.334 30.395 1.00 7.40 ? 110 THR A C 1
ATOM 872 O ? 16.558 15.563 29.652 1.00 6.43 ? 110 THR A O 1
ATOM 873 C ? 13.887 13.633 29.626 1.00 7.17 ? 110 THR A CB 1
ATOM 874 O ? 15.000 13.002 28.973 1.00 7.49 ? 110 THR A OG1 1
ATOM 875 C ? 12.616 13.377 28.803 1.00 6.64 ? 110 THR A CG2 1
ATOM 876 N ? 15.669 15.293 31.727 1.00 6.72 ? 111 ARG A N 1
ATOM 877 C ? 16.966 15.356 32.425 1.00 6.27 ? 111 ARG A CA 1
ATOM 878 C ? 16.924 14.287 33.483 1.00 7.89 ? 111 ARG A C 1
ATOM 879 O ? 15.928 14.156 34.193 1.00 8.35 ? 111 ARG A O 1
ATOM 880 C ? 17.240 16.722 33.068 1.00 6.20 ? 111 ARG A CB 1
ATOM 881 C ? 17.703 17.765 32.060 1.00 7.38 ? 111 ARG A CG 1
ATOM 882 C ? 18.100 19.072 32.727 1.00 8.70 ? 111 ARG A CD 1
ATOM 883 N ? 18.783 19.965 31.784 1.00 9.83 ? 111 ARG A NE 1
ATOM 884 C ? 18.158 20.804 30.963 1.00 10.23 ? 111 ARG A CZ 1
ATOM 885 N ? 16.840 20.869 30.966 1.00 10.89 ? 111 ARG A NH1 1
ATOM 886 N ? 18.847 21.590 30.144 1.00 11.56 ? 111 ARG A NH2 1
ATOM 887 N ? 17.957 13.464 33.534 1.00 7.64 ? 112 GLU A N 1
ATOM 888 C ? 17.977 12.402 34.527 1.00 10.31 ? 112 GLU A CA 1
ATOM 889 C ? 19.356 12.142 35.113 1.00 9.93 ? 112 GLU A C 1
ATOM 890 O ? 20.367 12.273 34.425 1.00 7.92 ? 112 GLU A O 1
ATOM 891 C ? 17.401 11.118 33.940 1.00 14.05 ? 112 GLU A CB 1
ATOM 892 C ? 18.213 10.489 32.836 1.00 20.37 ? 112 GLU A CG 1
ATOM 893 C ? 17.484 9.325 32.177 1.00 25.09 ? 112 GLU A CD 1
ATOM 894 O ? 17.223 8.308 32.883 1.00 22.36 ? 112 GLU A OE1 1
ATOM 895 O ? 17.175 9.443 30.955 1.00 25.10 ? 112 GLU A OE2 1
ATOM 896 N ? 19.387 11.816 36.401 1.00 8.96 ? 113 LEU A N 1
ATOM 897 C ? 20.634 11.503 37.091 1.00 12.04 ? 113 LEU A CA 1
ATOM 898 C ? 20.789 9.991 37.081 1.00 12.06 ? 113 LEU A C 1
ATOM 899 O ? 19.906 9.270 37.559 1.00 12.08 ? 113 LEU A O 1
ATOM 900 C ? 20.575 11.983 38.532 1.00 14.38 ? 113 LEU A CB 1
ATOM 901 C ? 20.768 13.465 38.799 1.00 17.46 ? 113 LEU A CG 1
ATOM 902 C ? 20.709 13.656 40.298 1.00 19.61 ? 113 LEU A CD1 1
ATOM 903 C ? 22.128 13.945 38.266 1.00 18.46 ? 113 LEU A CD2 1
ATOM 904 N ? 21.895 9.502 36.535 1.00 11.06 ? 114 THR A N 1
ATOM 905 C ? 22.110 8.062 36.452 1.00 11.74 ? 114 THR A CA 1
ATOM 906 C ? 22.816 7.522 37.686 1.00 11.41 ? 114 THR A C 1
ATOM 907 O ? 23.327 8.282 38.501 1.00 11.47 ? 114 THR A O 1
ATOM 908 C ? 22.894 7.700 35.188 1.00 12.89 ? 114 THR A CB 1
ATOM 909 O ? 24.109 8.451 35.164 1.00 15.50 ? 114 THR A OG1 1
ATOM 910 C ? 22.075 8.037 33.951 1.00 14.75 ? 114 THR A CG2 1
ATOM 911 N ? 22.834 6.202 37.808 1.00 13.23 ? 115 ASN A N 1
ATOM 912 C ? 23.441 5.538 38.951 1.00 16.19 ? 115 ASN A CA 1
ATOM 913 C ? 24.930 5.761 39.139 1.00 14.24 ? 115 ASN A C 1
ATOM 914 O ? 25.432 5.626 40.256 1.00 14.74 ? 115 ASN A O 1
ATOM 915 C ? 23.123 4.047 38.918 1.00 21.89 ? 115 ASN A CB 1
ATOM 916 C ? 21.703 3.754 39.357 1.00 29.77 ? 115 ASN A CG 1
ATOM 917 O ? 20.955 3.046 38.669 1.00 34.83 ? 115 ASN A OD1 1
ATOM 918 N ? 21.313 4.310 40.516 1.00 32.90 ? 115 ASN A ND2 1
ATOM 919 N ? 25.626 6.095 38.055 1.00 12.05 ? 116 ASP A N 1
ATOM 920 C ? 27.061 6.364 38.094 1.00 11.99 ? 116 ASP A CA 1
ATOM 921 C ? 27.424 7.821 38.397 1.00 11.45 ? 116 ASP A C 1
ATOM 922 O ? 28.592 8.184 38.393 1.00 12.23 ? 116 ASP A O 1
ATOM 923 C ? 27.764 5.875 36.806 1.00 13.89 ? 116 ASP A CB 1
ATOM 924 C ? 27.177 6.474 35.512 1.00 16.58 ? 116 ASP A CG 1
ATOM 925 O ? 26.263 7.303 35.569 1.00 19.66 ? 116 ASP A OD1 1
ATOM 926 O ? 27.651 6.113 34.422 1.00 20.14 ? 116 ASP A OD2 1
ATOM 927 N ? 26.420 8.647 38.675 1.00 10.58 ? 117 GLY A N 1
ATOM 928 C ? 26.669 10.042 38.997 1.00 9.83 ? 117 GLY A CA 1
ATOM 929 C ? 26.652 11.019 37.831 1.00 9.97 ? 117 GLY A C 1
ATOM 930 O ? 26.945 12.192 38.019 1.00 10.45 ? 117 GLY A O 1
ATOM 931 N ? 26.289 10.550 36.638 1.00 9.43 ? 118 GLU A N 1
ATOM 932 C ? 26.242 11.413 35.458 1.00 7.79 ? 118 GLU A CA 1
ATOM 933 C ? 24.834 11.955 35.213 1.00 7.60 ? 118 GLU A C 1
ATOM 934 O ? 23.872 11.565 35.885 1.00 8.05 ? 118 GLU A O 1
ATOM 935 C ? 26.776 10.653 34.241 1.00 8.86 ? 118 GLU A CB 1
ATOM 936 C ? 28.227 10.234 34.427 1.00 9.64 ? 118 GLU A CG 1
ATOM 937 C ? 28.770 9.370 33.310 1.00 13.39 ? 118 GLU A CD 1
ATOM 938 O ? 28.036 9.043 32.355 1.00 11.90 ? 118 GLU A OE1 1
ATOM 939 O ? 29.956 8.998 33.405 1.00 16.59 ? 118 GLU A OE2 1
ATOM 940 N ? 24.732 12.884 34.269 1.00 7.57 ? 119 LEU A N 1
ATOM 941 C ? 23.467 13.513 33.917 1.00 6.94 ? 119 LEU A CA 1
ATOM 942 C ? 23.189 13.277 32.431 1.00 8.29 ? 119 LEU A C 1
ATOM 943 O ? 24.070 13.506 31.593 1.00 8.23 ? 119 LEU A O 1
ATOM 944 C ? 23.556 15.023 34.184 1.00 7.83 ? 119 LEU A CB 1
ATOM 945 C ? 22.417 15.972 33.810 1.00 9.54 ? 119 LEU A CG 1
ATOM 946 C ? 21.213 15.661 34.618 1.00 11.05 ? 119 LEU A CD1 1
ATOM 947 C ? 22.822 17.421 34.066 1.00 12.54 ? 119 LEU A CD2 1
ATOM 948 N ? 22.010 12.743 32.119 1.00 6.17 ? 120 ILE A N 1
ATOM 949 C ? 21.638 12.529 30.730 1.00 6.22 ? 120 ILE A CA 1
ATOM 950 C ? 20.527 13.511 30.354 1.00 7.47 ? 120 ILE A C 1
ATOM 951 O ? 19.493 13.580 31.036 1.00 6.54 ? 120 ILE A O 1
ATOM 952 C ? 21.103 11.118 30.485 1.00 7.19 ? 120 ILE A CB 1
ATOM 953 C ? 22.171 10.070 30.801 1.00 8.26 ? 120 ILE A CG1 1
ATOM 954 C ? 20.556 11.003 29.047 1.00 6.54 ? 120 ILE A CG2 1
ATOM 955 C ? 21.668 8.658 30.600 1.00 9.35 ? 120 ILE A CD1 1
ATOM 956 N ? 20.771 14.301 29.306 1.00 6.41 ? 121 LEU A N 1
ATOM 957 C ? 19.783 15.236 28.779 1.00 6.25 ? 121 LEU A CA 1
ATOM 958 C ? 19.299 14.693 27.426 1.00 7.41 ? 121 LEU A C 1
ATOM 959 O ? 20.115 14.242 26.619 1.00 6.01 ? 121 LEU A O 1
ATOM 960 C ? 20.400 16.624 28.526 1.00 7.37 ? 121 LEU A CB 1
ATOM 961 C ? 19.607 17.580 27.597 1.00 7.96 ? 121 LEU A CG 1
ATOM 962 C ? 18.340 18.117 28.290 1.00 7.91 ? 121 LEU A CD1 1
ATOM 963 C ? 20.501 18.739 27.151 1.00 7.96 ? 121 LEU A CD2 1
ATOM 964 N ? 17.988 14.607 27.222 1.00 6.71 ? 122 THR A N 1
ATOM 965 C ? 17.514 14.205 25.898 1.00 7.80 ? 122 THR A CA 1
ATOM 966 C ? 16.633 15.334 25.402 1.00 8.58 ? 122 THR A C 1
ATOM 967 O ? 15.988 16.034 26.194 1.00 7.21 ? 122 THR A O 1
ATOM 968 C ? 16.754 12.843 25.832 1.00 7.51 ? 122 THR A CB 1
ATOM 969 O ? 15.422 12.992 26.313 1.00 9.27 ? 122 THR A OG1 1
ATOM 970 C ? 17.484 11.759 26.622 1.00 7.86 ? 122 THR A CG2 1
ATOM 971 N ? 16.732 15.613 24.110 1.00 7.87 ? 123 MET A N 1
ATOM 972 C ? 15.904 16.643 23.494 1.00 9.22 ? 123 MET A CA 1
ATOM 973 C ? 15.194 15.950 22.337 1.00 8.66 ? 123 MET A C 1
ATOM 974 O ? 15.828 15.189 21.601 1.00 8.09 ? 123 MET A O 1
ATOM 975 C ? 16.760 17.818 23.019 1.00 9.37 ? 123 MET A CB 1
ATOM 976 C ? 17.359 18.612 24.171 1.00 11.81 ? 123 MET A CG 1
ATOM 977 S ? 18.325 20.048 23.658 1.00 16.59 ? 123 MET A SD 1
ATOM 978 C ? 19.871 19.278 23.173 1.00 14.10 ? 123 MET A CE 1
ATOM 979 N ? 13.895 16.195 22.186 1.00 7.20 ? 124 THR A N 1
ATOM 980 C ? 13.133 15.534 21.134 1.00 9.54 ? 124 THR A CA 1
ATOM 981 C ? 12.407 16.513 20.222 1.00 10.12 ? 124 THR A C 1
ATOM 982 O ? 11.941 17.563 20.665 1.00 9.54 ? 124 THR A O 1
ATOM 983 C ? 12.073 14.552 21.756 1.00 10.74 ? 124 THR A CB 1
ATOM 984 O ? 12.740 13.544 22.535 1.00 11.99 ? 124 THR A OG1 1
ATOM 985 C ? 11.247 13.865 20.679 1.00 11.66 ? 124 THR A CG2 1
ATOM 986 N ? 12.346 16.167 18.935 1.00 11.06 ? 125 ALA A N 1
ATOM 987 C ? 11.634 16.962 17.923 1.00 11.63 ? 125 ALA A CA 1
ATOM 988 C ? 10.981 15.878 17.078 1.00 13.46 ? 125 ALA A C 1
ATOM 989 O ? 11.669 15.144 16.352 1.00 13.11 ? 125 ALA A O 1
ATOM 990 C ? 12.603 17.786 17.091 1.00 13.16 ? 125 ALA A CB 1
ATOM 991 N ? 9.664 15.754 17.216 1.00 14.63 ? 126 ASP A N 1
ATOM 992 C ? 8.901 14.721 16.536 1.00 17.86 ? 126 ASP A CA 1
ATOM 993 C ? 9.512 13.364 16.905 1.00 18.66 ? 126 ASP A C 1
ATOM 994 O ? 9.519 13.006 18.080 1.00 19.38 ? 126 ASP A O 1
ATOM 995 C ? 8.835 14.982 15.023 1.00 18.40 ? 126 ASP A CB 1
ATOM 996 C ? 7.786 16.032 14.660 1.00 22.34 ? 126 ASP A CG 1
ATOM 997 O ? 6.800 16.198 15.422 1.00 23.23 ? 126 ASP A OD1 1
ATOM 998 O ? 7.940 16.702 13.621 1.00 24.32 ? 126 ASP A OD2 1
ATOM 999 N ? 10.064 12.629 15.945 1.00 20.19 ? 127 ASP A N 1
ATOM 1000 C ? 10.656 11.333 16.271 1.00 21.56 ? 127 ASP A CA 1
ATOM 1001 C ? 12.175 11.279 16.416 1.00 18.85 ? 127 ASP A C 1
ATOM 1002 O ? 12.732 10.219 16.657 1.00 20.67 ? 127 ASP A O 1
ATOM 1003 C ? 10.178 10.263 15.303 1.00 26.47 ? 127 ASP A CB 1
ATOM 1004 C ? 9.043 9.450 15.880 1.00 33.21 ? 127 ASP A CG 1
ATOM 1005 O ? 7.892 9.959 15.934 1.00 36.08 ? 127 ASP A OD1 1
ATOM 1006 O ? 9.318 8.308 16.318 1.00 38.35 ? 127 ASP A OD2 1
ATOM 1007 N ? 12.836 12.418 16.281 1.00 15.22 ? 128 VAL A N 1
ATOM 1008 C ? 14.286 12.486 16.407 1.00 12.83 ? 128 VAL A CA 1
ATOM 1009 C ? 14.681 12.843 17.835 1.00 11.58 ? 128 VAL A C 1
ATOM 1010 O ? 14.176 13.811 18.408 1.00 9.74 ? 128 VAL A O 1
ATOM 1011 C ? 14.864 13.503 15.423 1.00 12.79 ? 128 VAL A CB 1
ATOM 1012 C ? 16.338 13.757 15.706 1.00 12.93 ? 128 VAL A CG1 1
ATOM 1013 C ? 14.677 12.968 14.005 1.00 14.30 ? 128 VAL A CG2 1
ATOM 1014 N ? 15.586 12.051 18.397 1.00 9.29 ? 129 VAL A N 1
ATOM 1015 C ? 16.054 12.257 19.761 1.00 7.95 ? 129 VAL A CA 1
ATOM 1016 C ? 17.558 12.546 19.842 1.00 7.49 ? 129 VAL A C 1
ATOM 1017 O ? 18.374 11.816 19.276 1.00 8.73 ? 129 VAL A O 1
ATOM 1018 C ? 15.764 11.007 20.617 1.00 9.43 ? 129 VAL A CB 1
ATOM 1019 C ? 16.153 11.253 22.076 1.00 9.09 ? 129 VAL A CG1 1
ATOM 1020 C ? 14.293 10.610 20.495 1.00 9.45 ? 129 VAL A CG2 1
ATOM 1021 N ? 17.912 13.630 20.534 1.00 7.54 ? 130 CYS A N 1
ATOM 1022 C ? 19.305 14.010 20.756 1.00 6.47 ? 130 CYS A CA 1
ATOM 1023 C ? 19.670 13.627 22.200 1.00 6.61 ? 130 CYS A C 1
ATOM 1024 O ? 18.955 13.992 23.135 1.00 7.53 ? 130 CYS A O 1
ATOM 1025 C ? 19.485 15.517 20.544 1.00 6.05 ? 130 CYS A CB 1
ATOM 1026 S ? 21.063 16.183 21.077 1.00 8.82 ? 130 CYS A SG 1
ATOM 1027 N ? 20.786 12.925 22.372 1.00 6.58 ? 131 THR A N 1
ATOM 1028 C ? 21.241 12.462 23.693 1.00 5.93 ? 131 THR A CA 1
ATOM 1029 C ? 22.569 13.102 24.054 1.00 6.18 ? 131 THR A C 1
ATOM 1030 O ? 23.528 13.003 23.294 1.00 5.77 ? 131 THR A O 1
ATOM 1031 C ? 21.419 10.914 23.699 1.00 6.63 ? 131 THR A CB 1
ATOM 1032 O ? 20.199 10.299 23.289 1.00 7.60 ? 131 THR A OG1 1
ATOM 1033 C ? 21.763 10.399 25.091 1.00 7.76 ? 131 THR A CG2 1
ATOM 1034 N ? 22.624 13.780 25.202 1.00 6.29 ? 132 ARG A N 1
ATOM 1035 C ? 23.853 14.429 25.660 1.00 7.67 ? 132 ARG A CA 1
ATOM 1036 C ? 24.108 13.960 27.093 1.00 7.19 ? 132 ARG A C 1
ATOM 1037 O ? 23.184 13.895 27.902 1.00 8.65 ? 132 ARG A O 1
ATOM 1038 C ? 23.719 15.957 25.621 1.00 9.67 ? 132 ARG A CB 1
ATOM 1039 C ? 22.945 16.470 24.429 1.00 15.02 ? 132 ARG A CG 1
ATOM 1040 C ? 23.781 17.260 23.476 1.00 16.80 ? 132 ARG A CD 1
ATOM 1041 N ? 24.140 18.580 23.984 1.00 12.48 ? 132 ARG A NE 1
ATOM 1042 C ? 25.030 19.377 23.395 1.00 12.93 ? 132 ARG A CZ 1
ATOM 1043 N ? 25.641 19.005 22.279 1.00 13.84 ? 132 ARG A NH1 1
ATOM 1044 N ? 25.398 20.506 23.973 1.00 11.57 ? 132 ARG A NH2 1
ATOM 1045 N ? 25.359 13.633 27.397 1.00 5.99 ? 133 VAL A N 1
ATOM 1046 C ? 25.739 13.124 28.719 1.00 5.92 ? 133 VAL A CA 1
ATOM 1047 C ? 26.773 14.055 29.345 1.00 5.85 ? 133 VAL A C 1
ATOM 1048 O ? 27.713 14.492 28.681 1.00 5.50 ? 133 VAL A O 1
ATOM 1049 C ? 26.333 11.698 28.608 1.00 6.37 ? 133 VAL A CB 1
ATOM 1050 C ? 26.609 11.120 29.988 1.00 7.95 ? 133 VAL A CG1 1
ATOM 1051 C ? 25.385 10.782 27.832 1.00 6.46 ? 133 VAL A CG2 1
ATOM 1052 N ? 26.619 14.337 30.635 1.00 5.35 ? 134 TYR A N 1
ATOM 1053 C ? 27.538 15.228 31.322 1.00 4.57 ? 134 TYR A CA 1
ATOM 1054 C ? 28.014 14.611 32.617 1.00 5.30 ? 134 TYR A C 1
ATOM 1055 O ? 27.371 13.712 33.165 1.00 3.92 ? 134 TYR A O 1
ATOM 1056 C ? 26.846 16.550 31.686 1.00 6.84 ? 134 TYR A CB 1
ATOM 1057 C ? 26.118 17.251 30.574 1.00 8.89 ? 134 TYR A CG 1
ATOM 1058 C ? 24.901 16.762 30.122 1.00 10.29 ? 134 TYR A CD1 1
ATOM 1059 C ? 26.628 18.406 29.992 1.00 10.49 ? 134 TYR A CD2 1
ATOM 1060 C ? 24.212 17.386 29.133 1.00 13.03 ? 134 TYR A CE1 1
ATOM 1061 C ? 25.930 19.051 28.982 1.00 12.15 ? 134 TYR A CE2 1
ATOM 1062 C ? 24.723 18.517 28.567 1.00 12.80 ? 134 TYR A CZ 1
ATOM 1063 O ? 23.991 19.082 27.567 1.00 18.07 ? 134 TYR A OH 1
ATOM 1064 N ? 29.113 15.158 33.119 1.00 6.63 ? 135 VAL A N 1
ATOM 1065 C ? 29.697 14.762 34.394 1.00 8.42 ? 135 VAL A CA 1
ATOM 1066 C ? 30.100 16.086 35.064 1.00 9.05 ? 135 VAL A C 1
ATOM 1067 O ? 30.340 17.086 34.385 1.00 9.02 ? 135 VAL A O 1
ATOM 1068 C ? 30.925 13.815 34.204 1.00 8.05 ? 135 VAL A CB 1
ATOM 1069 C ? 32.109 14.556 33.596 1.00 9.27 ? 135 VAL A CG1 1
ATOM 1070 C ? 31.304 13.151 35.533 1.00 10.37 ? 135 VAL A CG2 1
ATOM 1071 N ? 30.117 16.133 36.390 1.00 9.57 ? 136 ARG A N 1
ATOM 1072 C ? 30.498 17.375 37.040 1.00 10.86 ? 136 ARG A CA 1
ATOM 1073 C ? 31.964 17.676 36.776 1.00 11.68 ? 136 ARG A C 1
ATOM 1074 O ? 32.782 16.765 36.686 1.00 11.35 ? 136 ARG A O 1
ATOM 1075 C ? 30.221 17.319 38.536 1.00 11.99 ? 136 ARG A CB 1
ATOM 1076 C ? 28.746 17.454 38.885 1.00 13.89 ? 136 ARG A CG 1
ATOM 1077 C ? 28.576 17.533 40.382 1.00 15.85 ? 136 ARG A CD 1
ATOM 1078 N ? 27.185 17.407 40.754 1.00 17.08 ? 136 ARG A NE 1
ATOM 1079 C ? 26.561 16.245 40.926 1.00 21.69 ? 136 ARG A CZ 1
ATOM 1080 N ? 27.217 15.102 40.754 1.00 23.26 ? 136 ARG A NH1 1
ATOM 1081 N ? 25.278 16.227 41.283 1.00 22.60 ? 136 ARG A NH2 1
ATOM 1082 N ? 32.282 18.963 36.663 1.00 15.12 ? 137 GLU A N 1
ATOM 1083 C ? 33.641 19.430 36.400 1.00 18.00 ? 137 GLU A CA 1
ATOM 1084 C ? 34.615 19.038 37.493 1.00 18.96 ? 137 GLU A C 1
ATOM 1085 O ? 34.221 19.175 38.659 1.00 17.37 ? 137 GLU A O 1
ATOM 1086 C ? 33.661 20.943 36.293 1.00 19.89 ? 137 GLU A CB 1
ATOM 1087 C ? 33.092 21.492 35.035 1.00 28.03 ? 137 GLU A CG 1
ATOM 1088 C ? 33.469 22.953 34.865 1.00 33.22 ? 137 GLU A CD 1
ATOM 1089 O ? 34.630 23.217 34.473 1.00 37.31 ? 137 GLU A OE1 1
ATOM 1090 O ? 32.636 23.836 35.164 1.00 36.38 ? 137 GLU A OE2 1
ATOM 1091 O ? 35.776 18.680 37.173 1.00 22.23 ? 137 GLU A OXT 1
HETATM 1092 C ? 21.972 29.831 16.739 1.00 15.25 ? 200 REA A C1 1
HETATM 1093 C ? 20.921 30.524 15.841 1.00 15.61 ? 200 REA A C2 1
HETATM 1094 C ? 20.245 29.635 14.848 1.00 16.19 ? 200 REA A C3 1
HETATM 1095 C ? 19.555 28.479 15.488 1.00 14.59 ? 200 REA A C4 1
HETATM 1096 C ? 20.389 27.812 16.587 1.00 14.10 ? 200 REA A C5 1
HETATM 1097 C ? 21.425 28.446 17.218 1.00 14.42 ? 200 REA A C6 1
HETATM 1098 C ? 22.242 27.851 18.297 1.00 13.89 ? 200 REA A C7 1
HETATM 1099 C ? 21.868 26.977 19.240 1.00 11.86 ? 200 REA A C8 1
HETATM 1100 C ? 22.705 26.434 20.286 1.00 10.87 ? 200 REA A C9 1
HETATM 1101 C ? 22.159 25.536 21.131 1.00 9.19 ? 200 REA A C10 1
HETATM 1102 C ? 22.875 24.924 22.234 1.00 10.35 ? 200 REA A C11 1
HETATM 1103 C ? 22.237 24.026 22.990 1.00 10.53 ? 200 REA A C12 1
HETATM 1104 C ? 22.856 23.377 24.125 1.00 10.91 ? 200 REA A C13 1
HETATM 1105 C ? 22.135 22.473 24.834 1.00 11.88 ? 200 REA A C14 1
HETATM 1106 C ? 22.563 21.710 26.016 1.00 14.86 ? 200 REA A C15 1
HETATM 1107 C ? 22.238 30.737 17.948 1.00 15.47 ? 200 REA A C16 1
HETATM 1108 C ? 23.292 29.620 15.948 1.00 13.42 ? 200 REA A C17 1
HETATM 1109 C ? 19.791 26.449 16.947 1.00 12.61 ? 200 REA A C18 1
HETATM 1110 C ? 24.181 26.841 20.385 1.00 10.08 ? 200 REA A C19 1
HETATM 1111 C ? 24.303 23.747 24.489 1.00 10.10 ? 200 REA A C20 1
HETATM 1112 O ? 23.640 21.075 25.978 1.00 13.29 ? 200 REA A O1 1
HETATM 1113 O ? 21.840 21.712 27.037 1.00 10.99 ? 200 REA A O2 1
HETATM 1114 O ? 21.817 19.604 31.169 1.00 17.43 ? 300 HOH A O 1
HETATM 1115 O ? 7.617 26.892 37.107 1.00 12.66 ? 301 HOH A O 1
HETATM 1116 O ? 22.885 27.835 25.056 1.00 18.86 ? 302 HOH A O 1
HETATM 1117 O ? 30.685 27.402 22.818 1.00 14.12 ? 303 HOH A O 1
HETATM 1118 O ? 29.930 20.839 40.398 1.00 16.48 ? 304 HOH A O 1
HETATM 1119 O ? 31.492 21.096 28.452 1.00 16.65 ? 305 HOH A O 1
HETATM 1120 O ? 19.459 26.601 30.320 1.00 9.81 ? 306 HOH A O 1
HETATM 1121 O ? 19.116 26.759 22.930 1.00 22.33 ? 307 HOH A O 1
HETATM 1122 O ? 16.356 22.299 28.453 1.00 35.46 ? 308 HOH A O 1
HETATM 1123 O ? 21.823 21.939 29.734 1.00 13.95 ? 309 HOH A O 1
HETATM 1124 O ? 13.206 22.267 22.102 1.00 20.07 ? 310 HOH A O 1
HETATM 1125 O ? 30.300 22.803 12.740 1.00 24.70 ? 311 HOH A O 1
HETATM 1126 O ? 7.344 23.059 35.600 1.00 8.82 ? 312 HOH A O 1
HETATM 1127 O ? 6.876 22.668 20.375 1.00 29.74 ? 313 HOH A O 1
HETATM 1128 O ? 17.917 24.800 29.159 1.00 23.69 ? 314 HOH A O 1
HETATM 1129 O ? 37.101 16.714 38.714 1.00 19.84 ? 315 HOH A O 1
HETATM 1130 O ? 28.721 7.425 30.043 1.00 14.94 ? 316 HOH A O 1
HETATM 1131 O ? 13.212 14.450 25.193 1.00 18.03 ? 317 HOH A O 1
HETATM 1132 O ? 6.094 9.777 39.151 1.00 13.98 ? 318 HOH A O 1
HETATM 1133 O ? 19.296 10.379 13.144 1.00 27.20 ? 319 HOH A O 1
HETATM 1134 O ? 25.337 10.931 16.577 1.00 18.41 ? 320 HOH A O 1
HETATM 1135 O ? 25.244 34.269 18.193 1.00 9.65 ? 321 HOH A O 1
HETATM 1136 O ? 23.567 10.727 14.429 1.00 11.13 ? 322 HOH A O 1
HETATM 1137 O ? 17.151 12.178 30.238 1.00 11.53 ? 323 HOH A O 1
HETATM 1138 O ? 27.768 11.967 42.077 1.00 23.33 ? 324 HOH A O 1
HETATM 1139 O ? 30.270 12.554 21.386 1.00 25.05 ? 325 HOH A O 1
HETATM 1140 O ? 25.662 15.488 18.515 1.00 10.80 ? 326 HOH A O 1
HETATM 1141 O ? 4.514 21.426 18.685 1.00 45.94 ? 327 HOH A O 1
HETATM 1142 O ? 8.081 23.201 17.690 1.00 30.16 ? 328 HOH A O 1
HETATM 1143 O ? 13.242 29.389 14.924 1.00 39.93 ? 329 HOH A O 1
HETATM 1144 O ? 10.514 18.772 10.176 1.00 33.65 ? 330 HOH A O 1
HETATM 1145 O ? 10.555 13.666 26.313 1.00 32.55 ? 331 HOH A O 1
HETATM 1146 O ? 5.189 16.418 31.375 1.00 35.78 ? 332 HOH A O 1
HETATM 1147 O ? 0.738 25.633 36.349 1.00 29.00 ? 333 HOH A O 1
HETATM 1148 O ? 2.976 28.966 37.321 1.00 40.14 ? 334 HOH A O 1
HETATM 1149 O ? 6.424 28.750 38.849 1.00 32.17 ? 335 HOH A O 1
HETATM 1150 O ? 12.503 30.488 31.704 1.00 41.11 ? 336 HOH A O 1
HETATM 1151 O ? 14.979 30.157 27.559 1.00 23.78 ? 337 HOH A O 1
HETATM 1152 O ? 17.312 32.981 28.812 1.00 20.84 ? 338 HOH A O 1
HETATM 1153 O ? 29.473 25.946 34.693 1.00 29.05 ? 339 HOH A O 1
HETATM 1154 O ? 30.328 23.817 33.494 1.00 24.17 ? 340 HOH A O 1
HETATM 1155 O ? 31.158 28.144 26.433 1.00 42.66 ? 341 HOH A O 1
HETATM 1156 O ? 30.276 28.397 16.400 1.00 21.90 ? 342 HOH A O 1
HETATM 1157 O ? 19.533 23.600 26.857 1.00 21.12 ? 343 HOH A O 1
HETATM 1158 O ? 17.892 24.675 24.549 1.00 48.11 ? 344 HOH A O 1
HETATM 1159 O ? 14.211 24.152 25.435 1.00 21.09 ? 345 HOH A O 1
HETATM 1160 O ? 15.223 27.626 27.056 1.00 27.16 ? 346 HOH A O 1
HETATM 1161 O ? 3.502 22.911 43.083 1.00 30.15 ? 347 HOH A O 1
HETATM 1162 O ? 20.610 7.668 40.212 1.00 49.06 ? 348 HOH A O 1
HETATM 1163 O ? 24.813 2.899 36.403 1.00 48.98 ? 349 HOH A O 1
HETATM 1164 O ? 29.900 5.163 26.918 1.00 23.60 ? 350 HOH A O 1
HETATM 1165 O ? 14.333 5.466 42.757 1.00 22.90 ? 351 HOH A O 1
HETATM 1166 O ? 8.914 5.771 35.515 1.00 35.92 ? 352 HOH A O 1
HETATM 1167 O ? 14.519 28.906 40.193 1.00 28.73 ? 353 HOH A O 1
HETATM 1168 O ? 17.573 20.203 47.080 1.00 37.63 ? 354 HOH A O 1
HETATM 1169 O ? 13.324 32.251 34.152 1.00 47.79 ? 355 HOH A O 1
HETATM 1170 O ? 12.491 24.840 7.594 1.00 39.45 ? 356 HOH A O 1
HETATM 1171 O ? 25.066 15.777 15.214 1.00 27.39 ? 357 HOH A O 1
HETATM 1172 O ? 27.138 17.638 17.834 1.00 45.12 ? 358 HOH A O 1
HETATM 1173 O ? 27.611 19.792 19.503 1.00 24.45 ? 359 HOH A O 1
HETATM 1174 O ? 11.358 8.880 19.119 1.00 24.31 ? 360 HOH A O 1
HETATM 1175 O ? 16.252 27.169 24.557 1.00 25.40 ? 361 HOH A O 1
HETATM 1176 O ? 22.049 27.870 4.565 1.00 25.37 ? 362 HOH A O 1
HETATM 1177 O ? 11.533 6.689 34.501 1.00 29.92 ? 363 HOH A O 1
HETATM 1178 O ? 13.269 4.551 36.338 1.00 45.75 ? 364 HOH A O 1
HETATM 1179 O ? 23.149 9.493 41.173 1.00 30.10 ? 365 HOH A O 1
HETATM 1180 O ? 21.090 12.171 43.973 1.00 27.97 ? 366 HOH A O 1
HETATM 1181 O ? 11.884 13.399 42.560 1.00 23.28 ? 367 HOH A O 1
HETATM 1182 O ? 29.542 17.520 20.025 1.00 38.32 ? 368 HOH A O 1
HETATM 1183 O ? 31.058 17.427 22.538 1.00 37.85 ? 369 HOH A O 1
HETATM 1184 O ? 31.928 9.444 23.294 1.00 46.07 ? 370 HOH A O 1
HETATM 1185 O ? 25.699 10.933 9.557 1.00 44.12 ? 371 HOH A O 1
HETATM 1186 O ? 26.533 13.428 16.334 1.00 45.21 ? 372 HOH A O 1
HETATM 1187 O ? 27.078 16.850 13.245 1.00 39.52 ? 373 HOH A O 1
HETATM 1188 O ? 20.596 32.070 6.807 1.00 36.38 ? 374 HOH A O 1
HETATM 1189 O ? 17.126 28.421 9.515 1.00 23.81 ? 375 HOH A O 1
HETATM 1190 O ? 16.626 32.383 11.231 1.00 20.11 ? 376 HOH A O 1
HETATM 1191 O ? 6.046 30.510 19.639 1.00 29.02 ? 377 HOH A O 1
HETATM 1192 O ? 9.543 16.072 11.145 1.00 50.91 ? 378 HOH A O 1
HETATM 1193 O ? 8.174 14.289 20.240 1.00 54.21 ? 379 HOH A O 1
HETATM 1194 O ? 11.561 10.834 22.873 1.00 43.23 ? 380 HOH A O 1
HETATM 1195 O ? 5.486 15.385 24.922 1.00 50.19 ? 381 HOH A O 1
HETATM 1196 O ? 6.038 21.424 43.276 1.00 46.64 ? 382 HOH A O 1
HETATM 1197 O ? 34.144 19.165 27.284 1.00 41.41 ? 383 HOH A O 1
HETATM 1198 O ? 16.916 27.142 42.621 1.00 29.32 ? 384 HOH A O 1
HETATM 1199 O ? 25.509 24.918 41.520 1.00 32.12 ? 385 HOH A O 1
HETATM 1200 O ? 31.446 7.504 31.389 1.00 28.93 ? 386 HOH A O 1
HETATM 1201 O ? 18.212 20.893 5.892 1.00 29.90 ? 387 HOH A O 1
HETATM 1202 O ? 15.148 27.608 7.685 1.00 30.91 ? 388 HOH A O 1
HETATM 1203 O ? 2.656 23.148 20.117 1.00 35.98 ? 389 HOH A O 1
HETATM 1204 O ? 3.100 22.690 28.640 1.00 31.31 ? 390 HOH A O 1
HETATM 1205 O ? 13.699 19.720 21.819 1.00 26.56 ? 391 HOH A O 1
HETATM 1206 O ? 26.833 28.283 32.272 1.00 31.48 ? 392 HOH A O 1
HETATM 1207 O ? 20.458 26.214 25.811 1.00 24.39 ? 393 HOH A O 1
HETATM 1208 O ? 32.304 27.731 18.152 1.00 41.66 ? 394 HOH A O 1
HETATM 1209 O ? 24.283 13.868 42.687 1.00 35.59 ? 395 HOH A O 1
HETATM 1210 O ? 11.833 12.657 45.160 1.00 38.30 ? 396 HOH A O 1
HETATM 1211 O ? 1.988 27.992 43.589 1.00 33.97 ? 397 HOH A O 1
HETATM 1212 O ? 32.913 22.982 40.176 1.00 39.26 ? 398 HOH A O 1
HETATM 1213 O ? 32.435 20.043 40.169 1.00 33.87 ? 399 HOH A O 1
#
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test-main.hpp"
#include <cif++.hpp>
#include <iostream>
#include <fstream>
TEST_CASE("reconstruct")
{
cif::compound_factory::instance().push_dictionary(gTestDir / "REA.cif");
for (std::filesystem::directory_iterator i(gTestDir / "reconstruct"); i != std::filesystem::directory_iterator{}; ++i)
{
std::cout << i->path() << '\n';
if (i->path().extension() == ".pdb")
{
cif::file f = cif::pdb::read(i->path());
std::error_code ec;
if (not cif::pdb::is_valid_pdbx_file(f, ec))
CHECK(cif::pdb::reconstruct_pdbx(f));
}
else
{
cif::file f(i->path());
std::error_code ec;
CHECK_FALSE(cif::pdb::is_valid_pdbx_file(f, ec));
CHECK(ec != std::errc{});
CHECK(cif::pdb::reconstruct_pdbx(f));
}
}
}
\ No newline at end of file
......@@ -28,8 +28,6 @@
#include <cif++.hpp>
#include <catch2/catch.hpp>
#include <iostream>
#include <fstream>
......
#include "cif++/utilities.hpp"
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include "cif++/utilities.hpp"
#include <random>
#include <thread>
......
......@@ -26,8 +26,6 @@
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include <stdexcept>
#include <cif++.hpp>
......
#define CATCH_CONFIG_RUNNER 1
#include "test-main.hpp"
#include <cif++.hpp>
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
std::filesystem::path gTestDir = std::filesystem::current_path();
int main(int argc, char *argv[])
......@@ -12,7 +11,13 @@ int main(int argc, char *argv[])
Catch::Session session; // There must be exactly one instance
// Build a new parser on top of Catch2's
#if CATCH22
using namespace Catch::clara;
#else
// Build a new parser on top of Catch2's
using namespace Catch::Clara;
#endif
auto cli = session.cli() // Get Catch2's command line parser
| Opt(gTestDir, "data-dir") // bind variable to a new option, with a hint string
["-D"]["--data-dir"] // the option names it will respond to
......
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#if CATCH22
#include <catch2/catch.hpp>
#else
#include <catch2/catch_all.hpp>
#endif
#include <filesystem>
extern std::filesystem::path gTestDir;
......@@ -26,8 +26,6 @@
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include <stdexcept>
#include <cif++.hpp>
......
......@@ -26,8 +26,6 @@
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include <cif++.hpp>
#include "cif++/dictionary_parser.hpp"
......@@ -568,7 +566,7 @@ _test.value
auto &test = db["test"];
REQUIRE(test.size() == 5);
REQUIRE(test.exists("value"_key == cif::null));
REQUIRE(test.contains("value"_key == cif::null));
REQUIRE(test.find("value"_key == cif::null).size() == 2);
}
......@@ -746,27 +744,51 @@ _cat_2.desc
std::istream is_data(&data_buffer);
f.load(is_data);
auto &cat1 = f.front()["cat_1"];
auto &cat2 = f.front()["cat_2"];
SECTION("one")
{
auto &cat1 = f.front()["cat_1"];
auto &cat2 = f.front()["cat_2"];
REQUIRE(cat1.size() == 3);
REQUIRE(cat2.size() == 3);
REQUIRE(cat1.size() == 3);
REQUIRE(cat2.size() == 3);
cat1.erase(cif::key("id") == 1);
cat1.erase(cif::key("id") == 1);
REQUIRE(cat1.size() == 2);
REQUIRE(cat2.size() == 1);
REQUIRE(cat1.size() == 2);
REQUIRE(cat2.size() == 1);
// REQUIRE_THROWS_AS(cat2.emplace({
// { "id", 4 },
// { "parent_id", 4 },
// { "desc", "moet fout gaan" }
// }), std::exception);
// REQUIRE_THROWS_AS(cat2.emplace({
// { "id", 4 },
// { "parent_id", 4 },
// { "desc", "moet fout gaan" }
// }), std::exception);
REQUIRE_THROWS_AS(cat2.emplace({ { "id", "vijf" }, // <- invalid value
{ "parent_id", 2 },
{ "desc", "moet fout gaan" } }),
std::exception);
REQUIRE_THROWS_AS(cat2.emplace({ { "id", "vijf" }, // <- invalid value
{ "parent_id", 2 },
{ "desc", "moet fout gaan" } }),
std::exception);
}
// SECTION("two")
// {
// auto &cat1 = f.front()["cat_1"];
// auto &cat2 = f.front()["cat_2"];
// cat1.update_value(cif::all(), "id", [](std::string_view v) -> std::string
// {
// int vi;
// auto [ec, ptr] = std::from_chars(v.data(), v.data() + v.length(), vi);
// return std::to_string(vi + 1);
// });
// REQUIRE(cat1.find1<std::string>(cif::key("id") == 2, "name") == "Aap");
// REQUIRE(cat1.find1<std::string>(cif::key("id") == 3, "name") == "Noot");
// REQUIRE(cat1.find1<std::string>(cif::key("id") == 4, "name") == "Mies");
// REQUIRE(cat2.find1<int>(cif::key("id") == 1, "parent_id") == 2);
// REQUIRE(cat2.find1<int>(cif::key("id") == 2, "parent_id") == 2);
// REQUIRE(cat2.find1<int>(cif::key("id") == 3, "parent_id") == 3);
// }
}
// --------------------------------------------------------------------
......@@ -3486,4 +3508,11 @@ TEST_CASE("pdb2cif_formula_weight")
fw = a.front()["entity"].find1<float>(cif::key("id") == 3, "formula_weight");
CHECK(fw == 18.015f);
}
// --------------------------------------------------------------------
TEST_CASE("update_values_with_provider")
{
}
\ No newline at end of file
......@@ -26,8 +26,6 @@
#include "test-main.hpp"
#include <catch2/catch.hpp>
#include <cif++.hpp>
#include <stdexcept>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment