#include "hrichchernovringfitter.h"
#include "hrichphotonhit.h"
#include "hrichphotonhitheader.h"
#include "hruntimedb.h"
#include "hevent.h"
#include "hspectrometer.h"
#include "hdetector.h"
#include "hrichdetector.h"
#include "hcategory.h"
#include "hiterator.h"
#include "hmatrixcatiter.h"
#include "hlocation.h"
#include "hdebug.h"
#include "hades.h"
#include "richdef.h"
#include "hrichhit.h"
#include "hrichhitfit.h"
#include "hrichcal.h"
#include "hrichpad.h"
#include "hrichgeometrypar.h"
#include "hlinearcategory.h"
#include "TMath.h"
#include <cmath>
ClassImp(HRichChernovRingFitter)
HRichChernovRingFitter::HRichChernovRingFitter(const Text_t *name,const Text_t *title,Bool_t kPhoton) :
HReconstructor(name,title)
{
kPhotonFinder = kPhoton;
pIterCal=NULL;
pIterHit=NULL;
pIterPhotonHit=NULL;
fs = 6;
arraysize = (2*fs+1)*(2*fs+1);
evtcounter=0;
pCalCat=NULL;
pHitCat=NULL;
pHitFitCat=NULL;
pPhotonHitCat=NULL;
pGeomPar=NULL;
}
HRichChernovRingFitter::~HRichChernovRingFitter(void)
{
if (pIterCal) delete pIterCal;
if (pIterHit) delete pIterHit;
if (pIterPhotonHit) delete pIterPhotonHit;
}
Bool_t HRichChernovRingFitter::init()
{
HRichDetector *pRichDet = (HRichDetector*)gHades->getSetup()
->getDetector("Rich");
HRuntimeDb* rtdb=gHades->getRuntimeDb();
HRichGeometryPar *pGeomPar =
(HRichGeometryPar*)rtdb->getContainer("RichGeometryParameters");
setGeometryPar(pGeomPar);
if (getGeometryPar()==NULL)
{
cout<<"ERROR in init: no pointer to geom container"
<<endl;
}
pCalCat=gHades->getCurrentEvent()->getCategory(catRichCal);
if (!pCalCat) {
cout<<"no valid CAL category on file"<<endl;
return kFALSE;
}
pIterCal = (HIterator*)getCalCat()->MakeIterator("native");
pHitCat=gHades->getCurrentEvent()->getCategory(catRichHit);
if (!pHitCat)
{
cout<<"no valid HIT category on file"<<endl;
return kFALSE;
}
pIterHit = (HIterator*)getHitCat()->MakeIterator();
pHitFitCat=gHades->getCurrentEvent()->getCategory(catRichHitFit);
if (!pHitFitCat)
{
pHitFitCat=pRichDet->buildCategory(catRichHitFit);
if (!pHitFitCat) return kFALSE;
else gHades->getCurrentEvent()
->addCategory(catRichHitFit, pHitFitCat, "Rich");
}
if (kPhotonFinder){
pPhotonHitHeaderCat=gHades->getCurrentEvent()
->getCategory(catRichPhotonHitHeader);
if (!pPhotonHitHeaderCat) {
pPhotonHitHeaderCat=pRichDet
->buildCategory(catRichPhotonHitHeader);
if (!pPhotonHitHeaderCat) return kFALSE;
else gHades->getCurrentEvent()
->addCategory(catRichPhotonHitHeader,
pPhotonHitHeaderCat, "Rich");
}
pIterPhotonHitHeader = (HIterator*)getPhotonHitHeaderCat()
->MakeIterator("native");
pPhotonHitCat=gHades->getCurrentEvent()->getCategory(catRichPhotonHit);
if (!pPhotonHitCat) {
pPhotonHitCat=pRichDet->buildCategory(catRichPhotonHit);
if (!pPhotonHitCat) return kFALSE;
else gHades->getCurrentEvent()
->addCategory(catRichPhotonHit, pPhotonHitCat, "Rich");
}
pIterPhotonHit = (HIterator*)getPhotonHitCat()->MakeIterator("native");
}
return kTRUE;
}
Bool_t HRichChernovRingFitter::finalize()
{
return kTRUE;
}
Int_t HRichChernovRingFitter::execute()
{
if (kPhotonFinder){
if(!fitFoundPhotons()) return kFALSE;
}else{
if(!fitFiredPads()) return kFALSE;
}
evtcounter++;
return 0;
}
void HRichChernovRingFitter::switchXtoPhi()
{
dFittedCenterPhi=dFittedCenterX;
dFittedCenterTheta=dFittedCenterY;
dFittedCenterX=-1;
dFittedCenterY=-1;
}
Bool_t HRichChernovRingFitter::fitFiredPads2()
{
HRichHit *pHit;
pIterHit->Reset();
while((pHit = (HRichHit *)pIterHit->Next()))
{
Double_t *dX = new Double_t[arraysize];
Double_t *dY = new Double_t[arraysize];
Double_t *dCh = new Double_t[arraysize];
for (Int_t ii=0;ii<arraysize;ii++) dX[ii]=dY[ii]=dCh[ii]=-1.;
Int_t nPadCounter = 0;
Int_t nHitSector = pHit->getSector();
Int_t nHitX = pHit->iRingX;
Int_t nHitY = pHit->iRingY;
Int_t startcol=0;
if (nHitX-fs>=0) startcol = nHitX-fs;
else startcol = 0;
Int_t startrow=0;
if (nHitY-fs>=0) startrow = nHitY-fs;
else startrow = 0;
Int_t endcol=0;
if (nHitX+fs<=92) endcol = nHitX+fs;
else endcol = 92;
Int_t endrow=0;
if (nHitY+fs<=92) endrow = nHitY+fs;
else endrow = 92;
for (Int_t i=startcol;i<=endcol;i++)
{
for (Int_t j=startrow;j<=endrow;j++)
{
HLocation loc;
loc.set(3,0,0,0);
loc.setOffset(i);
loc.setIndex(1,j);
loc.setIndex(0,nHitSector);
HRichCal *c = (HRichCal*)((HMatrixCategory*)getCalCat())->getObject(loc);
if (c)
{
dX[nPadCounter] = i;
dY[nPadCounter] = j;
dCh[nPadCounter] = c->getCharge();
nPadCounter++;
}
}
}
Double_t *dnewX = compress(dX,nPadCounter);
Double_t *dnewY = compress(dY,nPadCounter);
Double_t *dnewCh = compress(dCh,nPadCounter);
TArrayD x(nPadCounter,dnewX);
TArrayD y(nPadCounter,dnewY);
TArrayD c(nPadCounter,dnewCh);
delete [] dX;
delete [] dY;
delete [] dCh;
delete [] dnewX;
delete [] dnewY;
delete [] dnewCh;
clearFitParams();
if (nPadCounter>3) {if (fit(x,y)) calcThetaAndPhi(pHit);}
}
return kTRUE;
}
Bool_t HRichChernovRingFitter::fitFiredPads()
{
HRichHit *pHit;
pIterHit->Reset();
while((pHit = (HRichHit *)pIterHit->Next()))
{
Double_t *dX = new Double_t[arraysize];
Double_t *dY = new Double_t[arraysize];
Double_t *dCh = new Double_t[arraysize];
for (Int_t i=0;i<arraysize;i++) dX[i]=dY[i]=dCh[i]=-1.;;
Int_t nHitSector = pHit->getSector();
Int_t nHitX = pHit->iRingX;
Int_t nHitY = pHit->iRingY;
HRichCal* pCal;
pIterCal->Reset();
Int_t nPadCounter=0;
while((pCal = (HRichCal *)pIterCal->Next()))
{
if (nHitSector == pCal->getSector())
{
Int_t nCalRow = pCal->getRow();
Int_t nCalCol = pCal->getCol();
Float_t nCalChrg = pCal->getCharge();
if(TMath::Abs(nCalRow-nHitY) <= fs &&
TMath::Abs(nCalCol-nHitX) <= fs)
{
dX[nPadCounter] = nCalCol;
dY[nPadCounter] = nCalRow;
dCh[nPadCounter] = nCalChrg;
nPadCounter++;
}
}
}
Double_t *dnewX = compress(dX,nPadCounter);
Double_t *dnewY = compress(dY,nPadCounter);
Double_t *dnewCh = compress(dCh,nPadCounter);
TArrayD x(nPadCounter,dnewX);
TArrayD y(nPadCounter,dnewY);
TArrayD c(nPadCounter,dnewCh);
if (dX) delete [] dX;
if (dY) delete [] dY;
if (dCh) delete [] dCh;
if (dnewX) delete [] dnewX;
if (dnewY) delete [] dnewY;
if (dnewCh) delete [] dnewCh;
clearFitParams();
if (nPadCounter>3 && fit(x,y))
{
if ((dFittedCenterX-nHitX) < 2. &&
(dFittedCenterY-nHitY) < 2. )
{
calcThetaAndPhi(pHit);
}
else
{
unvalidFitParams();
}
}
else
{
unvalidFitParams();
}
Int_t ind = getHitCat()->getIndex(pHit);
storeFitinHRichHitFit(pHit->getSector(),nPadCounter,ind);
}
return kTRUE;
}
void HRichChernovRingFitter::storeFitinHRichHitFit(Int_t s, Int_t n,Int_t i)
{
HLocation loc;
loc.set(1,s);
HRichHitFit *hitfit = (HRichHitFit*)((HLinearCategory*)getHitFitCat())
->getNewSlot(loc);
if (hitfit!=NULL)
{
hitfit->Reset();
hitfit = new(hitfit) HRichHitFit;
hitfit->setHitIndex(i);
hitfit->setSector(s);
hitfit->setNbCoords(n);
hitfit->setFitRadius(getFitRadius());
hitfit->setFitCenterX(getFitCenterX());
hitfit->setFitCenterY(getFitCenterY());
hitfit->setFitVar(getFitVar());
hitfit->setFitCenterTheta(getFitCenterTheta());
hitfit->setFitCenterPhi(getFitCenterPhi());
}
}
void HRichChernovRingFitter::clearFitParams()
{
dFittedRadius = 0.;
dFittedCenterX = 0.;
dFittedCenterY = 0.;
dFitVariance = 0.;
dFittedCenterTheta = 0.;
dFittedCenterPhi = 0.;
}
void HRichChernovRingFitter::unvalidFitParams()
{
dFittedRadius = -1.;
dFittedCenterX = -1.;
dFittedCenterY = -1.;
dFitVariance = -1.;
dFittedCenterTheta = -1.;
dFittedCenterPhi = -1.;
}
Double_t* HRichChernovRingFitter::compress(Double_t* arr,Int_t nPadCounter)
{
Int_t nNonZeroElementCounter=0;
Double_t* arr2=0;
for (Int_t i=0;i<arraysize;i++)
{
if (arr[i] != -1) nNonZeroElementCounter++;
}
if (nNonZeroElementCounter==nPadCounter)
{
arr2 = new Double_t[nNonZeroElementCounter];
for (Int_t j=0;j<nNonZeroElementCounter;j++)
{
arr2[j]=arr[j];
}
}
else
{
cout<<"cnt eles : "<<nNonZeroElementCounter<<" giv eles: "<<nPadCounter<<endl;
Error("compress","inconsistency");
}
return arr2;
}
Bool_t HRichChernovRingFitter::fit(TArrayD &mXc, TArrayD &mYc)
{
Int_t i;
Double_t xx, yy, xx2, yy2;
Double_t f, g, h, p, q, t, g0, g02, a, b, c, d;
Double_t xroot, ff, fp, xd, yd, g1;
Double_t dx, dy, dradius2, xnom;
Double_t xgravity = 0.0;
Double_t ygravity = 0.0;
Double_t x2 = 0.0;
Double_t y2 = 0.0;
Double_t xy = 0.0;
Double_t xx2y2 = 0.0;
Double_t yx2y2 = 0.0;
Double_t x2y22 = 0.0;
Double_t radius2 = 0.0;
mRC = 0;
Int_t npoints = mXc.GetSize();
if (npoints <= 3) {
mRC = 1;
return kFALSE;
}
xgravity = mXc.GetSum() / npoints;
ygravity = mYc.GetSum() / npoints;
for (i=0; i<npoints; i++) {
xx = mXc[i]-xgravity;
yy = mYc[i]-ygravity;
xx2 = xx*xx;
yy2 = yy*yy;
x2 += xx2;
y2 += yy2;
xy += xx*yy;
xx2y2 += xx*(xx2+yy2);
yx2y2 += yy*(xx2+yy2);
x2y22 += (xx2+yy2)*(xx2+yy2);
}
if (xy == 0.) {
mRC = 2;
return kFALSE;
}
f = (3.*x2+y2)/npoints;
g = (x2+3.*y2)/npoints;
h = 2*xy/npoints;
p = xx2y2/npoints;
q = yx2y2/npoints;
t = x2y22/npoints;
g0 = (x2+y2)/npoints;
g02 = g0*g0;
a = -4.0;
b = (f*g-t-h*h)/g02;
c = (t*(f+g)-2.*(p*p+q*q))/(g02*g0);
d = (t*(h*h-f*g)+2.*(p*p*g+q*q*f)-4.*p*q*h)/(g02*g02);
xroot = 1.0;
for (i=0; i<5; i++) {
ff = (((xroot+a)*xroot+b)*xroot+c)*xroot+d;
fp = ((4.*xroot+3.*a)*xroot+2.*b)*xroot+c;
xroot -= ff/fp;
}
g1 = xroot*g0;
xnom = (g-g1)*(f-g1)-h*h;
if (xnom == 0.) {
mRC = 3;
return kFALSE;
}
yd = (q*(f-g1)-h*p)/xnom;
xnom = f-g1;
if (xnom == 0.) {
mRC = 4;
return kFALSE;
}
xd = (p-h*yd )/xnom;
radius2 = xd*xd+yd*yd+g1;
dFittedCenterX = xd+xgravity;
dFittedCenterY = yd+ygravity;
for (i=0; i<npoints; i++) {
dx = mXc[i]-(dFittedCenterX);
dy = mYc[i]-(dFittedCenterY);
dradius2 = dx*dx+dy*dy;
dFitVariance += dradius2+radius2-2.*sqrt(dradius2*radius2);
}
dFitVariance /= npoints-3.0;
dFittedRadius = sqrt(radius2);
Bool_t kRC = kTRUE;
return kRC;
}
void HRichChernovRingFitter::dumpFitParameters(Int_t sec,Int_t x,Int_t y,Float_t r)
{
HRichPadTab *pPadsPar = ((HRichGeometryPar*)getGeometryPar())->getPadsPar();
if (pPadsPar)
{
HRichPad *pPad0 = pPadsPar->getPad(x,y);
if (pPad0)
{
Float_t theta = pPad0->getTheta();
Float_t phi = pPad0->getPhi(sec);
cout<<"EVENT NUMBER :"<<evtcounter<<endl;
cout<<"Rich Hit> x:"<<x<<" y:"<<y<<" rad:"<<r
<<" theta:"<<theta<<" phi:"<<phi<<" sec:"<<sec<<endl;
cout<<" Fit> x:"<<dFittedCenterX<<" y:"<<dFittedCenterY
<<" rad:"<<dFittedRadius<<" theta:"<<dFittedCenterTheta
<<" phi:"<<dFittedCenterPhi
<<" var:"<<dFitVariance
<<endl;
} else cout<<"ERROR in HRichChernovRingFitter::dumpFitParameters"<<
" : no pointer to pad"<<endl;
} else cout<<"ERROR in HRichChernovRingFitter::dumpFitParameters"<<
" : no pointer to RTDB"<<endl;
}
void HRichChernovRingFitter::calcThetaAndPhi(HRichHit *pHit)
{
HRichPadTab *pPadsPar = ((HRichGeometryPar*)getGeometryPar())->getPadsPar();
Int_t nPadX0 = (Int_t) TMath::Floor(dFittedCenterX);
Int_t nPadY0 = (Int_t) TMath::Floor(dFittedCenterY);
if (pPadsPar)
{
Float_t fThetaOfPadCenter0 = 0;
Float_t fPhiOfPadCenter0 = 0;
HRichPad *pPad0 = pPadsPar->getPad(nPadX0,nPadY0);
if (pPad0)
{
fThetaOfPadCenter0 = pPad0->getTheta();
fPhiOfPadCenter0 = pPad0->getPhi(pHit->getSector());
} else {
return;
}
Float_t fThetaOfPadCenter1 = 0;
HRichPad *pPad1 = pPadsPar->getPad(nPadX0,nPadY0-1);
if (pPad1)
{
fThetaOfPadCenter1 = pPad1->getTheta();
} else {
return;
}
Float_t fPhiOfPadCenter2 = 0;
HRichPad *pPad2 = pPadsPar->getPad(nPadX0-1,nPadY0);
if (pPad2)
{
fPhiOfPadCenter2 = pPad2->getPhi(pHit->getSector());
} else {
return;
}
Float_t fPhiOfPadCenter3 = 0;
HRichPad *pPad3 = pPadsPar->getPad(nPadX0+1,nPadY0);
if (pPad3)
{
fPhiOfPadCenter3 = pPad3->getPhi(pHit->getSector());
} else {
return;
}
Float_t fThetaOfPadCenter4 = 0;
HRichPad *pPad4 = pPadsPar->getPad(nPadX0,nPadY0+1);
if (pPad4)
{
fThetaOfPadCenter4 = pPad4->getTheta();
} else {
return;
}
if (dFittedCenterX-nPadX0 == 0.5) dFittedCenterPhi=fPhiOfPadCenter0;
if (dFittedCenterX-nPadX0 > 0.5)
{
dFittedCenterPhi = (dFittedCenterX-0.5-nPadX0)*
(fPhiOfPadCenter3-fPhiOfPadCenter0) + fPhiOfPadCenter0;
}
if (dFittedCenterX-nPadX0 < 0.5)
{
dFittedCenterPhi = (dFittedCenterX+0.5-nPadX0)*
(fPhiOfPadCenter0-fPhiOfPadCenter2) + fPhiOfPadCenter2;
}
if (dFittedCenterY-nPadY0 == 0.5) dFittedCenterTheta=fThetaOfPadCenter0;
if (dFittedCenterY-nPadY0 > 0.5)
{
dFittedCenterTheta = (dFittedCenterY-0.5-nPadY0)*
(fThetaOfPadCenter4-fThetaOfPadCenter0) + fThetaOfPadCenter0;
}
if (dFittedCenterY-nPadY0 < 0.5)
{
dFittedCenterTheta = (dFittedCenterY+0.5-nPadY0)*
(fThetaOfPadCenter0-fThetaOfPadCenter1) + fThetaOfPadCenter1;
}
}
else cout<<"ERROR: no pointer to RTDB"<<endl;
}
Last change: Sat May 22 13:08:18 2010
Last generated: 2010-05-22 13:08
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.