18 generate_n(sd.begin(), sd.size(), ref(r));
19 seed_seq ss(begin(sd), end(sd));
20 return mt19937_64(ss);
24 Point::Point(
float x,
float y,
float w):
31 return make_tuple(
x_,
y_,
w_)<make_tuple(other.
x_, other.
y_, other.
w_);
35 float dx = a.
x_ - b.
x_;
36 float dy = a.
y_ - b.
y_;
37 return a.
w_*b.
w_*(dx*dx+dy*dy)/(a.
w_+b.
w_);
42 dist_to_neighbor_(-1.),
62 max_points_(max_points),
63 hist_mode_(max_points == 0),
97 for(
const auto &p: points){
98 hist_.Fill(p.x_, p.y_, p.w_);
120 float xmin =
hist_.GetXaxis()->GetBinLowEdge(1);
121 float xmax =
hist_.GetXaxis()->GetBinUpEdge(
hist_.GetNbinsX());
122 float dx = 0.0001*(xmax-xmin);
125 float ymin =
hist_.GetYaxis()->GetBinLowEdge(1);
126 float ymax =
hist_.GetYaxis()->GetBinUpEdge(
hist_.GetNbinsY());
127 float dy = 0.0001*(ymax-ymin);
132 g.SetMarkerStyle(
hist_.GetMarkerStyle());
133 g.SetMarkerColor(
hist_.GetMarkerColor());
134 g.SetMarkerSize(
hist_.GetMarkerSize());
142 if(x < xmin) x = xmin;
143 if(x > xmax) x = xmax;
144 if(y < xmin) y = ymin;
145 if(y > ymax) y = ymax;
160 auto first =
nodes_.begin();
164 Link(first, second, dist);
165 Link(second, first, dist);
166 }
else if(
nodes_.size() == 1){
170 list<Node>::iterator this_node =
nodes_.begin();
171 auto the_end =
nodes_.end();
172 for(
auto it = ++
nodes_.begin(); it != the_end; ++it){
175 if(dist < this_node->dist_to_neighbor_ || this_node->dist_to_neighbor_ < 0.){
176 Link(this_node, it, dist);
179 if(dist < it->dist_to_neighbor_){
180 Link(it, this_node, dist);
188 nodes_.front().dist_to_neighbor_ = -1.;
189 nodes_.front().neighbor_ = list<Node>::iterator();
190 nodes_.front().neighbor_of_.clear();
192 }
else if(
nodes_.size() == 1){
197 auto pos = find(node->neighbor_->neighbor_of_.begin(), node->neighbor_->neighbor_of_.end(), node);
198 node->neighbor_->neighbor_of_.erase(pos);
200 auto invalidated = node->neighbor_of_;
205 for(
auto &bad_node: invalidated){
206 bad_node->dist_to_neighbor_ = -1.;
210 for(
auto new_neighbor =
nodes_.begin(); new_neighbor !=
nodes_.end(); ++new_neighbor){
211 for(
auto &bad_node: invalidated){
212 if(bad_node == new_neighbor)
continue;
214 if(dist < bad_node->dist_to_neighbor_ || bad_node->dist_to_neighbor_ < 0.){
215 Link(bad_node, new_neighbor, dist);
222 float min_dist = -1., min_dist_high_weight = -1.;
223 list<Node>::iterator best_node =
nodes_.begin(), best_node_high_weight =
nodes_.begin();
224 for(
auto node =
nodes_.begin(); node !=
nodes_.end(); ++node){
225 if(node->dist_to_neighbor_ < min_dist || min_dist < 0.){
227 min_dist = node->dist_to_neighbor_;
229 if((node->dist_to_neighbor_ < min_dist_high_weight || min_dist_high_weight < 0.)
230 && node->w_ > 1. && node->neighbor_->w_ < 1.){
231 best_node_high_weight = node;
232 min_dist_high_weight = node->dist_to_neighbor_;
235 if(min_dist < 0.)
ERROR(
"Could not find neighboring points.");
236 if(min_dist_high_weight > 0.){
237 return best_node_high_weight;
244 list<Node>::iterator neighbor,
247 if(node->dist_to_neighbor_ >= 0.){
248 auto pos = find(node->neighbor_->neighbor_of_.begin(), node->neighbor_->neighbor_of_.end(), node);
249 node->neighbor_->neighbor_of_.erase(pos);
253 node->dist_to_neighbor_ = dist;
254 node->neighbor_ = neighbor;
255 neighbor->neighbor_of_.push_back(node);
259 for(
int i = 0; i <
hist_.GetNcells(); ++i){
260 hist_.SetBinContent(i, 0.);
261 hist_.SetBinError(i, 0.);
263 hist_.SetEntries(0.);
280 int nx =
hist_.GetNbinsX();
281 int ny =
hist_.GetNbinsY();
282 float xmin =
hist_.GetXaxis()->GetBinLowEdge(1);
283 float xmax =
hist_.GetXaxis()->GetBinUpEdge(
hist_.GetNbinsX());
284 float dx = 0.5*(xmax-xmin);
285 float ymin =
hist_.GetYaxis()->GetBinLowEdge(1);
286 float ymax =
hist_.GetYaxis()->GetBinUpEdge(
hist_.GetNbinsY());
287 float dy = 0.5*(ymax-ymin);
288 for(
int ix = 0; ix <= nx+1; ++ix){
289 float xlow = (ix <= 0) ? (xmin-dx)
290 : (ix >
hist_.GetNbinsX()) ? (xmax+dx)
291 :
hist_.GetXaxis()->GetBinLowEdge(ix);
292 float xhigh = (ix <= 0) ? (xmin-dx)
293 : (ix >
hist_.GetNbinsX()) ? (xmax+dx)
294 :
hist_.GetXaxis()->GetBinUpEdge(ix);
295 for(
int iy = 0; iy <= ny+1; ++iy){
296 float ylow = (iy <= 0) ? (ymin-dy)
297 : (iy >
hist_.GetNbinsY()) ? (ymax+dy)
298 :
hist_.GetYaxis()->GetBinLowEdge(iy);
299 float yhigh = (iy <= 0) ? (ymin-dy)
300 : (iy >
hist_.GetNbinsY()) ? (ymax+dy)
301 :
hist_.GetYaxis()->GetBinUpEdge(iy);
303 float w = luminosity*
hist_.GetBinContent(ix, iy);
305 float x = xlow +
urd_(
prng_)*(xhigh-xlow);
306 float y = ylow +
urd_(
prng_)*(yhigh-ylow);
319 float w = luminosity * p.w_;
320 if(w <= 0.)
continue;
334 list<Node>::iterator neighbor = root_node->neighbor_;
339 if(
nodes_.front().w_ > 1.5){
341 }
else if(
nodes_.front().w_ >= 0.5){
352 list<Node>::iterator b)
const{
359 if(a->w_ + b->w_ <= 1.){
361 Point c((a->w_*a->x_+b->w_*b->x_)/(a->w_+b->w_),
362 (a->w_*a->y_+b->w_*b->y_)/(a->w_+b->w_),
373 float sumw = a->w_ + b->w_;
374 float summ1 = sumw - 1.;
375 float rt = sqrt(a->w_*b->w_*summ1);
377 if(fabs(1.-a->w_) <= fabs(1.-b->w_)){
379 Point c(((a->w_+rt)*a->x_ + (b->w_-rt)*b->x_)/sumw,
380 ((a->w_+rt)*a->y_ + (b->w_-rt)*b->y_)/sumw,
382 Point d(((a->w_*summ1-rt)*a->x_ + (b->w_*summ1+rt)*b->x_)/(sumw*summ1),
383 ((a->w_*summ1-rt)*a->y_ + (b->w_*summ1+rt)*b->y_)/(sumw*summ1),
395 Point c(((a->w_*summ1+rt)*a->x_ + (b->w_*summ1-rt)*b->x_)/(sumw*summ1),
396 ((a->w_*summ1+rt)*a->y_ + (b->w_*summ1-rt)*b->y_)/(sumw*summ1),
398 Point d(((a->w_-rt)*a->x_ + (b->w_+rt)*b->x_)/sumw,
399 ((a->w_-rt)*a->y_ + (b->w_+rt)*b->y_)/sumw,
414 list<Node>::iterator old =
nodes_.begin();
417 float min_dist = -1.;
418 size_t best_index = 0;
419 for(
size_t index = 0; index <
final_points_.size(); ++index){
421 if(dist < min_dist || min_dist < 0.){
427 float dx = old->x_ - p.
x_;
428 float dy = old->y_ - p.
y_;
430 a =
Point(old->x_ + scale*dy, old->y_ - scale*dx, 0.5*old->w_);
431 b =
Point(old->x_ - scale*dy, old->y_ + scale*dx, 0.5*old->w_);
433 a =
Point(old->x_+1., old->y_+1., 0.5*old->w_);
434 b =
Point(old->x_-1., old->y_-1., 0.5*old->w_);
450 stream <<
"Point(x=" << p.
x_ <<
",y=" << p.
y_ <<
",w=" << p.
w_ <<
")";
static void Link(std::list< Node >::iterator node, std::list< Node >::iterator neighbor, float dist)
void RemovePoint(std::list< Node >::iterator node) const
void Cluster(double luminosity) const
float WeightedDistance(const Point &a, const Point &b)
std::string FullTitle(const TH1 &h)
bool operator<(const Point &other) const
std::vector< Point > orig_points_
mt19937_64 InitializePRNG()
Node(float x, float y, float z)
static std::mt19937_64 prng_
void SetupNodes(double luminosity) const
TH2D GetHistogram(double luminosity) const
TGraph GetGraph(double luminosity, bool keep_in_frame=true) const
void InsertPoint(float x, float y, float w) const
Clusterizer(const TH2D &hist_template, long max_points=-1)
std::vector< Point > final_points_
std::list< Node >::iterator neighbor_
void AddPoint(float x, float y, float w)
ostream & operator<<(ostream &stream, const Clustering::Point &p)
static std::uniform_real_distribution< float > urd_
void SetPoints(const std::vector< Point > &points)
std::list< Node >::iterator NearestNeighbors() const
std::vector< std::list< Node >::iterator > neighbor_of_
bool operator<(const Node &other) const