10#ifndef GEMMI_BLOB_HPP_
11#define GEMMI_BLOB_HPP_
36struct GridConstPoint {
41inline Blob make_blob_of_points(
const std::vector<GridConstPoint>& points,
43 const BlobCriteria& criteria) {
45 if (points.size() < 3)
47 double volume_per_point = grid.unit_cell.
volume / grid.point_count();
48 double volume = points.size() * volume_per_point;
49 if (volume < criteria.min_volume)
51 double sum[3] = {0., 0., 0.};
52 const GridConstPoint* peak_point = &points[0];
53 blob.peak_value = points[0].
value;
55 for (
const GridConstPoint& point : points) {
57 if (point.value > blob.peak_value) {
58 blob.peak_value = point.value;
61 sum[0] += double(point.u) * point.value;
62 sum[1] += double(point.v) * point.value;
63 sum[2] += double(point.w) * point.value;
65 if (blob.peak_value < criteria.min_peak)
67 blob.score = score * volume_per_point;
68 if (blob.score < criteria.min_score)
71 sum[1] / (score * grid.nv),
72 sum[2] / (score * grid.nw));
73 blob.centroid = grid.unit_cell.orthogonalize(fract);
74 blob.peak_pos = grid.get_position(peak_point->u, peak_point->v, peak_point->w);
85 std::vector<Blob>
blobs;
86 std::array<std::array<int, 3>, 6>
moves = {{{{-1, 0, 0}}, {{1, 0, 0}},
87 {{0 ,-1, 0}}, {{0, 1, 0}},
88 {{0, 0, -1}}, {{0, 0, 1}}}};
92 std::vector<gemmi::GridOp>
ops = grid.get_scaled_ops_except_id();
94 for (
int w = 0; w != grid.nw; ++w)
95 for (
int v = 0; v != grid.nv; ++v)
96 for (
int u = 0; u != grid.nu; ++u, ++idx) {
97 assert(idx == grid.index_q(u, v, w));
100 float value = grid.data[idx];
105 std::vector<impl::GridConstPoint> points;
106 points.push_back({u, v, w, value});
108 for (
size_t j = 0;
j < points.size(); ++
j)
109 for (
const std::array<int, 3>&
mv :
moves) {
135 [](
const Blob& a,
const Blob& b) { return a.score > b.score; });
std::vector< Blob > find_blobs_by_flood_fill(const gemmi::Grid< float > &grid, const BlobCriteria &criteria, bool negate=false)
std::vector< V > get_asu_mask(const GridMeta &grid)
Coordinates in Angstroms - orthogonal (Cartesian) coordinates.