5#ifndef GEMMI_UNITCELL_HPP_
6#define GEMMI_UNITCELL_HPP_
61 return {x - std::floor(x), y - std::floor(y), z - std::floor(z)};
64 return {x - std::round(x), y - std::round(y), z - std::round(z)};
67 return {std::round(x), std::round(y), std::round(z)};
70 if (x > 0.5) x -= 1.0;
else if (x < -0.5) x += 1.0;
71 if (y > 0.5) y -= 1.0;
else if (y < -0.5) y += 1.0;
72 if (z > 0.5) z -= 1.0;
else if (z < -0.5) z += 1.0;
91 std::string s = std::to_string(
sym_idx + 1);
98 s +=
char(
'5' +
shift);
100 for (
int i = 0;
i < 3; ++
i) {
132 return std::size_t((hkl[0] * 1024 + hkl[1]) * 1024 + hkl[2]);
146 set(v[0], v[1], v[2], v[3], v[4], v[5]);
148 double a = 1.0,
b = 1.0,
c = 1.0;
167 return a ==
o.a &&
b ==
o.b &&
c ==
o.c &&
173 auto eq = [&](
double x,
double y) {
return std::fabs(x - y) <
epsilon; };
180 auto siml = [&](
double x,
double y) {
return std::fabs(x - y) <
rel * std::max(x, y); };
181 auto sima = [&](
double x,
double y) {
return std::fabs(x - y) <
deg; };
195 fail(
"Impossible angle - N*180deg.");
273 if (
frac.
mat[0][0] == 1.0 && (f.
mat[0][0] == 0.0 || f.
mat[0][0] > 1.0))
294 set(
va.length(),
vb.length(),
vc.length(),
322 std::array<double,6> other = {{
323 m.column_dot(0,0),
m.column_dot(1,1),
m.column_dot(2,2),
324 m.column_dot(1,2),
m.column_dot(0,2),
m.column_dot(0,1)
326 for (
int i = 0;
i < 6; ++
i)
365 std::vector<FTransform> ncs;
427 for (
int j = 0;
j < 3; ++
j)
437 for (
int j = 0;
j < 3; ++
j)
449 image.dist_sq = ref.dist_sq(pos);
456 image.pbc_shift[0] == 0 &&
image.pbc_shift[1] == 0 &&
image.pbc_shift[2] == 0)
458 for (
int n = 0; n !=
static_cast<int>(
images.size()); ++n)
460 image.sym_idx = n + 1;
475 int image_idx)
const {
484 int image_idx)
const {
495 int image_idx,
bool inverse=
false)
const {
556 auto acosd = [](
double x) {
return deg(std::acos(x)); };
566 if (centring_type ==
'P')
constexpr double deg(double angle)
Op::Rot centred_to_primitive(char centring_type)
std::array< int, 3 > Miller
A synonym for convenient passing of hkl.
Mat33 rot_as_mat33(const Op::Rot &rot)
Vec3 operator*(double d, const Vec3 &v)
constexpr double rad(double angle)
constexpr float sq(float x)
void fail(const std::string &msg)
Vec3 tran_as_vec3(const Op &op)
Fractional wrap_to_unit() const
void move_toward_zero_by_one()
Fractional(const Vec3 &v)
Fractional operator-(const Fractional &o) const
Fractional operator+(const Fractional &o) const
Fractional wrap_to_zero() const
std::vector< Op > sym_ops
Vec3 column_copy(int i) const
bool approx(const Mat33 &other, double epsilon) const
Vec3 multiply(const Vec3 &p) const
std::size_t operator()(const Miller &hkl) const noexcept
Non-crystallographic symmetry operation (such as in the MTRIXn record)
Position apply(const Position &p) const
Result of find_nearest_image.
std::string symmetry_code(bool underscore) const
Returns a string such as 1555 or 1_555.
std::array< std::array< int, 3 >, 3 > Rot
static constexpr Op identity()
Coordinates in Angstroms - orthogonal (Cartesian) coordinates.
Position operator*(double d) const
Position operator/(double d) const
Position & operator+=(const Position &o)
Position operator-(const Position &o) const
Position & operator*=(double d)
Position operator+(const Position &o) const
Position operator-() const
Position & operator-=(const Position &o)
Position & operator/=(double d)
std::array< T, 6 > elements_voigt() const
double calculate_d(const Miller &hkl) const
Calculate d-spacing.
double distance_sq(const Fractional &pos1, const Fractional &pos2) const
NearestImage find_nearest_image(const Position &ref, const Position &pos, Asu asu) const
UnitCell changed_basis_backward(const Op &op, bool set_images)
bool operator==(const UnitCell &o) const
std::vector< FTransform > get_ncs_transforms() const
UnitCell reciprocal() const
Returns reciprocal unit cell.
UnitCell(const std::array< double, 6 > &v)
double calculate_u_eq(const SMat33< double > &ani) const
The equivalent isotropic displacement factor.
Position find_nearest_pbc_position(const Position &ref, const Position &pos, int image_idx, bool inverse=false) const
void calculate_properties()
SMat33< double > metric_tensor() const
https://dictionary.iucr.org/Metric_tensor
double ar
reciprocal parameters a*, b*, c*, alpha*, beta*, gamma*
Fractional fractionalize(const Position &o) const
double calculate_stol_sq(const Miller &hkl) const
Calculate (sin(theta)/lambda)^2 = d*^2/4.
NearestImage find_nearest_pbc_image(const Fractional &fref, Fractional fpos, int image_idx) const
void set_matrices_from_fract(const Transform &f)
double distance_sq(const Position &pos1, const Position &pos2) const
Transform op_as_transform(const Op &op) const
Mat33 calculate_matrix_B() const
B matrix following convention from Busing & Levy (1967), not from cctbx.
void set(double a_, double b_, double c_, double alpha_, double beta_, double gamma_)
UnitCell(double a_, double b_, double c_, double alpha_, double beta_, double gamma_)
bool is_compatible_with_groupops(const GroupOps &gops, double eps=1e-3)
Miller get_hkl_limits(double dmin) const
void apply_transform(Fractional &fpos, int image_idx, bool inverse) const
void set_from_vectors(const Vec3 &va, const Vec3 &vb, const Vec3 &vc)
Mat33 primitive_orth_matrix(char centring_type) const
Position orthogonalize(const Fractional &f) const
double volume_per_image() const
void add_ncs_images_to_cs_images(const std::vector< NcsOp > &ncs)
double calculate_1_d2_double(double h, double k, double l) const
Calculate 1/d^2 for specified hkl reflection.
NearestImage find_nearest_pbc_image(const Position &ref, const Position &pos, int image_idx) const
bool search_pbc_images(Fractional &&diff, NearestImage &image) const
UnitCell changed_basis_forward(const Op &op, bool set_images)
double calculate_1_d2(const Miller &hkl) const
std::vector< FTransform > images
Position orthogonalize_difference(const Fractional &delta) const
orthogonalize_difference(a-b) == orthogonalize(a) - orthogonalize(b)
bool is_compatible_with_spacegroup(const SpaceGroup *sg, double eps=1e-3)
void set_cell_images_from_spacegroup(const SpaceGroup *sg)
int is_special_position(const Position &pos, double max_dist=0.8) const
int is_special_position(const Fractional &fpos, double max_dist) const
Counts nearby symmetry mates (0 = none, 3 = 4-fold axis, etc).
SMat33< double > reciprocal_metric_tensor() const
bool operator!=(const UnitCell &o) const
bool is_similar(const UnitCell &o, double rel, double deg) const
Box< Position > orthogonalize_box(const Box< Fractional > &f) const
Returns box containing fractional box (a cuboid in fractional coordinates can be a parallelepiped in ...
Fractional fractionalize_difference(const Position &delta) const
the inverse of orthogonalize_difference
Position orthogonalize_in_pbc(const Position &ref, const Fractional &fpos) const
bool approx(const UnitCell &o, double epsilon) const