5#ifndef GEMMI_ASUMASK_HPP_
6#define GEMMI_ASUMASK_HPP_
17 static constexpr int denom = 24;
25 std::string
str()
const {
27 for (
int i = 0;
i < 3; ++
i) {
32 s +=
incl[
i] ?
"<=" :
"<";
55 fail(
"grid is not fully setup");
58 auto iceil = [](
double x) {
return int(x) + 1; };
67 fail(
"Missing space group");
69 using Point = std::array<int, 3>;
83 const std::vector<GridOp>
ops = grid.get_scaled_ops_except_id();
127 auto is_in = [&](
const Point&
p) {
137 grid.index_n_ref(
t[0],
t[1],
t[2]);
146 for (;
it != end; ++
it)
156 for (
int w = 0; w <
w_lim; ++w)
157 for (
int v = 0; v <
v_lim; ++v)
158 for (
int u = 0; u <
u_lim; ++u) {
159 size_t idx = grid.index_q(u, v, w);
160 if (grid.data[idx] == 0) {
163 Point
t = op.apply(u, v, w);
172 for (
size_t n = 0; n != grid.data.size(); ++n)
173 if (grid.data[n] == 0) {
174 auto p = grid.index_to_point(n);
175 printf(
"[debug1] %d %d %d is missing\n",
p.u,
p.v,
p.w);
179 printf(
"[debug2] checkpoints failed\n");
181 return !
in_vector(std::int8_t(0), grid.data);
197 return a.volume < b.volume ||
198 (a.volume == b.volume && a.size[0] + a.size[1] + a.size[2] <
199 b.size[0] + b.size[1] + b.size[2]);
203 for (
int i = 0;
i < 3; ++
i) {
216template<
typename T,
typename V=std::
int8_t>
struct MaskedGrid {
239template<
typename V=std::
int8_t>
244 for (
int w = 0; w < end[2]; ++w)
245 for (
int v = 0; v < end[1]; ++v)
246 for (
int u = 0; u < end[0]; ++u) {
247 size_t idx = grid.
index_q(u, v, w);
248 if (mask[idx] == 2) {
251 std::array<int, 3>
t = op.apply(u, v, w);
259 if (std::find(mask.begin(), mask.end(), 2) != mask.end())
260 fail(
"get_asu_mask(): internal error");
274inline std::pair<int, int> trim_false_values(
const std::vector<bool>& vec) {
275 const int n = (int) vec.size();
277 std::pair<int, int> span{n, n};
280 if (!vec[0] || !vec[n-1]) {
282 while (span.first != 0 && !vec[span.first-1])
288 while (span.second != n && !vec[span.second])
290 max_trim = span.second + (n - span.first);
292 for (
int start = 0; ;) {
301 while (end != n && !vec[end])
303 if (end - start > max_trim) {
304 max_trim = end - start;
317 grid.check_not_empty();
318 std::vector<bool> nonzero[3];
319 nonzero[0].resize(grid.nu,
false);
320 nonzero[1].resize(grid.nv,
false);
321 nonzero[2].resize(grid.nw,
false);
323 for (
int w = 0; w != grid.nw; ++w)
324 for (
int v = 0; v != grid.nv; ++v)
325 for (
int u = 0; u != grid.nu; ++u, ++idx) {
326 T val = grid.data[idx];
327 if (!(impl::is_nan(val) || val == 0)) {
328 nonzero[0][u] =
true;
329 nonzero[1][v] =
true;
330 nonzero[2][w] =
true;
334 for (
int i = 0;
i < 3; ++
i) {
335 auto span = impl::trim_false_values(nonzero[
i]);
336 double inv_n = 1.0 / nonzero[
i].size();
337 box.minimum.at(
i) = (span.second - 0.5) *
inv_n -
int(span.second >= span.first);
338 box.maximum.at(
i) = (span.first - 0.5) *
inv_n;
3d grids used by CCP4 maps, cell-method search and hkl data.
MaskedGrid< T > masked_asu(Grid< T > &grid)
GEMMI_DLL void append_op_fraction(std::string &s, int w)
bool in_vector(const T &x, const std::vector< T > &v)
AsuBrick find_asu_brick(const SpaceGroup *sg)
Box< Fractional > get_nonzero_extent(const GridBase< T > &grid)
void fail(const std::string &msg)
std::vector< V > get_asu_mask(const GridMeta &grid)
std::array< int, 3 > size
Box< Fractional > get_extent() const
Fractional get_upper_limit() const
std::array< bool, 3 > incl
static constexpr int denom
std::array< int, 3 > uvw_end(const GridMeta &meta) const
AsuBrick(int a, int b, int c)
grid coordinates (modulo size) and a pointer to value
bool operator!=(const iterator &o) const
iterator(typename GridBase< T >::iterator it, const std::vector< V > &mask)
GridBase< T >::Point operator*()
const std::vector< V > & mask_ref
GridBase< T >::iterator grid_iterator
bool operator==(const iterator &o) const
Utilities. Mostly for working with strings and vectors.