68 mMathiesons[0].setPitch(0.21);
69 mMathiesons[0].setSqrtKx3AndDeriveKx2Kx4(0.7000);
70 mMathiesons[0].setSqrtKy3AndDeriveKy2Ky4(0.7550);
73 mMathiesons[1].setPitch(0.25);
74 mMathiesons[1].setSqrtKx3AndDeriveKx2Kx4(0.7131);
75 mMathiesons[1].setSqrtKy3AndDeriveKy2Ky4(0.7642);
85 currentBC = 0xFFFFFFFF;
86 currentOrbit = 0xFFFFFFFF;
87 currentPreClusterID = 0;
155 if (xyDxy !=
nullptr) {
159 if (cathode !=
nullptr) {
163 if (padCharge !=
nullptr) {
167 if (saturated !=
nullptr) {
183 double xyDxy[nPads * 4];
186 double padCharge[nPads];
188 uint32_t padADC[nPads];
189 DEId =
digits[0].getDetID();
190 double* xPad =
getX(xyDxy, nPads);
191 double* yPad =
getY(xyDxy, nPads);
192 double* dxPad =
getDX(xyDxy, nPads);
193 double* dyPad =
getDY(xyDxy, nPads);
195 for (
int iDigit = 0; iDigit <
digits.size(); ++iDigit) {
196 const auto& digit =
digits[iDigit];
197 int padID = digit.getPadID();
201 double dx = mSegmentation->
padSizeX(padID) / 2.;
202 double dy = mSegmentation->
padSizeY(padID) / 2.;
203 uint32_t
adc = digit.getADC();
205 bool isSaturated = digit.isSaturated();
209 throw std::runtime_error(
"The precluster contains a digit with charge <= 0");
218 padCharge[iDigit] =
charge;
219 saturated[iDigit] = isSaturated;
220 cathode[iDigit] = plane;
221 padADC[iDigit] =
adc;
224 uint32_t N =
digits.size();
229 uint32_t
header[6] = {(uint32_t)(bunchCrossing), (
orbit), iPreCluster, (0), N, (uint32_t)(DEId)};
247 uint32_t N =
clusters.size() - startIdx;
261 uint32_t
header[6] = {(uint32_t)(bunchCrossing), (
orbit), iPreCluster, (0), N, 0};
267 uint32_t firstDigit[N], nDigits[N];
306 mPreCluster->clear();
312 xyDxy =
new double[nPads * 4];
313 saturated =
new Mask_t[nPads];
314 cathode =
new Mask_t[nPads];
315 padCharge =
new double[nPads];
317 uint32_t padADC[nPads];
318 DEId =
digits[0].getDetID();
319 double* xPad =
getX(xyDxy, nPads);
320 double* yPad =
getY(xyDxy, nPads);
321 double* dxPad =
getDX(xyDxy, nPads);
322 double* dyPad =
getDY(xyDxy, nPads);
324 for (
int iDigit = 0; iDigit <
digits.size(); ++iDigit) {
325 const auto& digit =
digits[iDigit];
326 int padID = digit.getPadID();
330 double dx = mSegmentation->
padSizeX(padID) / 2.;
331 double dy = mSegmentation->
padSizeY(padID) / 2.;
332 uint32_t
adc = digit.getADC();
336 bool isSaturated = digit.isSaturated();
340 throw std::runtime_error(
"The precluster contains a digit with charge <= 0");
350 padCharge[iDigit] =
charge;
351 saturated[iDigit] = isSaturated;
352 cathode[iDigit] = plane;
353 padADC[iDigit] =
adc;
358void ClusterFinderGEM::setClusterResolution(
Cluster& cluster)
const
371 int padIDNB(-1), padIDB(-1);
375 auto itPadNB = mUsedDigits.end();
376 if (padsFound || mSegmentation->
isValid(padIDNB)) {
377 itPadNB = std::find_if(mUsedDigits.begin() + cluster.
firstDigit, mUsedDigits.end(),
378 [padIDNB](
const Digit& digit) { return digit.getPadID() == padIDNB; });
380 auto itPadB = mUsedDigits.end();
381 if (padsFound || mSegmentation->
isValid(padIDB)) {
382 itPadB = std::find_if(mUsedDigits.begin() + cluster.
firstDigit, mUsedDigits.end(),
383 [padIDB](
const Digit& digit) { return digit.getPadID() == padIDB; });
396 uint16_t bunchCrossing, uint32_t
orbit, uint32_t iPreCluster)
405 uint32_t nPreviousCluster = mClusters.size();
407 printf(
"----------------------------------------\n");
408 std::cout <<
" [GEM] PreCluster BC=" << bunchCrossing
409 <<
", orbit = " <<
orbit
410 <<
", iPreCluster, = " << iPreCluster
412 printf(
"----------------------------------------\n");
424 int chId = DEId / 100;
425 int nbrOfHits =
::clusterProcess(xyDxy, cathode, saturated, padCharge, chId, nPads);
426 double theta[nbrOfHits * 5];
431 double* muX =
getMuX(theta, nbrOfHits);
432 double* muY =
getMuY(theta, nbrOfHits);
433 double*
w =
getW(theta, nbrOfHits);
442 Groups_t nCathGrp = vectorMaxShort(padToCathGrp, nPads);
447 for (
int g = 1;
g < (nCathGrp + 1);
g++) {
449 firstDigit = mUsedDigits.size();
450 for (
const auto& pad : *mPreCluster) {
452 if (padToCathGrp[
i] ==
g) {
453 mUsedDigits.emplace_back(
digits[pad.digitIndex()]);
459 uint32_t nDigits = mUsedDigits.size() - firstDigit;
461 for (
int s = 0; s < nbrOfHits; s++) {
463 if (thetaToGroup[s] ==
g) {
485 uint32_t uid = Cluster::buildUniqueId(
digits[0].getDetID() / 100 - 1,
digits[0].getDetID(), nPreviousCluster + s);
490 mClusters.push_back({
491 static_cast<float>(
x),
static_cast<float>(
y), 0.0,
492 static_cast<float>(0),
static_cast<float>(0),
496 setClusterResolution(mClusters[mClusters.size() - 1]);
498 int iNewCluster = mClusters.size() - 1;
Clustering and fifting parameters.
Definition of the cluster used by the original cluster finder algorithm.
Configurable parameters for MCH clustering.
std::vector< std::string > header
Original definition of the Mathieson function.
Definition of the pad used by the original cluster finder algorithm.
static const ClusterizerParam & Instance()
void dumpInt16(int ifile, long size, const int16_t *data)
void dumpUInt32(int ifile, long size, const uint32_t *data)
void dumpFloat64(int ifile, long size, const double_t *data)
void fillGEMInputData(gsl::span< const Digit > &digits, uint16_t bunchCrossing, uint32_t orbit, uint32_t iPreCluster)
void findClusters(gsl::span< const Digit > digits, uint16_t bunchCrossing, uint32_t orbit, uint32_t iPreCluster)
void dumpPreCluster(ClusterDump *dumpFile, gsl::span< const Digit > digits, uint16_t bunchCrossing, uint32_t orbit, uint32_t iPreCluster)
void init(int mode, bool run2Config)
void dumpClusterResults(ClusterDump *dumpFile, const std::vector< Cluster > &clusters, size_t startIdx, uint16_t bunchCrossing, uint32_t orbit, uint32_t iPreCluster)
Original Mathieson function.
double padPositionX(int dePadIndex) const
double padSizeY(int dePadIndex) const
bool findPadPairByPosition(double x, double y, int &bpad, int &nbpad) const
bool isBendingPad(int dePadIndex) const
double padPositionY(int dePadIndex) const
double padSizeX(int dePadIndex) const
bool isValid(int dePadIndex) const
int clusterProcess(const double *xyDxyi, const o2::mch::Mask_t *cathi, const o2::mch::Mask_t *saturated, const double *zi, int chId, int nPads)
GLubyte GLubyte GLubyte GLubyte w
O2MCHMAPPINGIMPL3_EXPORT const Segmentation & segmentation(int detElemId)
void initMathieson(int useSpline_, int useCache_)
double * getMuY(double *theta, int K)
double * getDX(double *xyDxy, int N)
void collectSeeds(double *theta, o2::mch::Groups_t *thetaToGroup, int K)
void cleanClusterResults()
double * getX(double *xyDxy, int N)
double * getY(double *xyDxy, int N)
double * getMuX(double *theta, int K)
double * getW(double *theta, int K)
double * getDY(double *xyDxy, int N)
ClusterConfig clusterConfig
void collectGroupMapping(Mask_t *padToMGrp, int nPads)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
float SBadClusterResolutionX
bad (e.g. mono-cathode) cluster resolution in x direction (cm)
double minChargeOfClusterPerCathode
float SBadClusterResolutionY
bad (e.g. mono-cathode) cluster resolution in y direction (cm)
@ info
Describes main steps and high level behaviors.
VerboseMode processingLog
float SDefaultClusterResolutionY
default cluster resolution in y direction (cm)
float SDefaultClusterResolutionX
default cluster resolution in x direction (cm)
cluster minimal structure
float ey
cluster resolution along y
int getChamberId() const
Return the chamber ID (0..), part of the unique ID.
uint32_t firstDigit
index of first associated digit in the ordered vector of digits
uint32_t uid
cluster unique ID
uint32_t nDigits
number of digits attached to this cluster
float y
cluster position along y
float x
cluster position along x
float ex
cluster resolution along x
std::vector< Cluster > clusters
std::vector< Digit > digits