26bool Clusterizer::loadPreClusters(gsl::span<const PreCluster>&
preClusters)
32 auto&
de = mPreClustersDE[pc.deId];
35 if (pc.cathode == 0) {
36 de.getPreClustersBP(pc.firstColumn).push_back({
idx, 0, mPreClusterHelper.
getArea(pc)});
38 de.getPreClustersNBP().push_back({
idx, 0});
39 for (
int icolumn = pc.firstColumn; icolumn <= pc.lastColumn; ++icolumn) {
40 de.getPreClustersNBP().back().area[icolumn] = mPreClusterHelper.
getArea(icolumn, pc);
44 mActiveDEs.emplace(pc.deId);
59 for (
auto& deId : mActiveDEs) {
60 makeClusters(mPreClustersDE[deId]);
69 for (
auto& rofRecord : rofRecords) {
70 mPreClusterOffset = rofRecord.firstEntry;
71 auto firstEntry = mClusters.size();
73 auto nEntries = mClusters.size() - firstEntry;
74 mROFRecords.emplace_back(rofRecord, firstEntry,
nEntries);
87 int icolumn = mPreClusters[pcNB.index].firstColumn;
88 if (icolumn == mPreClusters[pcNB.index].lastColumn) {
94 makeCluster(pcB.area, pcNB.area[icolumn], deId);
97 mFunction(mClusters.size() - 1, pcB.index + mPreClusterOffset);
98 mFunction(mClusters.size() - 1, pcNB.index + mPreClusterOffset);
115 int pairId = 10 + inb;
116 for (; icolumn <= mPreClusters[pcNB.index].lastColumn; ++icolumn) {
117 int neighColumn = icolumn + 1;
126 if (
neighbours.empty() && pcB.paired != pairId) {
127 makeCluster(pcB.area, pcNB.area[icolumn], deId);
128 mFunction(mClusters.size() - 1, pcB.index + mPreClusterOffset);
129 mFunction(mClusters.size() - 1, pcNB.index + mPreClusterOffset);
133 makeCluster(pcB, pcBneigh, pcNB, deId);
136 pcBneigh.paired = pairId;
137 mFunction(mClusters.size() - 1, pcB.index + mPreClusterOffset);
138 mFunction(mClusters.size() - 1, pcBneigh.index + mPreClusterOffset);
139 mFunction(mClusters.size() - 1, pcNB.index + mPreClusterOffset);
148 if (pcNB.paired == 0) {
151 for (
int icolumn = mPreClusters[pcNB.index].firstColumn; icolumn <= mPreClusters[pcNB.index].lastColumn; ++icolumn) {
152 makeCluster(pcNB.area[icolumn], deId, 1);
153 mFunction(mClusters.size() - 1, pcNB.index + mPreClusterOffset);
159 for (
int icolumn = 0; icolumn <= 6; ++icolumn) {
162 if (pcB.paired == 0) {
163 makeCluster(pcB.area, deId, 0);
164 mFunction(mClusters.size() - 1, pcB.index + mPreClusterOffset);
188 constexpr double sqrt12 = 3.4641016;
193 mClusters.push_back({
static_cast<float>(xCoor),
static_cast<float>(yCoor), 0.,
static_cast<float>(errX),
static_cast<float>(errY), deId});
194 mClusters.back().setBothFired();
198void Clusterizer::makeCluster(
const MpArea& area,
uint8_t deId,
int cathode)
200 makeCluster(area, area, deId);
201 mClusters.back().setFired(1 - cathode,
false);
205void Clusterizer::makeCluster(
const PreClustersDE::BP& pcBP,
const PreClustersDE::BP& pcBPNeigh,
const PreClustersDE::NBP& pcNBP,
uint8_t deId)
210 double x2[2][2] = {{0., 0.}, {0., 0.}};
211 double x3[2][2] = {{0., 0.}, {0., 0.}};
216 std::vector<const PreClustersDE::BP*> pcBlist = {&pcBP, &pcBPNeigh};
218 for (
auto* pc : pcBlist) {
219 int icolumn = mPreClusters[pc->index].firstColumn;
220 dim[0][0] = pcNBP.area[icolumn].getXmin();
221 dim[0][1] = pcNBP.area[icolumn].getXmax();
222 dim[1][0] = pc->area.getYmin();
223 dim[1][1] = pc->area.getYmax();
224 for (
int iplane = 0; iplane < 2; ++iplane) {
225 delta[iplane] = dim[iplane][1] - dim[iplane][0];
228 sumArea += delta[0] * delta[1];
229 for (
int iplane = 0; iplane < 2; ++iplane) {
230 for (
int ip = 0; ip < 2; ++ip) {
232 double currX2 = dim[iplane][ip] * dim[iplane][ip] * delta[1 - iplane];
233 x2[iplane][ip] += currX2;
235 x3[iplane][ip] += currX2 * dim[iplane][ip];
240 double coor[2], sigma[2];
241 for (
int iplane = 0; iplane < 2; ++iplane) {
242 coor[iplane] = (
x2[iplane][1] -
x2[iplane][0]) / sumArea / 2.;
243 sigma[iplane] = std::sqrt((x3[iplane][1] - x3[iplane][0]) / sumArea / 3. - coor[iplane] * coor[iplane]);
246 mClusters.push_back({
static_cast<float>(coor[0]),
static_cast<float>(coor[1]), 0.,
static_cast<float>(sigma[0]),
static_cast<float>(sigma[1]), deId});
247 mClusters.back().setBothFired();
251void Clusterizer::reset()
Useful detector parameters for MID.
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to process
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of neighbours
Cluster reconstruction algorithm for MID.
bool init(std::function< void(size_t, size_t)> func=[](size_t, size_t) {})
void process(gsl::span< const PreCluster > preClusters, bool accumulate=false)
double getXmax() const
Get x max.
double getYmin() const
Get y min.
double getYmax() const
Get y max.
double getXmin() const
Get x min.
MpArea getArea(const PreCluster &pc) const
NBP & getPreClusterNBP(int idx)
Gets the pre-cluster in the NBP.
size_t getNPreClustersNBP() const
Gets the number of pre-clusters in the NBP.
std::vector< int > getNeighbours(int icolumn, int idx) const
uint8_t getDEId() const
Gets the detection element ID.
BP & getPreClusterBP(int icolumn, int idx)
Gets pre-cluster in the BP.
size_t getNPreClustersBP(int icolumn) const
Gets the number of pre-clusters in the BP.
float float float float x3
constexpr int NDetectionElements
Number of RPCs.
gsl::span< const PreCluster > preClusters(preClusterizer.getPreClusters().data(), preClusterizer.getPreClusters().size())
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...