#include "hades.h"
#include "hevent.h"
#include "hmatrixcategory.h"
#include "hrichanalysispar.h"
#include "hrichdetector.h"
#include "hrichdirclus.h"
#include "hrichgeometrypar.h"
#include "hrichpadclean.h"
#include "hspectrometer.h"
#include "richdef.h"
#include <iomanip>
#include <iostream>
#include <stdlib.h>
using namespace std;
ClassImp(HRichPadClean)
HRichPadClean::HRichPadClean()
{
iCount = 0;
minX = 200;
maxX = 200;
minY = 0;
maxY = 0;
deltaPhi = 0;
fRichClusCat = NULL;
iTempCluster.Set(100);
}
HRichPadClean::~HRichPadClean()
{
}
HRichPadClean::HRichPadClean(const HRichPadClean& source) :TObject(source)
{
iCount = source.iCount;
iTempCluster = source.iTempCluster;
}
HRichPadClean&
HRichPadClean::operator=(const HRichPadClean& source)
{
if (this != &source) {
iCount = source.iCount;
iTempCluster = source.iTempCluster;
}
return *this;
}
Bool_t
HRichPadClean::init()
{
fRichClusCat = gHades->getCurrentEvent()->getCategory(catRichDirClus);
if (NULL == fRichClusCat) {
fRichClusCat = gHades->getSetup()->getDetector("Rich")->buildCategory(catRichDirClus);
if (NULL == fRichClusCat) {
Error("init", "Category catRichDirClus could not be created");
return kFALSE;
} else
gHades->getCurrentEvent()->addCategory(catRichDirClus, fRichClusCat, "Rich");
}
return kTRUE;
}
Int_t
HRichPadClean::Execute(HRichAnalysis *giveMe)
{
if (giveMe->iPadFiredNr > 2) {
Int_t iReducedNr = 0;
HRichAnalysisPar *analParams = giveMe->getAnalysisPar();
Float_t corFac = analParams->fAmpCorrFac[giveMe->GetActiveSector()];
if (analParams->isActiveCleanHighPulse) {
iReducedNr += CleanHighPulse(giveMe, analParams->iCleanHighPulseBorder,
Int_t(analParams->iCleanHighPulseUpperThreshold * corFac + 0.5F));
}
if (analParams->isActiveCleanAlonePad)
iReducedNr += CleanAlonePad(giveMe, analParams->iCleanAlonePadBorder,
Int_t(analParams->iCleanAlonePadLowerThreshold*(0.5F + corFac*0.5F) + 0.5F));
return (iReducedNr);
} else
return giveMe->iPadFiredNr;
}
Int_t
HRichPadClean::CleanHighPulse(HRichAnalysis* showMe,
Int_t border,
Int_t upperThr)
{
if (0 == border) {
Error("CleanAlonePad", "Argument \'border\' in function CleanAlonePad must be larger than 0!");
return -1;
}
#ifdef HRICH_DEBUGMODE
cout << "RICH DEBUG MODE: DeletePulse cleans the following pads: \n";
#endif
const Int_t maxRows = showMe->GetPadsYNr();
const Int_t maxCols = showMe->GetPadsXNr();
Int_t iCountBefore = 0;
Int_t nCleaned = 0;
Int_t offset = 0;
Int_t rightBorder = 0;
HRichDirClus* clus = NULL;
HLocation loc;
Int_t old_row = 0;
Int_t old_col = 0;
iCount = 0;
for (Int_t row = 0; row < maxRows; ++row) {
offset = row * maxCols;
rightBorder = showMe->pRightBorder[row];
for (Int_t col = showMe->pLeftBorder[row]; col <= rightBorder; ++col) {
if (showMe->GetPad(col + offset)->getAmplitude() > upperThr) {
chargeTot = 0;
minX = 200;
maxX = 0;
minY = 200;
maxY = 0;
deltaPhi = 0;
iCountBefore = iCount;
old_row = row;
old_col = col;
DeletePulse(showMe, border, col, row);
if (old_row != row || old_col != col)
Error("CleanHighPulse", "Numbers changed: old = [%d,%d], new = old = [%d,%d]", old_row, old_col, row, col);
if ((iCount - iCountBefore) > 0 && nCleaned < 100) {
iTempCluster[nCleaned++] = iCount - iCountBefore;
clus = NULL;
loc.set(1, 0);
clus = static_cast<HRichDirClus*>(static_cast<HMatrixCategory*>(fRichClusCat)->getNewSlot(loc));
if (NULL == clus)
Error("CleanHighPulse", "Error no slot free in HRichDirClus !!!!!!!!!!! ");
else {
clus = new(clus) HRichDirClus;
clus->setSector(showMe->GetActiveSector());
clus->setX((Int_t)(maxX + minX) / 2);
clus->setY((Int_t)(maxY + minY) / 2);
clus->setXYDim(TMath::Abs(minX - maxX),
TMath::Abs(minY - maxY));
clus->setTotalCharge(chargeTot);
clus->setNrPad(iCount - iCountBefore);
clus->setPhiDiff(calculateDPhi(showMe, minX, minY, maxX, maxY));
Float_t theta = -1;
if (NULL != ((HRichGeometryPar*)showMe->getGeometryPar())->getPadsPar()->
getPad(((UInt_t)(maxX + minX) / 2), ((UInt_t)(maxY + minY) / 2))) {
theta = ((HRichGeometryPar*)showMe->getGeometryPar())->getPadsPar()->
getPad(((UInt_t)(maxX + minX) / 2), ((UInt_t)(maxY + minY) / 2))->getTheta();
}
clus->setTheta(theta);
}
}
}
}
}
showMe->iClusterCleanedNr = nCleaned;
showMe->iClustersCleaned.Set(nCleaned);
for (Int_t i = 0; i < nCleaned; i++)
showMe->iClustersCleaned[i] = iTempCluster[i];
#ifdef HRICH_DEBUGMODE
if (!iCount) cout << "None. \n" << "RICH DEBUG MODE: Total number "
<< "of pads cleaned by CleanHighPulse = 0\n";
else cout << "\nRICH DEBUG MODE: Total number of pads cleaned "
<< "by CleanHighPulse = " << iCount << "\n";
#endif
return iCount;
}
Int_t
HRichPadClean::CleanAlonePad(HRichAnalysis *showMe,
Int_t border,
Int_t lowerThr)
{
const Int_t maxCols = showMe->GetPadsXNr();
const Int_t maxRows = showMe->GetPadsYNr();
Int_t leftBorder;
Int_t rightBorder;
Int_t offset;
HRichPadSignal* pad = NULL;
iCount = 0;
if (0 == border) {
Error("CleanAlonePad", "Argument \'border\' in function CleanAlonePad must be larger than 0!");
return -1;
}
#ifdef HRICH_DEBUGMODE
cout << "RICH DEBUG MODE: CleanAlonePad cleans the following pads: \n";
#endif
for (Int_t row = 0; row < maxRows; ++row) {
leftBorder = showMe->pLeftBorder[row];
rightBorder = showMe->pRightBorder[row];
pad = showMe->GetPad(leftBorder + row * maxCols);
for (Int_t col = leftBorder; col <= rightBorder; ++col) {
if (pad->getAmplitude() > 0) {
for (Int_t k = row - border; k <= row + border; ++k) {
offset = k * maxCols;
for (Int_t l = col - border; l <= col + border; ++l)
if (!(l == col && k == row))
if (!showMe->IsOut(l, k))
if (showMe->GetPad(l + offset)->getAmplitude() > 0)
goto nextPad;
}
if (pad->getAmplitude() < lowerThr) {
pad->setAmplitude(0);
pad->setIsCleanedSingle(kTRUE);
iCount++;
#ifdef HRICH_DEBUGMODE
cout << " (" << colStart + border << "," << rowStart + border << ")... ";
#endif
}
}
nextPad:
++pad;
}
}
#ifdef HRICH_DEBUGMODE
if (0 == iCount) cout << "None. \n";
else cout << "\nRICH DEBUG MODE: Total number of pads cleaned by "
"CleanAlonePad = " << iCount << "\n";
#endif
return iCount;
}
void
HRichPadClean::DeletePulse(HRichAnalysis* showYou,
Int_t border,
Int_t col,
Int_t row)
{
const Int_t maxCols = showYou->GetPadsXNr();
Int_t offset;
chargeTot += showYou->GetPad(col + maxCols * row)->getAmplitude();
#ifdef HRICH_DEBUGMODE
cout << " charge " << showYou->GetPad(col + maxCols * row)->getAmplitude()
<< " chargeTot " << chargeTot << endl;
#endif
showYou->GetPad(col + maxCols * row)->setAmplitude(0);
showYou->GetPad(col + maxCols * row)->setIsCleanedHigh(kTRUE);
#ifdef HRICH_DEBUGMODE
cout << ((HRichGeometryPar*)showYou->getGeometryPar())->getPadsPar()->getPad(col, row)
<< " first pad with the second method" << endl;
cout << " ==================== it is assignment time!========= " << endl;
cout << " minX " << minX << " maxY " << maxY << " col " << col << " minY "
<< minY << " row " << row << " maxY " << maxY << endl;
#endif
minX = minX >= col ? col : minX;
minY = minY >= row ? row : minY;
maxX = maxX <= col ? col : maxX;
maxY = maxY <= row ? row : maxY;
#ifdef HRICH_DEBUGMODE
cout << " the harder you try the dumber you look " << endl;
cout << " minX " << minX << " maxX " << maxX << " col " << col
<< " minY " << minY << " row " << row << " maxY " << maxY << endl;
#endif
iCount++;
#ifdef HRICH_DEBUGMODE
cout << " (" << colStart + border << "," << rowStart + border << ")... ";
#endif
for (Int_t i = row - border; i <= row + border; ++i) {
offset = maxCols * i;
for (Int_t j = col - border; j <= col + border; ++j)
if (!showYou->IsOut(j, i))
if (!(i == row && j == col))
if (showYou->GetPad(j + offset)->getAmplitude() > 0)
DeletePulse(showYou, border, j, i);
}
return;
}
Float_t
HRichPadClean::calculateDPhi(HRichAnalysis *showMe,
Int_t xmin,
Int_t ymin,
Int_t xmax,
Int_t ymax)
{
Float_t phi1 = -1;
Float_t phi2 = -1;
#ifdef HRICH_DEBUGMODE
cout << " xmin " << xmin << " ymin " << ymin << " xmax " << xmax << " ymax " << ymax << endl;
#endif
Int_t maxCols = showMe->GetPadsXNr();
#ifdef HRICH_DEBUGMODE
cout << ((HRichGeometryPar*)showMe->getGeometryPar())->getPadsPar()->getPad(xmin, ymin) << " first pad " << endl;
cout << ((HRichGeometryPar*)showMe->getGeometryPar())->getPadsPar()->getPad(xmin + maxCols * ymin) << " first pad " << endl;
cout << ((HRichGeometryPar*)showMe->getGeometryPar())->getPadsPar()->getPad(xmax + maxCols * ymax) << " second pad " << endl;
cout << showMe->GetPad(xmin + maxCols * ymin) << " first pad, second method " << endl;
#endif
if (showMe->GetPad(xmin + maxCols * ymin))
phi1 = ((HRichGeometryPar*)showMe->getGeometryPar())->getPadsPar()->getPad(xmin + maxCols * ymin)->getPhi(showMe->GetActiveSector());
if (showMe->GetPad(xmax + maxCols * ymax))
phi2 = ((HRichGeometryPar*)showMe->getGeometryPar())->getPadsPar()->getPad(xmax + maxCols * ymax)->getPhi(showMe->GetActiveSector());
#ifdef HRICH_DEBUGMODE
cout << " delta Phi " << TMath::Abs(phi1 - phi2) << endl;
#endif
if (-1 == phi1 && -1 == phi2)
return -1;
return TMath::Abs(phi1 - phi2);
}