File indexing completed on 2025-08-06 08:17:31
0001
0002
0003
0004
0005 #include "BEmcCluster.h"
0006 #include "BEmcRec.h"
0007
0008 #include <iostream>
0009
0010
0011
0012
0013 int const EmcCluster::fgMaxNofPeaks = 1000;
0014
0015
0016
0017 int const EmcCluster::fgPeakIter = 6;
0018
0019
0020 float const EmcCluster::fgEmin = 0.002;
0021
0022
0023
0024
0025 void EmcCluster::GetCorrPos(float& xc, float& yc)
0026
0027
0028
0029 {
0030 float e;
0031 float x;
0032 float y;
0033 float xx;
0034 float yy;
0035 float xy;
0036
0037 fOwner->Momenta(&fHitList, e, x, y, xx, yy, xy);
0038 fOwner->CorrectPosition(e, x, y, xc, yc);
0039 }
0040
0041
0042
0043 void EmcCluster::GetGlobalPos(float& xA, float& yA, float& zA)
0044
0045 {
0046 float xc;
0047 float yc;
0048 float e = GetTotalEnergy();
0049 GetCorrPos(xc, yc);
0050 fOwner->Tower2Global(e, xc, yc, xA, yA, zA);
0051 }
0052
0053
0054
0055 float EmcCluster::GetTowerEnergy(int ich)
0056
0057 {
0058 std::vector<EmcModule>::iterator ph;
0059 if (fHitList.empty())
0060 {
0061 return 0;
0062 }
0063 ph = fHitList.begin();
0064 while (ph != fHitList.end())
0065 {
0066 if ((*ph).ich == ich)
0067 {
0068 return (*ph).amp;
0069 }
0070 ++ph;
0071 }
0072 return 0;
0073 }
0074
0075
0076
0077 float EmcCluster::GetTowerEnergy(int ix, int iy)
0078
0079 {
0080 std::vector<EmcModule>::iterator ph;
0081
0082 if (fHitList.empty())
0083 {
0084 return 0;
0085 }
0086 ph = fHitList.begin();
0087 int ich = (iy * fOwner->GetNx()) + ix;
0088 return GetTowerEnergy(ich);
0089 }
0090
0091
0092
0093 float EmcCluster::GetTowerToF(int ich)
0094
0095 {
0096 std::vector<EmcModule>::iterator ph;
0097 if (fHitList.empty())
0098 {
0099 return 0;
0100 }
0101 ph = fHitList.begin();
0102 while (ph != fHitList.end())
0103 {
0104 if ((*ph).ich == ich)
0105 {
0106 return (*ph).tof;
0107 }
0108 ++ph;
0109 }
0110 return 0;
0111 }
0112
0113
0114
0115 float EmcCluster::GetTotalEnergy()
0116
0117 {
0118 std::vector<EmcModule>::iterator ph;
0119 float et = 0;
0120 if (fHitList.empty())
0121 {
0122 return 0;
0123 }
0124 ph = fHitList.begin();
0125 while (ph != fHitList.end())
0126 {
0127 et += (*ph).amp;
0128 ++ph;
0129 }
0130 return et;
0131 }
0132
0133
0134
0135 float EmcCluster::GetECoreCorrected()
0136
0137
0138 {
0139 float e;
0140 float x;
0141 float y;
0142 float xx;
0143 float yy;
0144 float xy;
0145 float ecore;
0146 float ecorecorr;
0147 ecore = GetECore();
0148 fOwner->Momenta(&fHitList, e, x, y, xx, yy, xy);
0149 fOwner->CorrectECore(ecore, x, y, ecorecorr);
0150 return ecorecorr;
0151 }
0152
0153 float EmcCluster::GetECore()
0154
0155 {
0156 const float thresh = 0.01;
0157
0158 std::vector<EmcModule>::iterator ph;
0159 float xcg;
0160 float ycg;
0161 float xx;
0162 float xy;
0163 float yy;
0164 float energy;
0165 float es;
0166
0167 fOwner->Momenta(&fHitList, energy, xcg, ycg, xx, yy, xy);
0168
0169
0170 es = 0;
0171 if (fHitList.empty())
0172 {
0173 return 0;
0174 }
0175 ph = fHitList.begin();
0176 while (ph != fHitList.end())
0177 {
0178 int ixy = (*ph).ich;
0179 int iy = ixy / fOwner->GetNx();
0180 int ix = ixy - (iy * fOwner->GetNx());
0181
0182
0183
0184
0185 float et = fOwner->PredictEnergy(energy, xcg, ycg, ix, iy);
0186 if (et > thresh)
0187 {
0188 es += (*ph).amp;
0189 }
0190 ++ph;
0191 }
0192 return es;
0193 }
0194
0195
0196
0197 float EmcCluster::GetE4()
0198
0199 {
0200 float et;
0201 float xcg;
0202 float ycg;
0203 float xx;
0204 float xy;
0205 float yy;
0206 float e1;
0207 float e2;
0208 float e3;
0209 float e4;
0210 int ix0;
0211 int iy0;
0212 int isx;
0213 int isy;
0214
0215 fOwner->Momenta(&fHitList, et, xcg, ycg, xx, yy, xy);
0216
0217 ix0 = int(xcg + 0.5);
0218
0219 iy0 = int(ycg + 0.5);
0220
0221 isx = 1;
0222 if (xcg - ix0 < 0)
0223 {
0224 isx = -1;
0225 }
0226 isy = 1;
0227 if (ycg - iy0 < 0)
0228 {
0229 isy = -1;
0230 }
0231
0232 e1 = GetTowerEnergy(ix0, iy0);
0233 e2 = GetTowerEnergy(ix0 + isx, iy0);
0234 e3 = GetTowerEnergy(ix0 + isx, iy0 + isy);
0235 e4 = GetTowerEnergy(ix0, iy0 + isy);
0236
0237 return (e1 + e2 + e3 + e4);
0238 }
0239
0240
0241 float EmcCluster::GetE9()
0242
0243 {
0244 float et;
0245 float xcg;
0246 float ycg;
0247 float xx;
0248 float xy;
0249 float yy;
0250 int ich;
0251 int ix0;
0252 int iy0;
0253 int nhit;
0254
0255 nhit = fHitList.size();
0256
0257 if (nhit <= 0)
0258 {
0259 return 0;
0260 }
0261
0262 fOwner->Momenta(&fHitList, et, xcg, ycg, xx, yy, xy);
0263
0264 ix0 = int(xcg + 0.5);
0265
0266 iy0 = int(ycg + 0.5);
0267 ich = iy0 * fOwner->GetNx() + ix0;
0268
0269 return GetE9(ich);
0270 }
0271
0272
0273
0274 float EmcCluster::GetE9(int ich)
0275
0276 {
0277 std::vector<EmcModule>::iterator ph;
0278
0279 int iy0 = ich / fOwner->GetNx();
0280 int ix0 = ich - (iy0 * fOwner->GetNx());
0281
0282 float es = 0;
0283 if (fHitList.empty())
0284 {
0285 return 0;
0286 }
0287 ph = fHitList.begin();
0288 while (ph != fHitList.end())
0289 {
0290 int ixy = (*ph).ich;
0291 int iy = ixy / fOwner->GetNx();
0292 int ix = ixy - (iy * fOwner->GetNx());
0293 int idx = fOwner->iTowerDist(ix0, ix);
0294 int idy = iy - iy0;
0295 if (abs(idx) <= 1 && abs(idy) <= 1)
0296 {
0297 es += (*ph).amp;
0298 }
0299 ++ph;
0300 }
0301 return es;
0302 }
0303
0304
0305
0306 EmcModule EmcCluster::GetMaxTower()
0307
0308 {
0309 std::vector<EmcModule>::iterator ph;
0310 float emax = 0;
0311 EmcModule ht;
0312
0313 ht.ich = -1;
0314 ht.amp = 0;
0315 ht.tof = 0;
0316 if (fHitList.empty())
0317 {
0318 return ht;
0319 }
0320
0321 ph = fHitList.begin();
0322 while (ph != fHitList.end())
0323 {
0324 if ((*ph).amp > emax)
0325 {
0326 emax = (*ph).amp;
0327 ht = *ph;
0328 }
0329 ++ph;
0330 }
0331 return ht;
0332 }
0333
0334
0335
0336 void EmcCluster::GetMoments(float& x, float& y, float& xx, float& xy, float& yy)
0337
0338 {
0339 float e;
0340 fOwner->Momenta(&fHitList, e, x, y, xx, yy, xy);
0341 }
0342
0343
0344
0345 float EmcCluster::GetProb(float& chi2, int& ndf)
0346 {
0347 float e;
0348 float xg;
0349 float yg;
0350 float zg;
0351 e = GetTotalEnergy();
0352 xg = 0;
0353 GetGlobalPos(xg, yg, zg);
0354 return fOwner->GetProb(fHitList, e, xg, yg, zg, chi2, ndf);
0355 }
0356
0357
0358
0359 int EmcCluster::GetSubClusters(std::vector<EmcCluster>& PkList, std::vector<EmcModule>& ppeaks, bool dosubclustersplitting)
0360 {
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373 int npk;
0374 int ipk;
0375 int nhit;
0376 int ixypk;
0377 int ixpk;
0378 int iypk;
0379 int in;
0380 int nh;
0381 int ic;
0382 int ixy;
0383 int ix;
0384 int iy;
0385 int nn;
0386 int idx;
0387 int idy;
0388 int ig;
0389 int ng;
0390 int igmpk1[fgMaxNofPeaks];
0391 int igmpk2[fgMaxNofPeaks];
0392 int PeakCh[fgMaxNofPeaks];
0393 float epk[fgMaxNofPeaks * 2];
0394 float xpk[fgMaxNofPeaks * 2];
0395 float ypk[fgMaxNofPeaks * 2];
0396 float ratio;
0397 float eg;
0398 float dx;
0399 float dy;
0400 float a;
0401 float *Energy[fgMaxNofPeaks];
0402 float *totEnergy;
0403 float *tmpEnergy;
0404 EmcModule *phit;
0405 EmcModule *hlist;
0406 EmcModule *vv;
0407 EmcCluster peak(fOwner);
0408 std::vector<EmcModule>::iterator ph;
0409 std::vector<EmcModule> hl;
0410
0411 PkList.clear();
0412 ppeaks.clear();
0413
0414 nhit = fHitList.size();
0415
0416 if (nhit <= 0)
0417 {
0418 return 0;
0419 }
0420
0421 hlist = new EmcModule[nhit];
0422
0423 ph = fHitList.begin();
0424 vv = hlist;
0425 while (ph != fHitList.end())
0426 {
0427 *vv++ = *ph++;
0428 }
0429
0430
0431 qsort(hlist, nhit, sizeof(EmcModule), BEmcRec::HitNCompare);
0432
0433
0434
0435
0436
0437 int maxc=0;
0438 float maxamp = 0;
0439
0440 npk = 0;
0441 for (ic = 0; ic < nhit; ic++)
0442 {
0443 float amp = hlist[ic].amp;
0444 if (amp > fOwner->GetPeakThreshold())
0445 {
0446 int ich = hlist[ic].ich;
0447
0448
0449
0450 int ichmax = ((ich / fOwner->GetNx() + 2) * fOwner->GetNx()) - 1;
0451 int ichmin = (ich / fOwner->GetNx() - 1) * fOwner->GetNx();
0452 int ixc = ich - (ich / fOwner->GetNx() * fOwner->GetNx());
0453 int inA = ic + 1;
0454
0455 while ((inA < nhit) && (hlist[inA].ich <= ichmax))
0456 {
0457 int ixA = hlist[inA].ich - (hlist[inA].ich / fOwner->GetNx() * fOwner->GetNx());
0458
0459 if ((std::abs(fOwner->iTowerDist(ixA, ixc)) <= 1) && (hlist[inA].amp >= amp))
0460 {
0461 goto new_ic;
0462 }
0463 inA++;
0464 }
0465 inA = ic - 1;
0466
0467 while ((inA >= 0) && (hlist[inA].ich >= ichmin))
0468 {
0469 int ixA = hlist[inA].ich - (hlist[inA].ich / fOwner->GetNx() * fOwner->GetNx());
0470
0471 if ((std::abs(fOwner->iTowerDist(ixA, ixc)) <= 1) && (hlist[inA].amp > amp))
0472 {
0473 goto new_ic;
0474 }
0475 inA--;
0476 }
0477 if (npk >= fgMaxNofPeaks)
0478 {
0479 delete[] hlist;
0480 std::cout << "!!! Error in EmcCluster::GetSubClusters(): too many peaks in a cluster (>"
0481 << fgMaxNofPeaks
0482 << "). May need tower energy threshold increase for clustering." << std::endl;
0483 return -1;
0484 }
0485
0486
0487 if (amp > maxamp) {
0488 maxamp = amp;
0489 maxc = npk;
0490 }
0491 PeakCh[npk] = ic;
0492 npk++;
0493 }
0494 new_ic:
0495 continue;
0496 }
0497
0498
0499
0500
0501
0502
0503
0504 if(!dosubclustersplitting){
0505 hl.clear();
0506 for (int ich = 0; ich < nhit; ich++)
0507 {
0508 hl.push_back(hlist[ich]);
0509 }
0510 peak.ReInitialize(hl);
0511 PkList.push_back(peak);
0512
0513 if (npk > 0)
0514 {
0515 ppeaks.push_back(hlist[PeakCh[maxc]]);
0516 }
0517 else
0518 {
0519 ppeaks.push_back(GetMaxTower());
0520 }
0521 delete[] hlist;
0522 return 1;
0523 }
0524
0525
0526
0527 if(npk <= 1)
0528 {
0529 hl.clear();
0530 for (int ich = 0; ich < nhit; ich++)
0531 {
0532 hl.push_back(hlist[ich]);
0533 }
0534 peak.ReInitialize(hl);
0535 PkList.push_back(peak);
0536
0537 if (npk == 1)
0538 {
0539 ppeaks.push_back(hlist[PeakCh[0]]);
0540 }
0541 else
0542 {
0543 ppeaks.push_back(GetMaxTower());
0544 }
0545
0546 delete[] hlist;
0547 return 1;
0548 }
0549
0550
0551
0552 for (ipk = 0; ipk < npk; ipk++)
0553 {
0554 Energy[ipk] = new float[nhit];
0555 }
0556 totEnergy = new float[nhit];
0557 tmpEnergy = new float[nhit];
0558 for (int i = 0; i < nhit; ++i)
0559 {
0560 totEnergy[i] = 0.0;
0561 tmpEnergy[i] = 0.0;
0562 }
0563
0564
0565
0566 ratio = 1.;
0567 for (int iter = 0; iter < fgPeakIter; iter++)
0568 {
0569 BEmcRec::ZeroVector(tmpEnergy, nhit);
0570 for (ipk = 0; ipk < npk; ipk++)
0571 {
0572 ic = PeakCh[ipk];
0573 if (iter > 0)
0574 {
0575 ratio = Energy[ipk][ic] / totEnergy[ic];
0576 }
0577 eg = hlist[ic].amp * ratio;
0578 ixypk = hlist[ic].ich;
0579 iypk = ixypk / fOwner->GetNx();
0580 ixpk = ixypk - iypk * fOwner->GetNx();
0581 epk[ipk] = eg;
0582 xpk[ipk] = 0.;
0583 ypk[ipk] = 0.;
0584
0585 int ichmax = ((iypk + 2) * fOwner->GetNx()) - 1;
0586 int ichmin = (iypk - 1) * fOwner->GetNx();
0587
0588
0589 if (ic < nhit - 1)
0590 {
0591 for (in = ic + 1; in < nhit; in++)
0592 {
0593 ixy = hlist[in].ich;
0594 iy = ixy / fOwner->GetNx();
0595 ix = ixy - iy * fOwner->GetNx();
0596
0597
0598 if (ixy > ichmax)
0599 {
0600 break;
0601 }
0602
0603 idx = fOwner->iTowerDist(ixpk, ix);
0604 idy = iy - iypk;
0605 if (abs(idx) <= 1)
0606 {
0607 if (iter > 0)
0608 {
0609 ratio = Energy[ipk][in] / totEnergy[in];
0610 }
0611 eg = hlist[in].amp * ratio;
0612 epk[ipk] += eg;
0613 xpk[ipk] += eg * idx;
0614 ypk[ipk] += eg * idy;
0615 }
0616 }
0617 }
0618
0619
0620 if (ic >= 1)
0621 {
0622 for (in = ic - 1; in >= 0; in--)
0623 {
0624 ixy = hlist[in].ich;
0625 iy = ixy / fOwner->GetNx();
0626 ix = ixy - iy * fOwner->GetNx();
0627
0628
0629 if (ixy < ichmin)
0630 {
0631 break;
0632 }
0633
0634 idx = fOwner->iTowerDist(ixpk, ix);
0635 idy = iy - iypk;
0636 if (abs(idx) <= 1)
0637 {
0638 if (iter > 0)
0639 {
0640 ratio = Energy[ipk][in] / totEnergy[in];
0641 }
0642 eg = hlist[in].amp * ratio;
0643 epk[ipk] += eg;
0644 xpk[ipk] += eg * idx;
0645 ypk[ipk] += eg * idy;
0646 }
0647 }
0648 }
0649
0650 xpk[ipk] = xpk[ipk] / epk[ipk] + ixpk;
0651 ypk[ipk] = ypk[ipk] / epk[ipk] + iypk;
0652
0653
0654 for (in = 0; in < nhit; in++)
0655 {
0656 ixy = hlist[in].ich;
0657 iy = ixy / fOwner->GetNx();
0658 ix = ixy - iy * fOwner->GetNx();
0659 dx = fOwner->fTowerDist(float(ix), xpk[ipk]);
0660 dy = ypk[ipk] - iy;
0661 a = 0;
0662
0663
0664 if (ABS(dx) < 2.5 && ABS(dy) < 2.5)
0665 {
0666
0667 a = epk[ipk] * fOwner->PredictEnergy(epk[ipk], xpk[ipk], ypk[ipk], ix, iy);
0668 }
0669
0670 Energy[ipk][in] = a;
0671 tmpEnergy[in] += a;
0672 }
0673
0674 }
0675 float flim = 0.000001;
0676 for (in = 0; in < nhit; in++)
0677 {
0678 if (tmpEnergy[in] > flim)
0679 {
0680 totEnergy[in] = tmpEnergy[in];
0681 }
0682 else
0683 {
0684 totEnergy[in] = flim;
0685 }
0686 }
0687 }
0688
0689 phit = new EmcModule[nhit];
0690
0691 ng = 0;
0692 for (ipk = 0; ipk < npk; ipk++)
0693 {
0694 nh = 0;
0695
0696
0697 for (in = 0; in < nhit; in++)
0698 {
0699 if (tmpEnergy[in] > 0)
0700 {
0701 ixy = hlist[in].ich;
0702 a = hlist[in].amp * Energy[ipk][in] / tmpEnergy[in];
0703 if (a > fgEmin)
0704 {
0705 phit[nh].ich = ixy;
0706 phit[nh].amp = a;
0707 phit[nh].tof = hlist[in].tof;
0708
0709 nh++;
0710 }
0711 }
0712 }
0713
0714
0715 if (nh > 0)
0716 {
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729 igmpk1[ipk] = ng;
0730 igmpk2[ipk] = ng;
0731
0732 ng++;
0733 }
0734 else
0735 {
0736 igmpk1[ipk] = -1;
0737 igmpk2[ipk] = -1;
0738 }
0739 }
0740
0741 BEmcRec::ZeroVector(tmpEnergy, nhit);
0742 for (ipk = 0; ipk < npk; ipk++)
0743 {
0744 ig = igmpk1[ipk];
0745 if (ig >= 0)
0746 {
0747
0748
0749
0750 for (in = 0; in < nhit; in++)
0751 {
0752 Energy[ipk][in] = 0;
0753 for (ig = igmpk1[ipk]; ig <= igmpk2[ipk]; ig++)
0754 {
0755 ixy = hlist[in].ich;
0756 iy = ixy / fOwner->GetNx();
0757 ix = ixy - iy * fOwner->GetNx();
0758 dx = fOwner->fTowerDist(float(ix), xpk[ig]);
0759 dy = ypk[ig] - iy;
0760
0761 a = epk[ig] * fOwner->PredictEnergy(epk[ig], xpk[ig], ypk[ig], ix, iy);
0762 Energy[ipk][in] += a;
0763 tmpEnergy[in] += a;
0764 }
0765 }
0766 }
0767 }
0768
0769 nn = 0;
0770 for (ipk = 0; ipk < npk; ipk++)
0771 {
0772 nh = 0;
0773 for (in = 0; in < nhit; in++)
0774 {
0775 if (tmpEnergy[in] > 0)
0776 {
0777 ixy = hlist[in].ich;
0778 a = hlist[in].amp * Energy[ipk][in] / tmpEnergy[in];
0779 if (a > fgEmin)
0780 {
0781 phit[nh].ich = ixy;
0782 phit[nh].amp = a;
0783 phit[nh].tof = hlist[in].tof;
0784
0785 nh++;
0786 }
0787 }
0788 }
0789 if (nh > 0)
0790 {
0791
0792 ppeaks.push_back(hlist[PeakCh[ipk]]);
0793 hl.clear();
0794 for (in = 0; in < nh; in++)
0795 {
0796 hl.push_back(phit[in]);
0797 }
0798 peak.ReInitialize(hl);
0799 PkList.push_back(peak);
0800 nn++;
0801 }
0802 }
0803
0804 delete[] phit;
0805 delete[] hlist;
0806 for (ipk = 0; ipk < npk; ipk++)
0807 {
0808 delete[] Energy[ipk];
0809 }
0810 delete[] totEnergy;
0811 delete[] tmpEnergy;
0812
0813 return nn;
0814 }