12DBScanClusterBuilder::DBScanClusterBuilder() {
14 cluster_hit_dist_ = 100;
16 min_cluster_hit_mult_ = 2;
19DBScanClusterBuilder::DBScanClusterBuilder(
float minHitEnergy,
22 float minClusterHitMult) {
23 min_hit_energy_ = minHitEnergy;
24 cluster_hit_dist_ = clusterHitDist;
25 cluster_z_bias_ = clusterZBias;
26 min_cluster_hit_mult_ = minClusterHitMult;
29std::vector<std::vector<const ldmx::CalorimeterHit*> >
30DBScanClusterBuilder::runDBSCAN(
31 const std::vector<const ldmx::CalorimeterHit*>& hits_) {
32 const int n = hits_.size();
33 std::vector<std::vector<const ldmx::CalorimeterHit*> > idx_clusters;
34 std::vector<unsigned int> tried;
36 std::vector<unsigned int> used;
38 for (
unsigned int i = 0; i < n; i++) {
39 if (isIn(i, tried))
continue;
41 ldmx_log(debug) <<
"trying " << i;
42 if (hits_[i]->getEnergy() < min_hit_energy_)
continue;
43 std::set<unsigned int> neighbors;
44 unsigned int n_nearby = 1;
46 for (
unsigned int j = 0; j < n; j++) {
48 dist(hits_[i], hits_[j]) < cluster_hit_dist_) {
50 if (hits_[j]->getEnergy() >= min_hit_energy_) n_nearby++;
53 if (n_nearby >= min_cluster_hit_mult_) {
54 std::vector<const ldmx::CalorimeterHit*> idx_cluster{
57 ldmx_log(debug) <<
"- starting a cluster from " << i;
58 for (
unsigned int j : neighbors) {
59 if (!isIn(j, tried)) {
61 ldmx_log(debug) <<
"== tried " << j;
62 std::vector<unsigned int> neighbors2;
63 for (
unsigned int k = 0; k < n; k++) {
64 if (dist(hits_[k], hits_[j]) < cluster_hit_dist_) {
65 neighbors2.push_back(k);
68 for (
unsigned int k : neighbors2) neighbors.insert(k);
71 ldmx_log(debug) <<
"== used " << j;
73 idx_cluster.push_back(hits_[j]);
76 idx_clusters.push_back(idx_cluster);
79 ldmx_log(debug) <<
"done. writing this many clusters out: "
80 << idx_clusters.size();
84void DBScanClusterBuilder::fillClusterInfoFromHits(
86 bool logEnergyWeight,
bool saveHitContribs) {
87 float e(0), x(0), y(0), z(0), xx(0), yy(0), zz(0), n(0);
90 std::vector<float> raw_xvals{};
91 std::vector<float> raw_yvals{};
92 std::vector<float> raw_zvals{};
93 std::vector<float> raw_evals{};
94 std::vector<const ldmx::CalorimeterHit*> constituent_hits;
97 if (h->getEnergy() < min_hit_energy_)
continue;
98 if (logEnergyWeight) w = log(h->getEnergy()) - log(min_hit_energy_);
100 x += w * h->getXPos();
101 y += w * h->getYPos();
102 z += w * h->getZPos();
103 xx += w * h->getXPos() * h->getXPos();
104 yy += w * h->getYPos() * h->getYPos();
105 zz += w * h->getZPos() * h->getZPos();
108 if (saveHitContribs) {
109 raw_xvals.push_back(h->getXPos());
110 raw_yvals.push_back(h->getYPos());
111 raw_zvals.push_back(h->getZPos());
112 raw_evals.push_back(h->getEnergy());
113 constituent_hits.emplace_back(h);
122 xx = sqrt(xx - x * x);
123 yy = sqrt(yy - y * y);
124 zz = sqrt(zz - z * z);
128 cl->setRMSXYZ(xx, yy, zz);
129 if (saveHitContribs) {
130 cl->setHitValsX(raw_xvals);
131 cl->setHitValsY(raw_yvals);
132 cl->setHitValsZ(raw_zvals);
133 cl->setHitValsE(raw_evals);
137 if (raw_xvals.size() > 2) {
139 std::vector<float> sorted_z = raw_zvals;
140 std::sort(sorted_z.begin(), sorted_z.end());
141 if ((sorted_z.size() > 2) and (sorted_z.back() - sorted_z.front() > 1e3)) {
142 for (
int i = 0; i < raw_xvals.size(); i++) {
143 raw_xvals[i] = raw_xvals[i] - x;
144 raw_yvals[i] = raw_yvals[i] - y;
145 raw_zvals[i] = raw_zvals[i] - z;
148 TGraph gxz(raw_zvals.size(), raw_zvals.data(), raw_xvals.data());
149 auto r_xz = gxz.Fit(
"pol1",
"SQ");
150 cl->setDXDZ(r_xz->Value(1));
151 cl->setEDXDZ(r_xz->ParError(1));
153 TGraph gyz(raw_zvals.size(), raw_zvals.data(), raw_yvals.data());
154 auto r_yz = gyz.Fit(
"pol1",
"SQ");
155 cl->setDYDZ(r_yz->Value(1));
156 cl->setEDYDZ(r_yz->ParError(1));
Implementation of DBSCAN clustering algo.
Stores cluster information from the ECal.
void setNHits(int nHits)
Sets total number of hits in the cluster.
void addHits(const std::vector< const ldmx::CalorimeterHit * > hitsVec)
Take in the hits that make up the cluster.
void setCentroidXYZ(double centroid_x, double centroid_y, double centroid_z)
Sets the three coordinates of the cluster centroid.
void setEnergy(double energy)
Sets total energy for the cluster.
Represents a reconstructed hit in a calorimeter cell within the detector.