10DBScanClusterBuilder::DBScanClusterBuilder() {
12 clusterHitDist_ = 100;
14 minClusterHitMult_ = 2;
17DBScanClusterBuilder::DBScanClusterBuilder(
float minHitEnergy,
20 float minClusterHitMult) {
21 minHitEnergy_ = minHitEnergy;
22 clusterHitDist_ = clusterHitDist;
23 clusterZBias_ = clusterZBias;
24 minClusterHitMult_ = minClusterHitMult;
27std::vector<std::vector<const ldmx::CalorimeterHit *> >
28DBScanClusterBuilder::runDBSCAN(
29 const std::vector<const ldmx::CalorimeterHit *> &hits,
bool debug =
false) {
30 const int n = hits.size();
31 std::vector<std::vector<const ldmx::CalorimeterHit *> > idx_clusters;
32 std::vector<unsigned int> tried;
34 std::vector<unsigned int> used;
36 for (
unsigned int i = 0; i < n; i++) {
37 if (isIn(i, tried))
continue;
39 ldmx_log(debug) <<
"trying " << i;
40 if (hits[i]->getEnergy() < minHitEnergy_)
continue;
41 std::set<unsigned int> neighbors;
42 unsigned int nNearby = 1;
44 for (
unsigned int j = 0; j < n; j++) {
46 dist(hits[i], hits[j]) < clusterHitDist_) {
48 if (hits[j]->getEnergy() >= minHitEnergy_) nNearby++;
51 if (nNearby >= minClusterHitMult_) {
52 std::vector<const ldmx::CalorimeterHit *> idx_cluster{
55 ldmx_log(debug) <<
"- starting a cluster from " << i;
56 for (
unsigned int j : neighbors) {
57 if (!isIn(j, tried)) {
59 ldmx_log(debug) <<
"== tried " << j;
60 std::vector<unsigned int> neighbors2;
61 for (
unsigned int k = 0; k < n; k++) {
62 if (dist(hits[k], hits[j]) < clusterHitDist_) {
63 neighbors2.push_back(k);
66 for (
unsigned int k : neighbors2) neighbors.insert(k);
69 ldmx_log(debug) <<
"== used " << j;
71 idx_cluster.push_back(hits[j]);
74 idx_clusters.push_back(idx_cluster);
77 ldmx_log(debug) <<
"done. writing this many clusters out: "
78 << idx_clusters.size();
82void DBScanClusterBuilder::fillClusterInfoFromHits(
84 bool logEnergyWeight) {
85 float e(0), x(0), y(0), z(0), xx(0), yy(0), zz(0), n(0);
88 std::vector<float> raw_xvals{};
89 std::vector<float> raw_yvals{};
90 std::vector<float> raw_zvals{};
91 std::vector<float> raw_evals{};
94 if (h->getEnergy() < minHitEnergy_)
continue;
95 if (logEnergyWeight) w = log(h->getEnergy() - log(minHitEnergy_));
97 x += w * h->getXPos();
98 y += w * h->getYPos();
99 z += w * h->getZPos();
100 xx += w * h->getXPos() * h->getXPos();
101 yy += w * h->getYPos() * h->getYPos();
102 zz += w * h->getZPos() * h->getZPos();
105 raw_xvals.push_back(h->getXPos());
106 raw_yvals.push_back(h->getYPos());
107 raw_zvals.push_back(h->getZPos());
108 raw_evals.push_back(h->getEnergy());
116 xx = sqrt(xx - x * x);
117 yy = sqrt(yy - y * y);
118 zz = sqrt(zz - z * z);
122 cl->setRMSXYZ(xx, yy, zz);
123 cl->setHitValsX(raw_xvals);
124 cl->setHitValsY(raw_yvals);
125 cl->setHitValsZ(raw_zvals);
126 cl->setHitValsE(raw_evals);
128 if (raw_xvals.size() > 2) {
130 std::vector<float> sortedZ = raw_zvals;
131 std::sort(sortedZ.begin(), sortedZ.end());
132 if (sortedZ[sortedZ.size() - 1] - sortedZ[0] > 1e3) {
133 for (
int i = 0; i < raw_xvals.size(); i++) {
134 raw_xvals[i] = raw_xvals[i] - x;
135 raw_yvals[i] = raw_yvals[i] - y;
136 raw_zvals[i] = raw_zvals[i] - z;
139 TGraph gxz(raw_zvals.size(), raw_zvals.data(), raw_xvals.data());
140 auto r_xz = gxz.Fit(
"pol1",
"SQ");
141 cl->setDXDZ(r_xz->Value(1));
142 cl->setEDXDZ(r_xz->ParError(1));
144 TGraph gyz(raw_zvals.size(), raw_zvals.data(), raw_yvals.data());
145 auto r_yz = gyz.Fit(
"pol1",
"SQ");
146 cl->setDYDZ(r_yz->Value(1));
147 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 setEnergy(double energy)
Sets total energy for the cluster.
void setCentroidXYZ(double x, double y, double z)
Sets the three coordinates of the cluster centroid.
Represents a reconstructed hit in a calorimeter cell within the detector.