OpenMS
Loading...
Searching...
No Matches
GridBasedClustering.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Lars Nilse $
6// $Authors: Lars Nilse, Johannes Veit $
7// --------------------------------------------------------------------------
8
9#pragma once
10
17
18#include <cmath>
19#include <limits>
20#include <map>
21#include <set>
22#include <queue>
23#include <vector>
24#include <algorithm>
25#include <iostream>
26#include <unordered_map>
27
28namespace OpenMS
29{
30
34 class OPENMS_DLLAPI MinimumDistance
35 {
36public:
37
41 MinimumDistance(const int& cluster_index, const int& nearest_neighbour_index, const double& distance);
42
46 int getClusterIndex() const;
47
52
57 bool operator<(const MinimumDistance& other) const
58 {
59 return distance_ < other.distance_;
60 }
61 bool operator>(const MinimumDistance& other) const;
62 bool operator==(const MinimumDistance& other) const;
63
64private:
65
68
73
78
82 double distance_;
83
84 };
85
101 template <typename Metric>
103 public ProgressLogger
104 {
105public:
109 typedef GridBasedCluster::Point Point; // DPosition<2>
110 typedef GridBasedCluster::Rectangle Rectangle; // DBoundingBox<2>
111 typedef ClusteringGrid::CellIndex CellIndex; // std::pair<int,int>
112 typedef std::multiset<MinimumDistance>::const_iterator MultisetIterator;
113 typedef std::unordered_multimap<int, MultisetIterator>::const_iterator NNIterator;
114
126 GridBasedClustering(Metric metric, const std::vector<double>& data_x,
127 const std::vector<double>& data_y, const std::vector<int>& properties_A,
128 const std::vector<int>& properties_B, std::vector<double> grid_spacing_x,
129 std::vector<double> grid_spacing_y) :
130 metric_(metric),
131 grid_(grid_spacing_x, grid_spacing_y)
132 {
133 init_(data_x, data_y, properties_A, properties_B);
134 }
135
145 GridBasedClustering(Metric metric, const std::vector<double>& data_x,
146 const std::vector<double>& data_y, std::vector<double> grid_spacing_x,
147 std::vector<double> grid_spacing_y) :
148 metric_(metric),
149 grid_(grid_spacing_x, grid_spacing_y)
150 {
151 // set properties A and B to -1, i.e. ignore properties when clustering
152 std::vector<int> properties_A(data_x.size(), -1);
153 std::vector<int> properties_B(data_x.size(), -1);
154 init_(data_x, data_y, properties_A, properties_B);
155 }
156
161 void cluster()
162 {
163 // progress logger
164 // NOTE: for some reason, gcc7 chokes if we remove the std::string
165 // below, so lets just not change it.
166 Size clusters_start = clusters_.size();
167 startProgress(0, clusters_start, std::string("clustering"));
168
169 MinimumDistance zero_distance(-1, -1, 0);
170
171 // combine clusters until all have been moved to the final list
172 while (!clusters_.empty())
173 {
174 setProgress(clusters_start - clusters_.size());
175
176 MultisetIterator smallest_distance_it = distances_.lower_bound(zero_distance);
177
178 int cluster_index1 = smallest_distance_it->getClusterIndex();
179 int cluster_index2 = smallest_distance_it->getNearestNeighbourIndex();
180
181 eraseMinDistance_(smallest_distance_it);
182
183 // update cluster list
184 std::map<int, GridBasedCluster>::iterator cluster1_it = clusters_.find(cluster_index1);
185 std::map<int, GridBasedCluster>::iterator cluster2_it = clusters_.find(cluster_index2);
186 const GridBasedCluster& cluster1 = cluster1_it->second;
187 const GridBasedCluster& cluster2 = cluster2_it->second;
188 const std::vector<int>& points1 = cluster1.getPoints();
189 const std::vector<int>& points2 = cluster2.getPoints();
190 std::vector<int> new_points;
191 new_points.reserve(points1.size() + points2.size());
192 new_points.insert(new_points.end(), points1.begin(), points1.end());
193 new_points.insert(new_points.end(), points2.begin(), points2.end());
194
195 double new_x = (cluster1.getCentre().getX() * points1.size() + cluster2.getCentre().getX() * points2.size()) / (points1.size() + points2.size());
196 double new_y = (cluster1.getCentre().getY() * points1.size() + cluster2.getCentre().getY() * points2.size()) / (points1.size() + points2.size());
197
198 // update grid
199 CellIndex cell_for_cluster1 = grid_.getIndex(cluster1.getCentre());
200 CellIndex cell_for_cluster2 = grid_.getIndex(cluster2.getCentre());
201 CellIndex cell_for_new_cluster = grid_.getIndex(DPosition<2>(new_x, new_y));
202 grid_.removeCluster(cell_for_cluster1, cluster_index1);
203 grid_.removeCluster(cell_for_cluster2, cluster_index2);
204 grid_.addCluster(cell_for_new_cluster, cluster_index1);
205
206 // merge clusters
207 const Rectangle& box1 = cluster1.getBoundingBox();
208 const Rectangle& box2 = cluster2.getBoundingBox();
209 Rectangle new_box(box1);
210 new_box.enlarge(box2.minPosition());
211 new_box.enlarge(box2.maxPosition());
212
213 // Properties A of both clusters should by now be the same. The merge veto has been checked
214 // when a new entry to the minimum distance list was added, @see findNearestNeighbour_.
215 if (cluster1.getPropertyA() != cluster2.getPropertyA())
216 {
217 throw Exception::InvalidValue(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Property A of both clusters not the same. ", "A");
218 }
219 int new_A = cluster1.getPropertyA();
220
221 const std::vector<int>& B1 = cluster1.getPropertiesB();
222 const std::vector<int>& B2 = cluster2.getPropertiesB();
223 std::vector<int> new_B;
224 new_B.reserve(B1.size() + B2.size());
225 new_B.insert(new_B.end(), B1.begin(), B1.end());
226 new_B.insert(new_B.end(), B2.begin(), B2.end());
227
228 GridBasedCluster new_cluster(DPosition<2>(new_x, new_y), new_box, std::move(new_points), new_A, std::move(new_B));
229
230 // the merged cluster takes the place (index) of cluster 1
231 cluster1_it->second = std::move(new_cluster);
232 centres_[cluster_index1] = cluster1_it->second.getCentre();
233 clusters_.erase(cluster2_it);
234
235 std::set<int> clusters_to_be_updated;
236 clusters_to_be_updated.insert(cluster_index1);
237
238 // erase distance object of cluster with cluster_index2 without updating (does not exist anymore!)
239 // (the one with cluster_index1 has already been erased at the top of the while loop)
241
242 // find out which clusters need to be updated
243 std::pair<NNIterator, NNIterator> nn_range = reverse_nns_.equal_range(cluster_index1);
244 for (NNIterator nn_it = nn_range.first; nn_it != nn_range.second;)
245 {
246 clusters_to_be_updated.insert(nn_it->second->getClusterIndex());
247 eraseMinDistance_((nn_it++)->second);
248 }
249 nn_range = reverse_nns_.equal_range(cluster_index2);
250 for (NNIterator nn_it = nn_range.first; nn_it != nn_range.second;)
251 {
252 clusters_to_be_updated.insert(nn_it->second->getClusterIndex());
253 eraseMinDistance_((nn_it++)->second);
254 }
255
256 // update clusters
257 for (std::set<int>::const_iterator cluster_index = clusters_to_be_updated.begin(); cluster_index != clusters_to_be_updated.end(); ++cluster_index)
258 {
259 std::map<int, GridBasedCluster>::iterator c_it = clusters_.find(*cluster_index);
260 const GridBasedCluster& c = c_it->second;
261 if (findNearestNeighbour_(c, *cluster_index))
262 {
263 grid_.removeCluster(grid_.getIndex(c.getCentre()), *cluster_index); // remove from grid
264 clusters_.erase(c_it); // remove from cluster list
265 }
266 }
267 }
268
269 endProgress();
270 }
271
277 {
278
279 // construct new grid (grid only in x-direction, single cell in y-direction)
280 std::vector<double> grid_spacing_x = grid_.getGridSpacingX();
281 std::vector<double> grid_spacing_y = grid_.getGridSpacingY();
282 std::vector<double> grid_spacing_y_new;
283 grid_spacing_y_new.push_back(grid_spacing_y.front());
284 grid_spacing_y_new.push_back(grid_spacing_y.back());
285 ClusteringGrid grid_x_only(grid_spacing_x, grid_spacing_y_new);
286
287 // register final clusters on the new grid
288 for (std::map<int, GridBasedCluster>::const_iterator it = clusters_final_.begin(); it != clusters_final_.end(); ++it)
289 {
290 int cluster_index = it->first;
291 GridBasedCluster cluster = it->second;
292 grid_x_only.addCluster(grid_x_only.getIndex(cluster.getCentre()), cluster_index);
293 }
294
295
296 // scan through x on the grid
297 for (unsigned cell = 0; cell < grid_spacing_x.size(); ++cell)
298 {
299 CellIndex grid_index(cell, 1);
300 if (grid_x_only.isNonEmptyCell(grid_index))
301 {
302 std::list<int> cluster_indices = grid_x_only.getClusters(grid_index); // indices of clusters in this x-range
303 if (cluster_indices.size() > 1)
304 {
305 // First, order the clusters in ascending y.
306 std::list<GridBasedCluster> cluster_list; // list to order clusters in y
307 std::map<GridBasedCluster, int> index_list; // allows us to keep track of cluster indices after sorting
308 for (std::list<int>::const_iterator it = cluster_indices.begin(); it != cluster_indices.end(); ++it)
309 {
310 cluster_list.push_back(clusters_final_.find(*it)->second);
311 index_list.insert(std::make_pair(clusters_final_.find(*it)->second, *it));
312 }
313 cluster_list.sort();
314
315 // Now check if two adjacent clusters c1 and c2 can be merged.
316 std::list<GridBasedCluster>::const_iterator c1 = cluster_list.begin();
317 std::list<GridBasedCluster>::const_iterator c2 = cluster_list.begin();
318 ++c1;
319 while (c1 != cluster_list.end())
320 {
321 double centre1x = (*c1).getCentre().getX();
322 double centre1y = (*c1).getCentre().getY();
323 double centre2x = (*c2).getCentre().getX();
324 double centre2y = (*c2).getCentre().getY();
325
326 double box1x_min = (*c1).getBoundingBox().minX();
327 double box1x_max = (*c1).getBoundingBox().maxX();
328 double box1y_min = (*c1).getBoundingBox().minY();
329 double box1y_max = (*c1).getBoundingBox().maxY();
330 double box2x_min = (*c2).getBoundingBox().minX();
331 double box2x_max = (*c2).getBoundingBox().maxX();
332 double box2y_min = (*c2).getBoundingBox().minY();
333 double box2y_max = (*c2).getBoundingBox().maxY();
334
335 //double y_range1 = box1y_max - box1y_min;
336 //double y_range2 = box2y_max - box2y_min;
337 //double y_gap = box1y_min - box2y_max;
338
339 // Is there an overlap of the two clusters in x?
340 bool overlap = (box1x_min <= box2x_max && box1x_min >= box2x_min) || (box1x_max >= box2x_min && box1x_max <= box2x_max);
341
342 // Is the x-centre of one cluster in the x-range of the other?
343 //bool centre_in_range1 = (box2x_min <= centre1x && centre1x <= box2x_max);
344 //bool centre_in_range2 = (box1x_min <= centre2x && centre2x <= box1x_max);
345
346 // Is the y-gap between the two clusters smaller than 1/s of their average y-range?
347 //double s = 6; // scaling factor
348 //bool clusters_close = (y_gap * s <= (y_range1 - y_range2)/2);
349
350 // Shall we merge the two adjacent clusters?
351 //if ((centre_in_range1 || centre_in_range2) && clusters_close)
352 if (overlap)
353 {
354 std::vector<int> points1 = (*c1).getPoints();
355 std::vector<int> points2 = (*c2).getPoints();
356 std::vector<int> new_points;
357 new_points.reserve(points1.size() + points2.size());
358 new_points.insert(new_points.end(), points1.begin(), points1.end());
359 new_points.insert(new_points.end(), points2.begin(), points2.end());
360
361 double new_x = (centre1x * points1.size() + centre2x * points2.size()) / (points1.size() + points2.size());
362 double new_y = (centre1y * points1.size() + centre2y * points2.size()) / (points1.size() + points2.size());
363
364 double min_x = std::min(box1x_min, box2x_min);
365 double min_y = std::min(box1y_min, box2y_min);
366 double max_x = std::max(box1x_max, box2x_max);
367 double max_y = std::max(box1y_max, box2y_max);
368
369 Point new_centre(new_x, new_y);
370 Point position_min(min_x, min_y);
371 Point position_max(max_x, max_y);
372 Rectangle new_bounding_box(position_min, position_max);
373
374 GridBasedCluster new_cluster(new_centre, new_bounding_box, new_points);
375
376 // update final cluster list
377 clusters_final_.erase(clusters_final_.find(index_list.find(*c1)->second));
378 clusters_final_.erase(clusters_final_.find(index_list.find(*c2)->second));
379 clusters_final_.insert(std::make_pair(index_list.find(*c1)->second, new_cluster));
380
381 // update grid
382 CellIndex cell_for_cluster1 = grid_x_only.getIndex((*c1).getCentre());
383 CellIndex cell_for_cluster2 = grid_x_only.getIndex((*c2).getCentre());
384 CellIndex cell_for_new_cluster = grid_x_only.getIndex(new_centre);
385
386 grid_x_only.removeCluster(cell_for_cluster1, index_list.find(*c1)->second);
387 grid_x_only.removeCluster(cell_for_cluster2, index_list.find(*c2)->second);
388 grid_x_only.addCluster(cell_for_new_cluster, index_list.find(*c1)->second);
389 }
390 ++c1;
391 ++c2;
392 }
393 }
394 }
395 }
396
397 }
398
403 void removeSmallClustersY(double threshold_y)
404 {
405 std::map<int, GridBasedCluster>::iterator it = clusters_final_.begin();
406 while (it != clusters_final_.end())
407 {
408 Rectangle box = it->second.getBoundingBox();
409 if (box.maxY() - box.minY() < threshold_y)
410 {
411 it = clusters_final_.erase(it);
412 }
413 else
414 {
415 ++it;
416 }
417 }
418 }
419
423 std::map<int, GridBasedCluster> getResults() const
424 {
425 return clusters_final_;
426 }
427
428private:
429
433 Metric metric_;
434
440
445 std::map<int, GridBasedCluster> clusters_;
446
451 std::map<int, GridBasedCluster> clusters_final_;
452
457 std::vector<Point> centres_;
458
463 std::multiset<MinimumDistance> distances_;
464
469 std::unordered_multimap<int, std::multiset<MinimumDistance>::const_iterator> reverse_nns_;
470
475 std::unordered_map<int, std::multiset<MinimumDistance>::const_iterator> distance_it_for_cluster_idx_;
476
485 void init_(const std::vector<double>& data_x, const std::vector<double>& data_y,
486 const std::vector<int>& properties_A, const std::vector<int>& properties_B)
487 {
488 // fill the grid with points to be clustered (initially each cluster contains a single point)
489 centres_.resize(data_x.size());
490 for (unsigned i = 0; i < data_x.size(); ++i)
491 {
492 Point position(data_x[i], data_y[i]);
493 centres_[i] = position;
494 Rectangle box(position, position);
495
496 std::vector<int> pi; // point indices
497 pi.push_back(i);
498 std::vector<int> pb; // properties B
499 pb.push_back(properties_B[i]);
500
501 // add to cluster list
502 GridBasedCluster cluster(position, box, pi, properties_A[i], pb);
503 clusters_.insert(std::make_pair(i, cluster));
504
505 // register on grid
506 grid_.addCluster(grid_.getIndex(position), i);
507 }
508
509 // fill list of minimum distances
510 std::map<int, GridBasedCluster>::iterator iterator = clusters_.begin();
511 while (iterator != clusters_.end())
512 {
513 int cluster_index = iterator->first;
514 const GridBasedCluster& cluster = iterator->second;
515
516 if (findNearestNeighbour_(cluster, cluster_index))
517 {
518 // remove from grid
519 grid_.removeCluster(grid_.getIndex(cluster.getCentre()), cluster_index);
520 // remove from cluster list
521 iterator = clusters_.erase(iterator);
522 }
523 else
524 {
525 ++iterator;
526 }
527 }
528 }
529
543 bool mergeVeto_(const GridBasedCluster& c1, const GridBasedCluster& c2) const
544 {
545 int A1 = c1.getPropertyA();
546 int A2 = c2.getPropertyA();
547
548 // check if properties A of both clusters is set or not (not set := -1)
549 if (A1 == -1 || A2 == -1)
550 {
551 return false;
552 }
553
554 // Will the merged cluster have the same properties A?
555 if (A1 != A2) return true;
556
557 std::vector<int> B1 = c1.getPropertiesB();
558 std::vector<int> B2 = c2.getPropertiesB();
559
560 // check if properties B of both clusters is set or not (not set := -1)
561 if (std::find(B1.begin(), B1.end(), -1) != B1.end() || std::find(B2.begin(), B2.end(), -1) != B2.end())
562 {
563 return false;
564 }
565
566 // Will the merged cluster have different properties B?
567 // (Hence the intersection of properties B of cluster 1 and cluster 2 should be empty.)
568 std::vector<int> B_intersection;
569 sort(B1.begin(), B1.end());
570 sort(B2.begin(), B2.end());
571 set_intersection(B1.begin(), B1.end(), B2.begin(), B2.end(), back_inserter(B_intersection));
572
573 return !B_intersection.empty();
574 }
575
589 bool findNearestNeighbour_(const GridBasedCluster& cluster, int cluster_index)
590 {
591 const Point& centre = cluster.getCentre();
592 const CellIndex& cell_index = grid_.getIndex(centre);
593 double min_dist = 0;
594 int nearest_neighbour = -1;
595
596 // search in the grid cell and its 8 neighbouring cells for the nearest neighbouring cluster
597 for (int i = -1; i <= 1; ++i)
598 {
599 for (int j = -1; j <= 1; ++j)
600 {
601 CellIndex cell_index2(cell_index);
602 cell_index2.first += i;
603 cell_index2.second += j;
604 // (empty for a cell without clusters)
605 const std::list<int>& cluster_indices = grid_.getClusters(cell_index2);
606 for (std::list<int>::const_iterator cluster_index2 = cluster_indices.begin(); cluster_index2 != cluster_indices.end(); ++cluster_index2)
607 {
608 if (*cluster_index2 != cluster_index)
609 {
610 const Point& centre2 = centres_[*cluster_index2];
611 double distance = metric_(centre, centre2);
612
613 if (distance < min_dist || nearest_neighbour == -1)
614 {
615 // If clusters cannot be merged anyhow, they are no nearest neighbours.
616 // (Without property A, cluster can be merged with any other, see mergeVeto_().)
617 bool veto = cluster.getPropertyA() != -1 && mergeVeto_(cluster, clusters_.find(*cluster_index2)->second);
618 if (!veto)
619 {
620 min_dist = distance;
621 nearest_neighbour = *cluster_index2;
622 }
623 }
624 }
625 }
626 }
627 }
628
629 if (nearest_neighbour == -1)
630 {
631 // no other cluster nearby, hence move the cluster to the final results
632 clusters_final_.insert(std::make_pair(cluster_index, clusters_.find(cluster_index)->second));
633 return true;
634 }
635
636 // add to the list of minimal distances
637 std::multiset<MinimumDistance>::const_iterator it = distances_.insert(MinimumDistance(cluster_index, nearest_neighbour, min_dist));
638 // add to reverse nearest neighbor lookup table
639 reverse_nns_.insert(std::make_pair(nearest_neighbour, it));
640 // add to cluster index -> distance lookup table
641 distance_it_for_cluster_idx_[cluster_index] = it;
642
643 return false;
644 }
645
655 void eraseMinDistance_(const std::multiset<MinimumDistance>::const_iterator it)
656 {
657 // remove corresponding entries from nearest neighbor lookup table
658 std::pair<NNIterator, NNIterator> nn_range = reverse_nns_.equal_range(it->getNearestNeighbourIndex());
659 for (NNIterator nn_it = nn_range.first; nn_it != nn_range.second; ++nn_it)
660 {
661 if (nn_it->second == it)
662 {
663 reverse_nns_.erase(nn_it);
664 break;
665 }
666 }
667
668 // remove corresponding entry from cluster index -> distance lookup table
669 distance_it_for_cluster_idx_.erase(it->getClusterIndex());
670
671 // remove from distances_
672 distances_.erase(it);
673 }
674 };
675}
data structure to store 2D data to be clustered e.g. (m/z, retention time) coordinates from multiplex...
Definition ClusteringGrid.h:30
CellIndex getIndex(const Point &position) const
returns grid cell index (i,j) for the positions (x,y)
void removeCluster(const CellIndex &cell_index, const int &cluster_index)
removes a cluster from this grid cell and removes the cell if no other cluster left
const std::list< int > & getClusters(const CellIndex &cell_index) const
returns clusters in this grid cell
std::vector< double > getGridSpacingY() const
returns grid spacing in y direction
std::pair< int, int > CellIndex
Definition ClusteringGrid.h:35
bool isNonEmptyCell(const CellIndex &cell_index) const
checks if there are clusters at this cell index
void addCluster(const CellIndex &cell_index, const int &cluster_index)
adds a cluster to this grid cell
std::vector< double > getGridSpacingX() const
returns grid spacing in x direction
void enlarge(const PositionType &p)
Enlarges the bounding box such that it contains a position.
Definition DBoundingBox.h:98
CoordinateType getY() const
Name accessor for the second dimension. Only for DPosition<2>, for visualization.
Definition DPosition.h:147
CoordinateType getX() const
Name accessor for the first dimension. Only for DPosition<2>, for visualization.
Definition DPosition.h:140
Invalid value exception.
Definition Exception.h:306
basic data structure for clustering
Definition GridBasedCluster.h:23
const Rectangle & getBoundingBox() const
returns bounding box
const std::vector< int > & getPoints() const
returns indices of points in cluster
const std::vector< int > & getPropertiesB() const
returns properties B of all points
int getPropertyA() const
returns property A
const Point & getCentre() const
returns cluster centre
2D hierarchical clustering implementation optimized for large data sets containing many small cluster...
Definition GridBasedClustering.h:104
void removeSmallClustersY(double threshold_y)
removes clusters with bounding box dimension in y-direction below certain threshold
Definition GridBasedClustering.h:403
std::map< int, GridBasedCluster > getResults() const
returns final results (mapping of cluster indices to clusters)
Definition GridBasedClustering.h:423
bool findNearestNeighbour_(const GridBasedCluster &cluster, int cluster_index)
determines the nearest neighbour for each cluster
Definition GridBasedClustering.h:589
std::unordered_map< int, std::multiset< MinimumDistance >::const_iterator > distance_it_for_cluster_idx_
cluster index to distance iterator lookup table for finding out which clusters need to be updated fas...
Definition GridBasedClustering.h:475
bool mergeVeto_(const GridBasedCluster &c1, const GridBasedCluster &c2) const
checks if two clusters can be merged Each point in a cluster can (optionally) have two properties A a...
Definition GridBasedClustering.h:543
void init_(const std::vector< double > &data_x, const std::vector< double > &data_y, const std::vector< int > &properties_A, const std::vector< int > &properties_B)
initialises all data structures
Definition GridBasedClustering.h:485
ClusteringGrid grid_
grid on which the position of the clusters are registered used in cluster method
Definition GridBasedClustering.h:439
void extendClustersY()
extends clusters in y-direction if possible (merges clusters further in y-direction,...
Definition GridBasedClustering.h:276
Metric metric_
metric for measuring the distance between points in the 2D plane
Definition GridBasedClustering.h:433
GridBasedClustering(Metric metric, const std::vector< double > &data_x, const std::vector< double > &data_y, std::vector< double > grid_spacing_x, std::vector< double > grid_spacing_y)
initialises all data structures
Definition GridBasedClustering.h:145
std::vector< Point > centres_
centres of the clusters in clusters_, indexed by cluster index (the same as their getCentre(),...
Definition GridBasedClustering.h:457
GridBasedCluster::Rectangle Rectangle
Definition GridBasedClustering.h:110
std::multiset< MinimumDistance > distances_
list of minimum distances stores the smallest of the distances in the head
Definition GridBasedClustering.h:463
GridBasedClustering(Metric metric, const std::vector< double > &data_x, const std::vector< double > &data_y, const std::vector< int > &properties_A, const std::vector< int > &properties_B, std::vector< double > grid_spacing_x, std::vector< double > grid_spacing_y)
initialises all data structures
Definition GridBasedClustering.h:126
void cluster()
performs the hierarchical clustering (merges clusters until their dimension exceeds that of cell)
Definition GridBasedClustering.h:161
GridBasedCluster::Point Point
cluster centre, cluster bounding box, grid index
Definition GridBasedClustering.h:109
std::unordered_multimap< int, std::multiset< MinimumDistance >::const_iterator > reverse_nns_
reverse nearest neighbor lookup table for finding out which clusters need to be updated faster
Definition GridBasedClustering.h:469
std::multiset< MinimumDistance >::const_iterator MultisetIterator
Definition GridBasedClustering.h:112
std::map< int, GridBasedCluster > clusters_
list of clusters maps cluster indices to clusters
Definition GridBasedClustering.h:445
std::map< int, GridBasedCluster > clusters_final_
list of final clusters i.e. clusters that are no longer merged
Definition GridBasedClustering.h:451
std::unordered_multimap< int, MultisetIterator >::const_iterator NNIterator
Definition GridBasedClustering.h:113
void eraseMinDistance_(const std::multiset< MinimumDistance >::const_iterator it)
remove minimum distance object and its related data
Definition GridBasedClustering.h:655
ClusteringGrid::CellIndex CellIndex
Definition GridBasedClustering.h:111
PositionType const & maxPosition() const
Accessor to maximum position.
Definition DIntervalBase.h:104
PositionType const & minPosition() const
Accessor to minimum position.
Definition DIntervalBase.h:98
CoordinateType maxY() const
Accessor for max_ coordinate maximum.
Definition DIntervalBase.h:286
CoordinateType minY() const
Accessor for max_ coordinate minimum.
Definition DIntervalBase.h:274
basic data structure for distances between clusters
Definition GridBasedClustering.h:35
MinimumDistance()
hide default constructor
bool operator>(const MinimumDistance &other) const
int getClusterIndex() const
returns cluster index
MinimumDistance(const int &cluster_index, const int &nearest_neighbour_index, const double &distance)
constructor
int nearest_neighbour_index_
index of the nearest neighbour of the above cluster
Definition GridBasedClustering.h:77
int getNearestNeighbourIndex() const
returns index of nearest cluster
double distance_
distance between cluster and its nearest neighbour
Definition GridBasedClustering.h:82
bool operator==(const MinimumDistance &other) const
int cluster_index_
index in the cluster list
Definition GridBasedClustering.h:72
bool operator<(const MinimumDistance &other) const
operators for comparisons (for multiset)
Definition GridBasedClustering.h:57
Base class for all classes that want to report their progress.
Definition ProgressLogger.h:28
void setProgress(SignedSize value) const
Sets the current progress.
void endProgress(UInt64 bytes_processed=0) const
void startProgress(SignedSize begin, SignedSize end, const std::string &label) const
Initializes the progress display.
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition Types.h:97
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19