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.
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 ...
Defining DataPointCompositeObject explicitly as copiable.
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