LDMX Software
TemplatedClusterFinder.h
1/*
2 TemplatedClusterFinder
3 */
4
5#ifndef ECAL_TEMPLATEDCLUSTERFINDER_H_
6#define ECAL_TEMPLATEDCLUSTERFINDER_H_
7
8#include <math.h>
9
10#include <iostream>
11#include <map>
12
13#include "Ecal/IntermediateCluster.h"
14#include "TH2F.h"
15
16namespace ecal {
17
18template <class WeightClass>
19
21 public:
22 void add(const ldmx::EcalHit& eh) {
23 clusters_.push_back(IntermediateCluster(eh));
24 }
25
26 static bool compClusters(const IntermediateCluster& a,
27 const IntermediateCluster& b) {
28 return a.centroid().E() > b.centroid().E();
29 }
30
31 void cluster(double seed_threshold, double cutoff) {
32 int ncluster = clusters_.size();
33 double minwgt = cutoff;
34 // Sort after highest energy
35 std::sort(clusters_.begin(), clusters_.end(), compClusters);
36 loops_ = 0;
37 do {
38 bool any = false;
39 size_t mi(0), mj(0);
40
41 int nseeds = 0;
42
43 for (size_t i = 0; i < clusters_.size(); i++) {
44 if (clusters_[i].empty()) continue;
45
46 bool iseed = (clusters_[i].centroid().E() >= seed_threshold);
47 if (iseed) {
48 nseeds++;
49 } else {
50 // Since we sorted initially if we find a hit below seed threshold
51 // it is guaranteed that there will be no seeds after.
52 break;
53 }
54
55 for (size_t j = i + 1; j < clusters_.size(); j++) {
56 if (clusters_[j].empty() ||
57 (!iseed && clusters_[j].centroid().E() <
58 seed_threshold)) // this never happens
59 continue;
60 double wgt = wgt_(clusters_[i], clusters_[j]);
61 if (!any || wgt < minwgt) {
62 any = true;
63 minwgt = wgt;
64 mi = i;
65 mj = j;
66 }
67 }
68 }
69
70 nseeds_ = nseeds;
71 transition_weights_.insert(std::pair<int, double>(ncluster, minwgt));
72
73 if (any && minwgt < cutoff) {
74 // put the bigger one in mi
75 if (clusters_[mi].centroid().E() < clusters_[mj].centroid().E()) {
76 std::swap(mi, mj);
77 }
78 // now we have the smallest, merge
79 clusters_[mi].add(clusters_[mj]);
80 clusters_[mj].clear();
81 // decrement cluster count
82 ncluster--;
83 }
84 loops_++;
85 } while (minwgt < cutoff && ncluster > 1);
86 finalwgt_ = minwgt;
87 for (const auto& cl : clusters_) {
88 if (!cl.empty() && cl.centroid().E() >= seed_threshold)
89 final_clusters_.push_back(cl);
90 else if (cl.centroid().E() < seed_threshold)
91 break; // clusters are sorted, so should be safe to break
92 }
93 }
94
95 double getYMax() const { return finalwgt_; }
96
97 int getNSeeds() const { return nseeds_; }
98
99 int getNLoops() const { return loops_; }
100
101 std::map<int, double> getWeights() const { return transition_weights_; }
102
103 std::vector<IntermediateCluster> getClusters() const {
104 return final_clusters_;
105 }
106
107 private:
108 WeightClass wgt_;
109 double finalwgt_;
110 int nseeds_;
111 int loops_;
112 std::map<int, double> transition_weights_;
113 std::vector<IntermediateCluster> clusters_;
114 std::vector<IntermediateCluster> final_clusters_;
115};
116} // namespace ecal
117
118#endif
Stores reconstructed hit information from the ECAL.
Definition EcalHit.h:19