// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "UnitCell.h" #include #include bool UnitCell::is_finite() const { return std::isfinite(a) && std::isfinite(b) && std::isfinite(c) && std::isfinite(alpha) && std::isfinite(beta) && std::isfinite(gamma); } bool UnitCell::is_close(const UnitCell &ref, float dist_tolerance, float angle_tolerance_deg) const { if (!is_finite() || !ref.is_finite()) return false; constexpr float min_length = 1e-6f; if (std::fabs(a - ref.a) / std::max(std::fabs(ref.a), min_length) > dist_tolerance) return false; if (std::fabs(b - ref.b) / std::max(std::fabs(ref.b), min_length) > dist_tolerance) return false; if (std::fabs(c - ref.c) / std::max(std::fabs(ref.c), min_length) > dist_tolerance) return false; if (std::fabs(alpha - ref.alpha) > angle_tolerance_deg) return false; if (std::fabs(beta - ref.beta) > angle_tolerance_deg) return false; if (std::fabs(gamma - ref.gamma) > angle_tolerance_deg) return false; return true; } std::ostream &operator<<(std::ostream &output, const UnitCell &in) { output << in.a << " " << in.b << " " << in.c; output << " " << in.alpha << " " << in.beta << " " << in.gamma; return output; } std::optional MeanUnitCell(const std::vector &cells) { if (cells.empty()) return {}; UnitCell ret{}; for (const auto &cell: cells) { ret.a += cell.a; ret.b += cell.b; ret.c += cell.c; ret.alpha += cell.alpha; ret.beta += cell.beta; ret.gamma += cell.gamma; } const auto scale = 1.0f / static_cast(cells.size()); ret.a *= scale; ret.b *= scale; ret.c *= scale; ret.alpha *= scale; ret.beta *= scale; ret.gamma *= scale; return ret; } UnitCell::operator gemmi::UnitCell() const { return {a, b, c, alpha, beta, gamma}; }