41 #include "AliRunLoader.h"
43 #include <Riostream.h>
48 #include "AliCodeTimer.h"
85 fLowestPixelCharge(0),
87 fLowestClusterCharge(0)
91 fkSegmentation[1] = fkSegmentation[0] = 0x0;
93 if (fPlot) fDebug = 1;
104 AliInfo(Form(
"Total clusters %d AddVirtualPad needed %d",
118 for ( Int_t i = 0; i < 2; ++i )
135 AliRunLoader *runLoader = AliRunLoader::Instance();
136 fEventNumber = runLoader ? runLoader->GetEventNumber() : 0;
196 for ( Int_t i = 0; i < mult; ++i )
222 printf(
" bbb %3d %1d %8.4f %8.4f %8.4f %8.4f %6.1f %3d %3d %2d %1d %1d \n",
229 if (!cluster)
return kFALSE;
235 AliDebug(1,
"No pixel for the above cluster");
241 Int_t nMax = 1, localMax[100], maxPos[100];
242 Double_t maxVal[100];
244 Int_t iSimple = 0, nInX = -1, nInY;
248 if (nInX < 4 && nInY < 4)
257 if (nMax > 1) TMath::Sort(nMax, maxVal, maxPos, kTRUE);
261 for (Int_t i = 0; i < nMax; ++i)
273 for (Int_t j = 0; j < mult; ++j)
312 AliCodeTimerAuto(
"",0)
323 AliDebug(2,
"Start of CheckPreCluster=");
346 Int_t* flags =
new Int_t[npad];
347 for (Int_t j = 0; j < npad; ++j) flags[j] = 0;
350 for ( Int_t i = 0; i < npad; ++i)
353 if ( padi->
Cathode() != 0 )
continue;
354 for (Int_t j = i+1; j < npad; ++j)
357 if ( padj->
Cathode() != 1 )
continue;
359 flags[i] = flags[j] = 1;
365 for (Int_t i = 0; i < npad; ++i)
367 if (!flags[i]) ++nFlags;
373 if (
fDebug) cout <<
" nFlags: " << nFlags << endl;
375 for (Int_t i = 0; i < npad; ++i)
378 if (flags[i])
continue;
380 Int_t cath1 = TMath::Even(cath);
385 if (!mpPad.
IsValid())
continue;
387 AliDebug(2,Form(
"Releasing the following pad : de,cath,ix,iy %d,%d,%d,%d charge %e",
389 toBeRemoved.AddLast(pad);
392 Int_t nRemove = toBeRemoved.GetEntriesFast();
393 for ( Int_t i = 0; i < nRemove; ++i )
395 cluster->
RemovePad(static_cast<AliMUONPad*>(toBeRemoved.UncheckedAt(i)));
413 for ( Int_t i = 0; i < mult; ++i )
422 if ( pad->
Charge() < cmin )
431 else if ( pad->
Charge() > cmax )
437 AliDebug(2,Form(
"Pad imin,imax %d,%d cmin,cmax %e,%e",
438 imin,imax,cmin,cmax));
442 Double_t* dist =
new Double_t[mult];
449 for ( Int_t i = 0; i < mult; ++i )
452 if ( i == imax)
continue;
455 Double_t dx = (pad->
X()-padmax->
X())/padmax->
DX()/2.0;
456 Double_t dy = (pad->
Y()-padmax->
Y())/padmax->
DY()/2.0;
457 dist[i] = TMath::Sqrt(dx*dx+dy*dy);
460 dmin = dist[i] + 1E-3;
466 TMath::Sort(mult,dist,flags,kFALSE);
467 Double_t xmax(-1), distPrev(999);
470 for ( Int_t i = 0; i < mult; ++i )
472 Int_t indx = flags[i];
475 if ( dist[indx] > dmin )
478 Double_t dx = (pad->
X()-padmax->
X())/padmax->
DX()/2.0;
479 Double_t dy = (pad->
Y()-padmax->
Y())/padmax->
DY()/2.0;
482 if (dx >= 0 && dy >= 0)
continue;
483 if (TMath::Abs(dx) > TMath::Abs(dy) && dx >= 0)
continue;
484 if (TMath::Abs(dy) > TMath::Abs(dx) && dy >= 0)
continue;
486 if (dist[indx] > distPrev + 1)
break;
487 if ( pad->
Charge() <= cmax || TMath::Abs(dist[indx]-xmax) < 1E-3 )
490 if (TMath::Abs(dist[indx]-xmax) < 1.e-3)
492 cmax = TMath::Max(pad->
Charge(),cmax);
499 distPrev = dist[indx];
500 AliDebug(2,Form(
"Releasing the following pad : de,cath,ix,iy %d,%d,%d,%d charge %e",
504 toBeRemoved.AddLast(pad);
508 Int_t nRemove = toBeRemoved.GetEntriesFast();
509 for ( Int_t i = 0; i < nRemove; ++i )
511 cluster->
RemovePad(static_cast<AliMUONPad*>(toBeRemoved.UncheckedAt(i)));
518 AliDebug(2,
"End of CheckPreClusterTwoCathodes=");
533 for ( Int_t i = 0; i < nPix; ++i )
538 pixelI->
Size(0),pixelI->
Size(1),0.0);
540 for ( Int_t j = i+1; j < nPix; ++j )
545 pixelJ->
Size(0),pixelJ->
Size(1),0.0);
550 AliInfo(Form(
"The following 2 pixels (%d and %d) overlap !",i,j));
573 AliWarning(
"Got no pad at all ?!");
589 for ( Int_t i = npad; i < nPix; ++i )
609 Double_t width[2] = {dim.X(), dim.Y()}, xy0[2]={99999,99999};
612 for ( Int_t i = 0; i < mult; ++i) {
614 for (Int_t j = 0; j < 2; ++j) {
616 xy0[j] = pad->
Coord(j);
620 if (found[0] && found[1])
break;
623 Double_t min[2], max[2];
624 Int_t cath0 = 0, cath1 = 1;
629 Double_t leftDownX, leftDownY;
631 Double_t rightUpX, rightUpY;
637 if (cath1 != cath0) {
640 min[0] = TMath::Max (min[0], leftDownX);
641 min[1] = TMath::Max (min[1], leftDownY);
642 max[0] = TMath::Min (max[0], rightUpX);
643 max[1] = TMath::Min (max[1], rightUpY);
648 Int_t nbins[2]={0,0};
649 for (Int_t i = 0; i < 2; ++i) {
650 Double_t dist = (min[i] - xy0[i]) / width[i] / 2;
651 if (TMath::Abs(dist) < 1.e-6) dist = -1.e-6;
652 min[i] = xy0[i] + (TMath::Nint(dist-TMath::Sign(1.e-6,dist))
653 + TMath::Sign(0.5,dist)) * width[i] * 2;
654 nbins[i] = TMath::Nint ((max[i] - min[i]) / width[i] / 2);
655 if (nbins[i] == 0) ++nbins[i];
656 max[i] = min[i] + nbins[i] * width[i] * 2;
661 TH2D *hist1 =
new TH2D (
"Grid",
"", nbins[0], min[0], max[0], nbins[1], min[1], max[1]);
662 TH2D *hist2 =
new TH2D (
"Entries",
"", nbins[0], min[0], max[0], nbins[1], min[1], max[1]);
663 TAxis *xaxis = hist1->GetXaxis();
664 TAxis *yaxis = hist1->GetYaxis();
667 for ( Int_t i = 0; i < mult; ++i) {
669 Int_t ix0 = xaxis->FindBin(pad->
X());
670 Int_t iy0 = yaxis->FindBin(pad->
Y());
675 for (Int_t i = 1; i <= nbins[0]; ++i) {
676 Double_t x = xaxis->GetBinCenter(i);
677 for (Int_t j = 1; j <= nbins[1]; ++j) {
678 if (hist2->GetBinContent(hist2->GetBin(i,j)) < 0.1)
continue;
681 if (cath0 != cath1) {
683 Double_t cont = hist2->GetBinContent(hist2->GetBin(i,j));
684 if (cont < 999.)
continue;
685 if (cont-Int_t(cont/1000.)*1000. < 0.5)
continue;
687 Double_t y = yaxis->GetBinCenter(j);
688 Double_t charge = hist1->GetBinContent(hist1->GetBin(i,j));
697 pixPtr->
SetSize(0,width[0]/2.);
698 pixPtr->
Shift(0,-width[0]/4.);
699 pixPtr =
new AliMUONPad(pixPtr->
X()+width[0], pixPtr->
Y(), width[0]/2., width[1], pixPtr->
Charge());
710 TH2D *hist1, TH2D *hist2)
714 TAxis *axis = idir == 0 ? hist1->GetXaxis() : hist1->GetYaxis();
715 Int_t nbins = axis->GetNbins(), cath = pad->
Cathode();
716 Double_t bin = axis->GetBinWidth(1), amask = TMath::Power(1000.,cath*1.);
720 for (Int_t i = 0; i < nbinPad; ++i) {
721 Int_t ixy = idir == 0 ? ix0 + i : iy0 + i;
722 if (ixy > nbins)
break;
723 Double_t lowEdge = axis->GetBinLowEdge(ixy);
725 if (idir == 0)
PadOverHist(1, ixy, iy0, pad, hist1, hist2);
728 Double_t cont = pad->
Charge();
729 if (hist2->GetBinContent(hist2->GetBin(ix0, ixy)) > 0.1)
730 cont = TMath::Min (hist1->GetBinContent(hist1->GetBin(ix0, ixy)), cont);
731 hist1->SetBinContent(hist1->GetBin(ix0, ixy), cont);
733 hist2->SetBinContent(hist2->GetBin(ix0, ixy), hist2->GetBinContent(hist2->GetBin(ix0, ixy))+amask);
737 for (Int_t i = -1; i > -nbinPad; --i) {
738 Int_t ixy = idir == 0 ? ix0 + i : iy0 + i;
740 Double_t upEdge = axis->GetBinUpEdge(ixy);
741 if (upEdge - fgkDistancePrecision < pad->Coord(idir) - pad->
Size(idir))
break;
742 if (idir == 0)
PadOverHist(1, ixy, iy0, pad, hist1, hist2);
745 Double_t cont = pad->
Charge();
746 if (hist2->GetBinContent(hist2->GetBin(ix0, ixy)) > 0.1)
747 cont = TMath::Min (hist1->GetBinContent(hist1->GetBin(ix0, ixy)), cont);
748 hist1->SetBinContent(hist1->GetBin(ix0, ixy), cont);
750 hist2->SetBinContent(hist2->GetBin(ix0, ixy), hist2->GetBinContent(hist2->GetBin(ix0, ixy))+amask);
785 for (Int_t j = 0; j < npadTot*nPix; ++j) coef[j] = 0.;
786 for (Int_t j = 0; j < nPix; ++j) probi[j] = 0.;
789 for ( Int_t j = 0; j < mult; ++j )
794 for ( Int_t ipix = 0; ipix < nPix; ++ipix )
796 Int_t indx1 = indx + ipix;
815 probi[ipix] += coef[indx1];
829 AliDebug(2,Form(
"nPix=%d iSimple=%d, precluster=",nPix,iSimple));
834 AliDebug(1,
"No pixels, why am I here then ?");
841 for (Int_t i = 0; i < npadTot; ++i)
848 Double_t* probi(0x0);
853 Double_t xylim[4] = {pixPtr->
X(), -pixPtr->
X(), pixPtr->
Y(), -pixPtr->
Y()};
861 AliDebug(2,Form(
"lc %d nPix %d(%d) npadTot %d npadOK %d",lc,nPix,
fPixArray->GetLast()+1,npadTot,npadOK));
865 coef =
new Double_t [npadTot*nPix];
866 probi =
new Double_t [nPix];
871 for (Int_t ipix = 0; ipix < nPix; ++ipix)
873 if (probi[ipix] < 0.01)
876 AliDebug(2,Form(
"Setting the following pixel to invisible as its probi<0.01:"));
883 Mlem(cluster,coef, probi, 15);
887 for ( Int_t ipix = 1; ipix < nPix; ++ipix )
889 pixPtr =
Pixel(ipix);
890 for ( Int_t i = 0; i < 2; ++i )
893 if (pixPtr->
Coord(i) < xylim[indx]) xylim[indx] = pixPtr->
Coord(i);
894 else if (-pixPtr->
Coord(i) < xylim[indx+1]) xylim[indx+1] = -pixPtr->
Coord(i);
897 }
else pixPtr =
Pixel(0);
899 for (Int_t i = 0; i < 4; i++)
901 xylim[i] -= pixPtr->
Size(i/2);
904 Int_t nx = TMath::Nint ((-xylim[1]-xylim[0])/pixPtr->
Size(0)/2);
905 Int_t ny = TMath::Nint ((-xylim[3]-xylim[2])/pixPtr->
Size(1)/2);
908 AliDebug(2,Form(
"lc %d pixPtr size = %e,%e nx,ny=%d,%d xylim=%e,%e,%e,%e",
909 lc,pixPtr->
Size(0),pixPtr->
Size(1),nx,ny,
910 xylim[0],-xylim[1],xylim[2],-xylim[3]
917 fHistMlem =
new TH2D(
"mlem",
"mlem",nx,xylim[0],-xylim[1],ny,xylim[2],-xylim[3]);
919 for (Int_t ipix = 0; ipix < nPix; ++ipix)
927 for ( Int_t i = 0; i < nPix; ++i)
934 AliDebug(1,Form(
"Deleting the above cluster (charge %e too low, npadOK=%d)",qTot,npadOK));
938 for ( Int_t i = 0; i < npadTot; ++i)
961 if (TMath::Min(pixPtr->
Size(0),pixPtr->
Size(1)) < 0.07 &&
962 pixPtr->
Size(0) > pixPtr->
Size(1))
break;
973 Int_t indx = (pixPtr->
Size(0)>pixPtr->
Size(1)) ? 0 : 1;
976 Double_t shift[2] = { 0.0, 0.0 };
977 for (Int_t i = 0; i < 4; ++i) xylim[i] = 999;
980 for (Int_t ipix = 0; ipix < nPix1; ++ipix)
991 for (Int_t i = 0; i < 2; ++i)
997 width = -pixPtr2->
Size(indx);
998 pixPtr2->
Shift(indx, width);
1003 for (Int_t j = 0; j < 2; ++j)
1005 shift[j] = pixPtr2->
Coord(j) - xyCOG[j];
1006 shift[j] -= ((Int_t)(shift[j]/pixPtr2->
Size(j)/2))*pixPtr2->
Size(j)*2;
1009 pixPtr2->
Shift(0, -shift[0]);
1010 pixPtr2->
Shift(1, -shift[1]);
1013 else if (nPix < npadOK)
1016 pixPtr2->
Shift(indx, -2*width);
1022 for (Int_t j = 0; j < 4; ++j)
1024 xylim[j] = TMath::Min (xylim[j], (j%2 ? -1 : 1)*pixPtr2->
Coord(j/2));
1031 AliDebug(2,Form(
"After shift:"));
1035 AliDebug(2,Form(
" xyCOG=%9.6f %9.6f xylim=%9.6f,%9.6f,%9.6f,%9.6f",
1038 xylim[2],xylim[3]));
1046 for (Int_t i = 3; i > -1; --i)
1048 if (nPix < npadOK &&
1049 TMath::Abs((i%2 ? -1 : 1)*xylim[i]-xyCOG[i/2]) < pixPtr2->
Size(i/2))
1053 p->
SetCoord(i/2, xyCOG[i/2]+(i%2 ? 2:-2)*pixPtr2->
Size(i/2));
1054 xylim[i] = p->
Coord(i/2) * (i%2 ? -1 : 1);
1055 j = TMath::Even (i/2);
1057 AliDebug(2,Form(
"Adding pixel on the edge (i=%d) ",i));
1070 AliDebug(2,Form(
"At the end of while loop nPix=%d : ",
fPixArray->GetLast()+1));
1077 Double_t charge = 0;
1080 for (Int_t i = 0; i < nPix; ++i)
1083 charge = pixPtr2->
Charge();
1084 if (charge < thresh)
1092 for (Int_t i = 0; i < nPix; ++i)
1095 charge = pixPtr2->
Charge();
1096 if (charge > 0)
continue;
1103 Mlem(cluster,coef,probi,2);
1110 for (Int_t i = 0; i < nPix; ++i)
1142 for (Int_t i = 0; i <
fPixArray->GetEntriesFast(); ++i) {
1153 const Double_t* coef, Double_t* probi,
1158 Int_t nPix =
fPixArray->GetEntriesFast();
1162 Double_t* probi1 =
new Double_t[nPix];
1163 Double_t probMax = TMath::MaxElement(nPix,probi);
1165 for (Int_t iter = 0; iter < nIter; ++iter)
1168 for (Int_t ipix = 0; ipix < nPix; ++ipix)
1173 if (probi[ipix] < 0.01)
continue;
1175 probi1[ipix] = probMax;
1176 for (Int_t j = 0; j < npad; ++j)
1182 Int_t indx1 = j*nPix;
1183 Int_t indx = indx1 + ipix;
1185 for (Int_t i = 0; i < nPix; ++i)
1193 probi1[ipix] -= coef[indx];
1198 if (sum1 > 1.e-6) sum += pad->
Charge()*coef[indx]/sum1;
1201 if (probi1[ipix] > 1.e-6)
1209 for (Int_t i = 0; i < nPix; ++i) {
1212 qTot += pixPtr->
Charge();
1228 Int_t ixmax, iymax, ix, nsumx=0, nsumy=0, nsum=0;
1229 Int_t i1 = -9, j1 = -9;
1230 fHistMlem->GetMaximumBin(ixmax,iymax,ix);
1233 Double_t thresh =
fHistMlem->GetMaximum()/10;
1234 Double_t x, y, cont, xq=0, yq=0, qq=0;
1236 Int_t ie = TMath::Min(ny,iymax+1), je = TMath::Min(nx,ixmax+1);
1237 for (Int_t i = TMath::Max(1,iymax-1); i <= ie; ++i) {
1238 y =
fHistMlem->GetYaxis()->GetBinCenter(i);
1239 for (Int_t j = TMath::Max(1,ixmax-1); j <= je; ++j) {
1241 if (cont < thresh)
continue;
1242 if (i != i1) {i1 = i; nsumy++;}
1243 if (j != j1) {j1 = j; nsumx++;}
1244 x =
fHistMlem->GetXaxis()->GetBinCenter(j);
1253 Int_t i2 = 0, j2 = 0;
1257 for (Int_t i = TMath::Max(1,iymax-1); i <= ie; ++i) {
1258 if (i == iymax)
continue;
1259 for (Int_t j = TMath::Max(1,ixmax-1); j <= je; ++j) {
1263 x =
fHistMlem->GetXaxis()->GetBinCenter(j);
1264 y =
fHistMlem->GetYaxis()->GetBinCenter(i);
1273 if (i2 != i1) nsumy++;
1274 if (j2 != j1) nsumx++;
1281 for (Int_t j = TMath::Max(1,ixmax-1); j <= je; ++j) {
1282 if (j == ixmax)
continue;
1283 for (Int_t i = TMath::Max(1,iymax-1); i <= ie; ++i) {
1287 x =
fHistMlem->GetXaxis()->GetBinCenter(j);
1288 y =
fHistMlem->GetYaxis()->GetBinCenter(i);
1297 if (i2 != i1) nsumy++;
1298 if (j2 != j1) nsumx++;
1302 xyc[0] = xq/qq; xyc[1] = yq/qq;
1303 AliDebug(2,Form(
"x,y COG = %e,%e",xyc[0],xyc[1]));
1312 Int_t nPix =
fPixArray->GetEntriesFast(), imin = 0;
1313 Double_t rmin = 99999, dx = 0, dy = 0, r = 0;
1314 Double_t xc = pixPtr0->
Coord(0), yc = pixPtr0->
Coord(1);
1317 for (Int_t i = 0; i < nPix; ++i) {
1320 dx = (xc - pixPtr->
Coord(0)) / pixPtr->
Size(0);
1321 dy = (yc - pixPtr->
Coord(1)) / pixPtr->
Size(1);
1322 r = dx *dx + dy * dy;
1323 if (r < rmin) { rmin = r; imin = i; }
1336 gPad->Range(area.LeftBorder(),area.DownBorder(),area.RightBorder(),area.UpBorder());
1338 gVirtualX->SetFillStyle(1001);
1339 gVirtualX->SetFillColor(3);
1340 gVirtualX->SetLineColor(3);
1344 for ( Int_t i = 0; i <=
fPixArray->GetLast(); ++i)
1348 gPad->PaintBox(pixel->
Coord(0)-pixel->
Size(0)*s,
1364 gVirtualX->SetFillStyle(0);
1368 gVirtualX->SetLineColor(1);
1369 gVirtualX->SetLineWidth(2);
1370 gVirtualX->SetFillStyle(0);
1371 gVirtualX->SetTextColor(1);
1372 gVirtualX->SetTextAlign(22);
1374 for ( Int_t i = 0; i <=
fPixArray->GetLast(); ++i)
1377 gPad->PaintBox(pixel->
Coord(0)-pixel->
Size(0),
1381 gVirtualX->SetTextSize(pixel->
Size(0)*60);
1383 gPad->PaintText(pixel->
Coord(0),pixel->
Coord(1),Form(
"%d",(Int_t)(pixel->
Charge())));
1394 AliDebug(1,Form(
"nPix=%d",pixArray->GetLast()+1));
1396 Double_t xylim[4] = {999, 999, 999, 999};
1398 Int_t nPix = pixArray->GetEntriesFast();
1400 if ( nPix <= 0 )
return 0;
1403 for (Int_t ipix = 0; ipix < nPix; ++ipix) {
1404 pixPtr = (
AliMUONPad*) pixArray->UncheckedAt(ipix);
1405 for (Int_t i = 0; i < 4; ++i)
1406 xylim[i] = TMath::Min (xylim[i], (i%2 ? -1 : 1)*pixPtr->
Coord(i/2));
1408 for (Int_t i = 0; i < 4; ++i) xylim[i] -= pixPtr->
Size(i/2);
1410 Int_t nx = TMath::Nint ((-xylim[1]-xylim[0])/pixPtr->
Size(0)/2);
1411 Int_t ny = TMath::Nint ((-xylim[3]-xylim[2])/pixPtr->
Size(1)/2);
1412 if (pixArray ==
fPixArray)
fHistAnode =
new TH2D(
"anode",
"anode",nx,xylim[0],-xylim[1],ny,xylim[2],-xylim[3]);
1413 else fHistAnode =
new TH2D(
"anode1",
"anode1",nx,xylim[0],-xylim[1],ny,xylim[2],-xylim[3]);
1414 for (Int_t ipix = 0; ipix < nPix; ++ipix) {
1415 pixPtr = (
AliMUONPad*) pixArray->UncheckedAt(ipix);
1420 Int_t nMax = 0, indx, nxy = ny * nx;
1421 Int_t *isLocalMax =
new Int_t[nxy];
1422 for (Int_t i = 0; i < nxy; ++i) isLocalMax[i] = 0;
1424 for (Int_t i = 1; i <= ny; ++i) {
1426 for (Int_t j = 1; j <= nx; ++j) {
1429 if (isLocalMax[indx+j-1] != 0)
continue;
1434 for (Int_t i = 1; i <= ny; ++i) {
1436 for (Int_t j = 1; j <= nx; ++j) {
1437 if (isLocalMax[indx+j-1] > 0) {
1438 localMax[nMax] = indx + j - 1;
1441 if (nMax > 99)
break;
1445 AliError(
" Too many local maxima !!!");
1449 if (
fDebug) cout <<
" Local max: " << nMax << endl;
1450 delete [] isLocalMax;
1459 Int_t nx = hist->GetNbinsX();
1460 Int_t ny = hist->GetNbinsY();
1461 Int_t cont = TMath::Nint (hist->GetBinContent(hist->GetBin(j,i)));
1462 Int_t cont1 = 0, indx = (i-1)*nx+j-1, indx1 = 0, indx2 = 0;
1464 Int_t ie = i + 2, je = j + 2;
1465 for (Int_t i1 = i-1; i1 < ie; ++i1) {
1466 if (i1 < 1 || i1 > ny)
continue;
1467 indx1 = (i1 - 1) * nx;
1468 for (Int_t j1 = j-1; j1 < je; ++j1) {
1469 if (j1 < 1 || j1 > nx)
continue;
1470 if (i == i1 && j == j1)
continue;
1471 indx2 = indx1 + j1 - 1;
1472 cont1 = TMath::Nint (hist->GetBinContent(hist->GetBin(j1,i1)));
1473 if (cont < cont1) { isLocalMax[indx] = -1;
return; }
1474 else if (cont > cont1) isLocalMax[indx2] = -1;
1476 isLocalMax[indx] = 1;
1477 if (isLocalMax[indx2] == 0) {
1479 if (isLocalMax[indx2] < 0) { isLocalMax[indx] = -1;
return; }
1480 else isLocalMax[indx2] = -1;
1485 isLocalMax[indx] = 1;
1490 const Int_t *localMax, Int_t iMax)
1505 Int_t ic = localMax[iMax] / nx + 1;
1506 Int_t jc = localMax[iMax] % nx + 1;
1507 Int_t nxy = ny * nx;
1508 Bool_t *used =
new Bool_t[nxy];
1509 for (Int_t i = 0; i < nxy; ++i) used[i] = kFALSE;
1514 Double_t wx =
fHistAnode->GetXaxis()->GetBinWidth(1)/2;
1515 Double_t wy =
fHistAnode->GetYaxis()->GetBinWidth(1)/2;
1516 Double_t yc =
fHistAnode->GetYaxis()->GetBinCenter(ic);
1517 Double_t xc =
fHistAnode->GetXaxis()->GetBinCenter(jc);
1520 used[(ic-1)*nx+jc-1] = kTRUE;
1524 Int_t nPix =
fPixArray->GetEntriesFast();
1527 for (Int_t i = 0; i < nPix; ++i)
1535 for (Int_t i = 0; i < npad; ++i)
1541 for (Int_t i = 0; i < nPix; ++i)
1544 for (Int_t j = 0; j < npad; ++j)
1553 if (
fDebug) { cout << j <<
" "; pad->
Print(
"full"); }
1567 Int_t nx = hist->GetNbinsX();
1568 Int_t ny = hist->GetNbinsY();
1569 Double_t cont1, cont = hist->GetBinContent(hist->GetBin(jc,ic));
1572 Int_t ie = TMath::Min(ic+1,ny), je = TMath::Min(jc+1,nx);
1573 for (Int_t i = TMath::Max(ic-1,1); i <= ie; ++i) {
1574 for (Int_t j = TMath::Max(jc-1,1); j <= je; ++j) {
1575 cont1 = hist->GetBinContent(hist->GetBin(j,i));
1576 if (cont1 > cont)
continue;
1578 pixPtr =
new AliMUONPad (hist->GetXaxis()->GetBinCenter(j),
1579 hist->GetYaxis()->GetBinCenter(i), 0, 0, cont1);
1591 if (
this == &rhs)
return *
this;
1593 AliFatal(
"Not implemented.");
1605 Int_t nonb[2] = {1, 0};
1614 Bool_t same = kFALSE;
1618 Bool_t check[2] = {kFALSE, kFALSE};
1620 nxy[0] = nxy[1] = 0;
1621 for (Int_t inb = 0; inb < 2; ++inb) {
1622 cn = cluster.
NofPads(nonb[inb], 0, kTRUE);
1628 if (inb == 0 && nxy[0] < 2) nonb[inb] = !nonb[inb];
1633 if (nxy[0] > 2) check[0] = kFALSE;
1634 if (nxy[1] > 2) check[1] = kFALSE;
1636 if (!check[0] && !check[1])
return;
1638 for (Int_t inb = 0; inb < 2; ++inb) {
1639 if (!check[inb])
continue;
1642 Int_t maxPads[2] = {-1, -1};
1643 Double_t amax[2] = {0};
1645 for (Int_t j = 0; j < mult; ++j) {
1647 if (pad->
Cathode() != nonb[inb])
continue;
1648 for (Int_t j2 = 0; j2 < 2; ++j2) {
1649 if (pad->
Charge() > amax[j2]) {
1650 if (j2 == 0) { amax[1] = amax[0]; maxPads[1] = maxPads[0]; }
1651 amax[j2] = pad->
Charge();
1659 Double_t limits[2] = {9999, -9999};
1660 for (Int_t j = 0; j < mult; ++j) {
1662 if (pad->
Cathode() != nonb[inb])
continue;
1663 if (pad->
Coord(inb) < limits[0]) limits[0] = pad->
Coord(inb);
1664 if (pad->
Coord(inb) > limits[1]) limits[1] = pad->
Coord(inb);
1668 Bool_t add = kFALSE;
1670 for (Int_t j = 0; j < 2; ++j) {
1672 if (maxPads[j] < 0)
continue;
1674 if (amax[1] / amax[0] < 0.5)
break;
1685 if (j == 1 && idir == idirAdd)
break;
1693 if (!mppad.
IsValid())
continue;
1701 muonPad.SetReal(kFALSE);
1702 if (
fDebug)
printf(
" ***** Add virtual pad in %d direction ***** %f %f %f %3d %3d %f %f \n",
1703 inb, muonPad.Charge(), muonPad.X(), muonPad.Y(), muonPad.Ix(),
1704 muonPad.Iy(), muonPad.DX(), muonPad.DY());
1714 Int_t &nInX, Int_t &nInY)
const
1723 if ( nInX < 0 ) statusToTest =
fgkZero;
1725 Bool_t mustMatch(kTRUE);
1727 Long_t cn = cluster.
NofPads(statusToTest,mustMatch);
1747 Int_t nForFit = 1, clustFit[1] = {0};
1748 Double_t parOk[3] = {0.};
1752 AliDebug(1,Form(
"nPix=%d",
fPixArray->GetLast()+1));
1755 for (Int_t i = 0; i < mult; ++i)
1786 TString swhat(what);
1788 if ( swhat.Contains(
"precluster") )
static Bool_t AreOverlapping(const AliMUONPad &d1, const AliMUONPad &d2, const TVector2 &precision, AliMpArea &overlapArea)
AliMUONVClusterFinder * fPreClusterFinder
! the pre-clustering worker
Int_t FindNearest(const AliMUONPad *pixPtr0)
Int_t fNClusters
! total number of clusters
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
void BuildPixArrayOneCathode(AliMUONCluster &cluster)
Bool_t IsReal() const
Return info whether this is a real pad or a virtual one.
Interface of a cluster finder.
void SetStatus(Int_t status)
Set status word.
Double_t fLowestPixelCharge
! see AliMUONRecoParam
Bool_t IsSaturated() const
Return info whether this pad is saturated or not.
AliMUONPad * Pixel(Int_t i) const
TObject * BinToPix(TH2 *mlem, Int_t jc, Int_t ic)
Int_t FindLocalMaxima(TObjArray *pixArray, Int_t *localMax, Double_t *maxVal)
A group of adjacent pads.
void RevertCharge()
Set charge to value in backup charge.
void FindCOG(Double_t *xyc)
virtual void Print(Option_t *opt="") const
void Split(const AliMUONCluster &cluster, TH2 *mlem, Double_t *coef, TObjArray &clusterList)
Splitter class for the MLEM algorithm.
A rectangle area positioned in plane..
void PadsInXandY(AliMUONCluster &cluster, Int_t &nInX, Int_t &nInY) const
virtual Bool_t Prepare(Int_t detElemId, TObjArray *pads[2], const AliMpArea &area, const AliMpVSegmentation *segmentations[2])
Double_t DY() const
Return half dimensions in y (cm)
Bool_t MainLoop(AliMUONCluster &cluster, Int_t iSimple)
Int_t Multiplicity() const
virtual Bool_t Prepare(Int_t detElemId, TObjArray *pads[2], const AliMpArea &area)
void Shift(Int_t ixy, Double_t shift)
virtual Bool_t NeedSegmentation() const
TH2D * fHistMlem
! histogram for MLEM procedure
void AddBinSimple(TH2D *mlem, Int_t ic, Int_t jc)
void BuildPixArray(AliMUONCluster &cluster)
build array of pixels
void SetSize(Int_t ixy, Double_t Size)
AliMUONCluster * fPreCluster
! current pre-cluster
virtual Bool_t UsePad(const AliMUONPad &pad)
AliMUONCluster * CheckPrecluster(const AliMUONCluster &cluster)
Check precluster to simplify it (if possible), and return the simplified cluster. ...
static const Int_t fgkMustKeep
do not kill (for pixels)
void ComputeCoefficients(AliMUONCluster &cluster, Double_t *coef, Double_t *probi)
Double_t Y() const
Return position in y (cm)
void SetChargeBackup(Double_t charge)
Set charge backup.
Int_t fClusterNumber
! current cluster number
Bool_t Overlap(const AliMUONPad &pad, const AliMUONPad &pixel)
Checks whether a pad and a pixel have an overlapping area.
void FlagLocalMax(TH2D *hist, Int_t i, Int_t j, Int_t *isLocalMax)
void SetCharge(Double_t charge)
Set charge.
static const TVector2 fgkDecreaseSize
idem
Int_t Iy() const
Return y-index.
void Release()
Detach this pad from a cluster.
static const Int_t fgkZero
pad "basic" state
TObjArray fClusterList
! clusters corresponding to the current pre-cluster
void Simple(AliMUONCluster &cluster)
Process simple cluster.
void LeftDownCorner(Double_t &x, Double_t &y) const
Double_t X() const
Return position in x (cm)
Double_t GetPositionY() const
Return the pad x position (in cm)
virtual ~AliMUONClusterFinderMLEM()
void SetDebug(Int_t debug)
Set debug level.
virtual void Print(Option_t *opt="") const
void MaskPeaks(Int_t mask)
void AddVirtualPad(AliMUONCluster &cluster)
Int_t Cathode() const
Return cathode number.
AliMUONClusterFinderMLEM & operator=(const AliMUONClusterFinderMLEM &rhs)
Not implemented.
Bool_t IsUsed() const
Return true if is used.
Int_t fDebug
! debug level
AliMUONCluster * CheckPreclusterTwoCathodes(AliMUONCluster *cluster)
Double_t Size(Int_t ixy) const
void plot(const std::vector< TH1 * > &v, Double_t min, Double_t max, Double_t factor)
void RemovePad(AliMUONPad *pad)
Int_t fDetElemId
! current DE being processed
AliMUONPad * AddPad(const AliMUONPad &pad)
Int_t fEventNumber
! current event being processed
TObjArray * fPixArray
! collection of pixels
Bool_t IsValid() const
Return validity.
TVector2 Position() const
Return positions in x and y (cm)
virtual AliMpPad PadByPosition(Double_t x, Double_t y, Bool_t warning=true) const =0
Find pad by position.
static const Int_t fgkOver
processing is over
static const Int_t fgkUseForFit
should be used for fit
void RightUpCorner(Double_t &x, Double_t &y) const
virtual AliMUONCluster * NextCluster()=0
void Plot(const char *outputfile)
void SetCoord(Int_t ixy, Double_t Coord)
void Mlem(AliMUONCluster &cluster, const Double_t *coef, Double_t *probi, Int_t nIter)
Long_t NofPads(Int_t cathode, Int_t statusMask, Bool_t matchMask) const
Compute number of pads in X and Y direction for a given cathode.
The abstract base class for the segmentation.
Int_t Ix() const
Return x-index.
AliMpArea Area() const
Area that contains all the pads (whatever the cathode)
Double_t GetDimensionY() const
Return the y pad dimension - half length (in cm)
virtual void Paint(Option_t *opt="")
Int_t PairFirst(MpPair_t pair)
Decode the first integer from encoded pair.
void Print(Option_t *opt="") const
Double_t Charge() const
Return pad charge.
Int_t Fit(const AliMUONCluster &cluster, Int_t iSimple, Int_t nfit, const Int_t *clustFit, TObjArray **clusters, Double_t *parOk, TObjArray &clusterList, TH2 *mlem)
void RemovePixel(Int_t i)
virtual AliMUONCluster * NextCluster()
Double_t Coord(Int_t ixy) const
Class which encapsuate all information about a pad.
Int_t fNAddVirtualPads
! number of clusters for which we added virtual pads
Bool_t WorkOnPreCluster()
Bool_t IsSaturated(Int_t cathode) const
Whether we have at least one saturated pad in a given cathode.
Double_t fLowestClusterCharge
! see AliMUONRecoParam
void FindCluster(AliMUONCluster &cluster, const Int_t *localMax, Int_t iMax)
Double_t GetPositionX() const
Return the pad x position (in cm)
Int_t DetElemId() const
Return detection element id.
AliMUONClusterSplitterMLEM * fSplitter
! helper class to go from pixel arrays to clusters
Float_t ChargeAsymmetry() const
Return the cathode's charges asymmetry.
Float_t ChargeIntegration(Double_t x, Double_t y, const AliMUONPad &pad)
virtual void Paint(Option_t *opt="")
Int_t PairSecond(MpPair_t pair)
Decode the second integer from encoded pair.
virtual void SetChargeHints(Double_t lowestPadCharge, Double_t lowestClusterCharge)
TVector2 MinPadDimensions(Int_t cathode, Int_t statusMask, Bool_t matchMask) const
Return the smallest pad dimensions for a given cathode.
Int_t Status() const
Return status word.
TH2D * fHistAnode
! histogram for local maxima search
Double_t fLowestPadCharge
! see AliMUONRecoParam
static const Double_t fgkDistancePrecision
used to check overlaps and so on
Int_t MaxRawChargeCathode() const
Return the max raw charge on the chathod.
AliMUONPad * Pad(Int_t index) const
Double_t GetDimensionX() const
Return the x pad dimension - half length (in cm)
Cluster finder in MUON arm of ALICE.
Combination of digit and mppad informations.
void PadOverHist(Int_t idir, Int_t ix0, Int_t iy0, AliMUONPad *pad, TH2D *hist1, TH2D *hist2)
const AliMpVSegmentation * fkSegmentation[2]
! new segmentation
Double_t DX() const
Return half dimensions in x (cm)