mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-04 13:54:25 +08:00
Merge branch 'develop' of github.com:PDB-REDO/libcifpp into develop
This commit is contained in:
@@ -374,7 +374,7 @@ class atom
|
||||
/// Return true if this atom is an alternate
|
||||
[[nodiscard]] bool is_alternate() const
|
||||
{
|
||||
if (auto alt_id = get_label_alt_id(); alt_id.empty())
|
||||
if (auto alt_id = get_property_value("label_alt_id"); alt_id.empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,12 +61,6 @@
|
||||
namespace cif
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/// \brief Our value for Pi
|
||||
const double
|
||||
kPI = std::numbers::pi;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/**
|
||||
* @brief A stripped down quaternion implementation, based on boost::math::quaternion
|
||||
@@ -809,7 +803,7 @@ constexpr auto angle(const point_type<F> &p1, const point_type<F> &p2, const poi
|
||||
point_type<F> v1 = p1 - p2;
|
||||
point_type<F> v2 = p3 - p2;
|
||||
|
||||
return std::acos(dot_product(v1, v2) / (v1.length() * v2.length())) * 180 / kPI;
|
||||
return std::acos(dot_product(v1, v2) / (v1.length() * v2.length())) * 180 / std::numbers::pi_v<F>;
|
||||
}
|
||||
|
||||
/// \brief return the dihedral angle in degrees for the four points @a p1, @a p2, @a p3 and @a p4
|
||||
@@ -836,7 +830,7 @@ constexpr auto dihedral_angle(const point_type<F> &p1, const point_type<F> &p2,
|
||||
u = dot_product(p, x) / std::sqrt(u);
|
||||
v = dot_product(p, y) / std::sqrt(v);
|
||||
if (u != 0 or v != 0)
|
||||
result = std::atan2(v, u) * static_cast<F>(180 / kPI);
|
||||
result = std::atan2(v, u) * static_cast<F>(180 / std::numbers::pi_v<F>);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -882,7 +876,7 @@ point nudge(point p, float offset);
|
||||
quaternion construct_from_angle_axis(float angle, point axis);
|
||||
|
||||
/// \brief Return a tuple of an angle and an axis for quaternion @a q
|
||||
std::tuple<double, point> quaternion_to_angle_axis(quaternion q);
|
||||
std::tuple<float, point> quaternion_to_angle_axis(quaternion q);
|
||||
|
||||
/// @brief Given four points and an angle, return the quaternion required to rotate
|
||||
/// point p4 along the p2-p3 axis and around point p3 to obtain the required within
|
||||
@@ -924,7 +918,7 @@ class spherical_dots
|
||||
constexpr static int P = 2 * N * 1;
|
||||
|
||||
/// \brief the *weight* of the fibonacci sphere
|
||||
constexpr static double W = (4 * kPI) / P;
|
||||
constexpr static double W = (4 * std::numbers::pi) / P;
|
||||
|
||||
/// \brief the internal storage type
|
||||
using array_type = typename std::array<point, P>;
|
||||
@@ -964,7 +958,7 @@ class spherical_dots
|
||||
for (int32_t i = -N; i <= N; ++i)
|
||||
{
|
||||
double lat = std::asin((2.0 * i) / P);
|
||||
double lon = std::fmod(i, kGoldenRatio) * 2 * kPI / kGoldenRatio;
|
||||
double lon = std::fmod(i, kGoldenRatio) * 2 * std::numbers::pi / kGoldenRatio;
|
||||
|
||||
p->m_x = std::sin(lon) * std::cos(lat);
|
||||
p->m_y = std::cos(lon) * std::cos(lat);
|
||||
|
||||
@@ -490,7 +490,7 @@ float monomer::kappa() const
|
||||
{
|
||||
double ckap = cosinus_angle(CAlpha().get_location(), prevPrev.CAlpha().get_location(), nextNext.CAlpha().get_location(), CAlpha().get_location());
|
||||
double skap = std::sqrt(1 - ckap * ckap);
|
||||
result = static_cast<float>(std::atan2(skap, ckap) * 180 / kPI);
|
||||
result = static_cast<float>(std::atan2(skap, ckap) * 180 / std::numbers::pi_v<float>);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1298,31 +1298,31 @@ void structure::load_data()
|
||||
|
||||
// place atoms in residues
|
||||
|
||||
using key_type = std::tuple<std::string, int, std::string>;
|
||||
using key_type = std::tuple<std::string, int, std::string, std::string>;
|
||||
std::map<key_type, residue *> resMap;
|
||||
|
||||
for (auto &poly : m_polymers)
|
||||
{
|
||||
for (auto &res : poly)
|
||||
resMap[{ res.get_asym_id(), res.get_seq_id(), res.get_pdb_seq_num() }] = &res;
|
||||
resMap[{ res.get_asym_id(), res.get_seq_id(), res.get_pdb_seq_num(), res.get_compound_id() }] = &res;
|
||||
}
|
||||
|
||||
for (auto &res : m_non_polymers)
|
||||
resMap[{ res.get_asym_id(), res.get_seq_id(), res.get_pdb_seq_num() }] = &res;
|
||||
resMap[{ res.get_asym_id(), res.get_seq_id(), res.get_pdb_seq_num(), res.get_compound_id() }] = &res;
|
||||
|
||||
std::set<std::string> sugars;
|
||||
for (auto &branch : m_branches)
|
||||
{
|
||||
for (auto &sugar : branch)
|
||||
{
|
||||
resMap[{ sugar.get_asym_id(), sugar.get_seq_id(), sugar.get_pdb_seq_num() }] = &sugar;
|
||||
resMap[{ sugar.get_asym_id(), sugar.get_seq_id(), sugar.get_pdb_seq_num(), sugar.get_compound_id() }] = &sugar;
|
||||
sugars.insert(sugar.get_compound_id());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &atom : m_atoms)
|
||||
{
|
||||
key_type k(atom.get_label_asym_id(), atom.get_label_seq_id(), atom.get_auth_seq_id());
|
||||
key_type k(atom.get_label_asym_id(), atom.get_label_seq_id(), atom.get_auth_seq_id(), atom.get_label_comp_id());
|
||||
auto ri = resMap.find(k);
|
||||
|
||||
if (ri == resMap.end())
|
||||
|
||||
@@ -73,7 +73,7 @@ quaternion_type<T> normalize(quaternion_type<T> q)
|
||||
|
||||
quaternion construct_from_angle_axis(float angle, point axis)
|
||||
{
|
||||
angle = static_cast<float>((angle * kPI / 180) / 2);
|
||||
angle = (angle * std::numbers::pi_v<float> / 180) / 2;
|
||||
auto s = std::sin(angle);
|
||||
auto c = std::cos(angle);
|
||||
|
||||
@@ -86,14 +86,14 @@ quaternion construct_from_angle_axis(float angle, point axis)
|
||||
static_cast<float>(s * axis.m_z) });
|
||||
}
|
||||
|
||||
std::tuple<double, point> quaternion_to_angle_axis(quaternion q)
|
||||
std::tuple<float, point> quaternion_to_angle_axis(quaternion q)
|
||||
{
|
||||
if (q.get_a() > 1)
|
||||
q = normalize(q);
|
||||
|
||||
// angle:
|
||||
double angle = 2 * std::acos(q.get_a());
|
||||
angle = angle * 180 / kPI;
|
||||
float angle = 2 * std::acos(q.get_a());
|
||||
angle = angle * 180 / std::numbers::pi_v<float>;
|
||||
|
||||
// axis:
|
||||
float s = std::sqrt(1 - q.get_a() * q.get_a());
|
||||
|
||||
@@ -75,29 +75,29 @@ cell::cell(const datablock &db)
|
||||
|
||||
void cell::init()
|
||||
{
|
||||
auto alpha = (m_alpha * kPI) / 180;
|
||||
auto beta = (m_beta * kPI) / 180;
|
||||
auto gamma = (m_gamma * kPI) / 180;
|
||||
auto alpha = (m_alpha * std::numbers::pi_v<float>) / 180;
|
||||
auto beta = (m_beta * std::numbers::pi_v<float>) / 180;
|
||||
auto gamma = (m_gamma * std::numbers::pi_v<float>) / 180;
|
||||
|
||||
auto alpha_star = std::acos((std::cos(gamma) * std::cos(beta) - std::cos(alpha)) / (std::sin(beta) * std::sin(gamma)));
|
||||
|
||||
m_orthogonal = identity_matrix(3);
|
||||
|
||||
m_orthogonal(0, 0) = static_cast<float>(m_a);
|
||||
m_orthogonal(0, 1) = static_cast<float>(m_b * std::cos(gamma));
|
||||
m_orthogonal(0, 2) = static_cast<float>(m_c * std::cos(beta));
|
||||
m_orthogonal(1, 1) = static_cast<float>(m_b * std::sin(gamma));
|
||||
m_orthogonal(1, 2) = static_cast<float>(-m_c * std::sin(beta) * std::cos(alpha_star));
|
||||
m_orthogonal(2, 2) = static_cast<float>(m_c * std::sin(beta) * std::sin(alpha_star));
|
||||
m_orthogonal(0, 0) = m_a;
|
||||
m_orthogonal(0, 1) = m_b * std::cos(gamma);
|
||||
m_orthogonal(0, 2) = m_c * std::cos(beta);
|
||||
m_orthogonal(1, 1) = m_b * std::sin(gamma);
|
||||
m_orthogonal(1, 2) = m_c * std::sin(beta) * std::cos(alpha_star);
|
||||
m_orthogonal(2, 2) = m_c * std::sin(beta) * std::sin(alpha_star);
|
||||
|
||||
m_fractional = inverse(m_orthogonal);
|
||||
}
|
||||
|
||||
float cell::get_volume() const
|
||||
{
|
||||
auto alpha = (m_alpha * kPI) / 180;
|
||||
auto beta = (m_beta * kPI) / 180;
|
||||
auto gamma = (m_gamma * kPI) / 180;
|
||||
auto alpha = (m_alpha * std::numbers::pi_v<float>) / 180;
|
||||
auto beta = (m_beta * std::numbers::pi_v<float>) / 180;
|
||||
auto gamma = (m_gamma * std::numbers::pi_v<float>) / 180;
|
||||
|
||||
auto cos_alpha = std::cos(alpha);
|
||||
auto cos_beta = std::cos(beta);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "test-main.hpp"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cif++/cif++.hpp>
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -433,6 +434,23 @@ TEST_CASE("remove_residue_1")
|
||||
CHECK_NOTHROW(s.validate_atoms());
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("test_alternates_1")
|
||||
{
|
||||
using namespace cif::literals;
|
||||
|
||||
const std::filesystem::path example(gTestDir / ".." / "examples" / "1cbs.cif.gz");
|
||||
cif::file file(example.string());
|
||||
|
||||
auto &db = file.front();
|
||||
|
||||
cif::mm::structure s(file);
|
||||
|
||||
for (auto atom : s.atoms())
|
||||
CHECK_FALSE(atom.is_alternate());
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Tests for structure_open_options
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ TEST_CASE("t2")
|
||||
|
||||
cif::point xp = cif::cross_product(p[1] - p[0], p[2] - p[0]);
|
||||
|
||||
auto q = cif::construct_from_angle_axis(45, xp); // mmcif::Normalize(Quaternion{45 * mmcif::kPI / 180, xp.mX, xp.mY, xp.mZ});
|
||||
auto q = cif::construct_from_angle_axis(45, xp);
|
||||
|
||||
auto &&[angle, axis] = cif::quaternion_to_angle_axis(q);
|
||||
|
||||
@@ -134,7 +134,7 @@ TEST_CASE("t3")
|
||||
|
||||
cif::point xp = cif::cross_product(p[1] - p[0], p[2] - p[0]);
|
||||
|
||||
auto q = cif::construct_from_angle_axis(45, xp); // mmcif::Normalize(Quaternion{45 * mmcif::kPI / 180, xp.mX, xp.mY, xp.mZ});
|
||||
auto q = cif::construct_from_angle_axis(45, xp);
|
||||
|
||||
auto v = p[1];
|
||||
v -= p[0];
|
||||
|
||||
Reference in New Issue
Block a user