// $Id: hrichchernovringfitter.cc,v 1.3 2002-09-25 16:19:52 eberl Exp $ // Last update by Thomas Eberl: 02/09/25 17:29:44 // // Class HRichChernovRingFitter // shamelessly adapted from: Thomas Ullrich, Dec 1999, STAR Collaboration // *************************************************************************** // * // * Description: // * // * Fast fitting routine using an iterative linear regression // * method (ILRM). Reference: N.I.Chernov, G.A.Ososkov, Computer // * Physics Communication 33 (1984) 329-333. // * // *************************************************************************** #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" ClassImp(HRichChernovRingFitter) HRichChernovRingFitter::HRichChernovRingFitter(Text_t *name,Text_t *title,Bool_t kPhoton) : HReconstructor(name,title) { kPhotonFinder = kPhoton; pIterCal=NULL; pIterHit=NULL; pIterPhotonHit=NULL; fs = 6; //size of square to be cut out around hit point 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; //if (mX) delete mX; //if (mY) delete mY; //if (mCh) delete mCh; } Bool_t HRichChernovRingFitter::init() { //cout<<" in HRichChernovRingFitter init"<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" <getCurrentEvent()->getCategory(catRichCal); if (!pCalCat) { cout<<"no valid CAL category on file"<buildCategory(catRichCal); // if (!pCalCat) return kFALSE; // else gHades->getCurrentEvent() // ->addCategory(catRichCal, pCalCat, "Rich"); // } pIterCal = (HIterator*)getCalCat()->MakeIterator("native"); cout<<"this was cal"<getCurrentEvent()->getCategory(catRichHit); if (!pHitCat) { pHitCat=pRichDet->buildCategory(catRichHit); if (!pHitCat) return kFALSE; else gHades->getCurrentEvent() ->addCategory(catRichHit, pHitCat, "Rich"); } //pIterHit = (HMatrixCatIter*)getHitCat()->MakeIterator(); pIterHit = (HIterator*)getHitCat()->MakeIterator(); cout<<"this was hit"<getCurrentEvent()->getCategory(catRichHitFit); if (!pHitFitCat) { pHitFitCat=pRichDet->buildCategory(catRichHitFit); if (!pHitFitCat) return kFALSE; else gHades->getCurrentEvent() ->addCategory(catRichHitFit, pHitFitCat, "Rich"); } cout<<"this was fit"<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"); // RICH PHOTON HIT container 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"); } // init helper arrays for temp storage of cut out pads //cout<<"end of init()"<Reset(); Double_t *dX = new Double_t[arraysize]; Double_t *dY = new Double_t[arraysize]; Double_t *dCh = new Double_t[arraysize]; while( (pPhotonHitHeader = (HRichPhotonHitHeader *) pIterPhotonHitHeader->Next()) ) { //cout<<"in photon hit header loop"<getRingX(); Int_t nHeaderRingY = pPhotonHitHeader->getRingY(); Float_t fHeaderRingPhi = pPhotonHitHeader->getRingPhi(); Float_t fHeaderRingTheta = pPhotonHitHeader->getRingTheta(); Int_t nHeaderSector = pPhotonHitHeader->getSector(); Int_t nHeaderNbPhot = pPhotonHitHeader->getNbPhotons(); //cout<<"ring X: "<Reset(); Int_t nHitCounter=0; while( (pPhotonHit = (HRichPhotonHit *)pIterPhotonHit->Next()) ) { //cout<<"in photon hit header loop"<getRingX(); Int_t nHitRingY = pPhotonHit->getRingY(); Int_t nHitSector = pPhotonHit->getSector(); if (nHitSector==nHeaderSector && nHitRingX ==nHeaderRingX && nHitRingY ==nHeaderRingY) { dX[nHitCounter]=pPhotonHit->getPhi(); dY[nHitCounter]=pPhotonHit->getTheta(); dCh[nHitCounter]=pPhotonHit->getCharge(); nHitCounter++; } } //end while photon hits if (nHitCounter!=nHeaderNbPhot) cout<<"Error:photon nb mismatch"<Set(nHitCounter,compress(dX,nHitCounter)); //if (!mY) mY = new TArrayD(nHitCounter,compress(dY,nHitCounter)); mY->Set(nHitCounter,compress(dY,nHitCounter)); //if (!mCh) mCh = new TArrayD(nHitCounter,compress(dCh,nHitCounter)); mCh->Set(nHitCounter,compress(dCh,nHitCounter)); clearFitParams(); // =================================================================== if (fit()) // <------ here the actual fitting algorithm is called !!! // =================================================================== {//check if fit is reasonable if (! ((dFittedCenterX-fHeaderRingPhi) < 2. && (dFittedCenterY-fHeaderRingTheta) < 2. ) ) unvalidFitParams(); }else{unvalidFitParams();} switchXtoPhi(); Int_t ind=-1; storeFitinHRichHitFit(nHeaderSector,nHitCounter,ind); //dumpFitParameters(nHeaderSector,nHeaderRingX,nHeaderRingY,-1.); } // end while photon hit header if (dX) delete [] dX; if (dY) delete [] dY; if (dCh) delete [] dCh; return kTRUE; } void HRichChernovRingFitter::switchXtoPhi() { dFittedCenterPhi=dFittedCenterX; dFittedCenterTheta=dFittedCenterY; dFittedCenterX=-1; dFittedCenterY=-1; } Bool_t HRichChernovRingFitter::fitFiredPads() { // What to do with hits on the padplane border ? // They are not fitted correctly ! HRichHit *pHit; pIterHit->Reset(); Double_t *dX = new Double_t[arraysize]; Double_t *dY = new Double_t[arraysize]; Double_t *dCh = new Double_t[arraysize]; // loop over each ring in event while((pHit = (HRichHit *)pIterHit->Next())) { Int_t nHitSector = pHit->getSector(); Int_t nHitX = pHit->iRingX; Int_t nHitY = pHit->iRingY; HRichCal* pCal; for (Int_t i=0;iReset(); //cout<Next())) { //pCal->dumpToStdout(); if (nHitSector == pCal->getSector()) { Int_t nCalRow = pCal->getRow(); Int_t nCalCol = pCal->getCol(); Float_t nCalChrg = pCal->getCharge(); //pCal->dumpToStdout(); if(TMath::Abs(nCalRow-nHitY) <= fs && TMath::Abs(nCalCol-nHitX) <= fs) { dX[nPadCounter] = nCalCol; dY[nPadCounter] = nCalRow; dCh[nPadCounter] = nCalChrg; //pCal->dumpToStdout(); nPadCounter++; } } } // endwhile cal container //if (!mX && dblx) mX = new TArrayD(nPadCounter,dblx); mX->Set(nPadCounter,compress(dX,nPadCounter)); //if (!mY) mY = new TArrayD(nPadCounter,compress(dY,nPadCounter)); mY->Set(nPadCounter,compress(dY,nPadCounter)); //if (!mCh) mCh = new TArrayD(nPadCounter,compress(dCh,nPadCounter)); mCh->Set(nPadCounter,compress(dCh,nPadCounter)); clearFitParams(); // =================================================================== if (fit()) // <------ here the actual fitting algorithm is called !!! // =================================================================== {//check if fit is reasonable if ((dFittedCenterX-nHitX) < 2. && (dFittedCenterY-nHitY) < 2. ) { calcThetaAndPhi(pHit); } else { //cout<<"ERROR: Fitted center too far off !"<fRingRadius); unvalidFitParams(); } } else { //cout<<"ERROR: Fit unsuccessful !"<fRingRadius); unvalidFitParams(); } Int_t ind = getHitCat()->getIndex(pHit); storeFitinHRichHitFit(pHit->getSector(),nPadCounter,ind); //dumpFitParameters(nHitSector,nHitX,nHitY,pHit->fRingRadius); } //endwhile hit container if (dX) delete [] dX; if (dY) delete [] dY; if (dCh) delete [] dCh; return kTRUE; } void HRichChernovRingFitter::storeFitinHRichHitFit(Int_t s, Int_t n,Int_t i) { //cout<<"in storeFitinHRichHitFit()"<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::storeFitParamsInHRichHit(HRichHit *hit) // { // //cout<<"in storeFitParamsInRichHit()"<setFitRadius(getFitRadius()); // hit->setFitCenterX(getFitCenterX()); // hit->setFitCenterY(getFitCenterY()); // hit->setFitVar(getFitVar()); // hit->setFitCenterTheta(getFitCenterTheta()); // hit->setFitCenterPhi(getFitCenterPhi()); // } void HRichChernovRingFitter::clearFitParams() { //cout<<"in clearFitParams()"<GetSize(); if (npoints <= 3) { mRC = 1; cout<<"Error: less than 4 points for fit !!"<GetSum() / npoints; ygravity = mY->GetSum() / npoints; for (i=0; igetPadsPar(); if (pPadsPar) { HRichPad *pPad0 = pPadsPar->getPad(x,y); if (pPad0) { Float_t theta = pPad0->getTheta(); Float_t phi = pPad0->getPhi(sec); cout<<"EVENT NUMBER :"< x:"< x:"<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 { cout<<"ERROR: no pointer to pad 0"<getSector(),pHit->iRingX,pHit->iRingY, pHit->fRingRadius); cout<<" PadX: "<getPad(nPadX0,nPadY0-1); if (pPad1) { fThetaOfPadCenter1 = pPad1->getTheta(); //fPhiOfPadCenter1 = pPad1->getPhi(sector);//for later use } else { cout<<"ERROR: no pointer to pad 1"<getSector(),pHit->iRingX,pHit->iRingY, pHit->fRingRadius); cout<<" PadX: "<getPad(nPadX0-1,nPadY0); if (pPad2) { //fThetaOfPadCenter2 = pPad2->getTheta();//for later use fPhiOfPadCenter2 = pPad2->getPhi(pHit->getSector()); } else { cout<<"ERROR: no pointer to pad 2"<getSector(),pHit->iRingX,pHit->iRingY, pHit->fRingRadius); cout<<" PadX: "<getPad(nPadX0+1,nPadY0); if (pPad3) { // fThetaOfPadCenter3 = pPad3->getTheta();//for later use fPhiOfPadCenter3 = pPad3->getPhi(pHit->getSector()); } else { cout<<"ERROR: no pointer to pad 3"<getSector(),pHit->iRingX,pHit->iRingY, pHit->fRingRadius); cout<<" PadX: "<getPad(nPadX0,nPadY0+1); if (pPad4) { fThetaOfPadCenter4 = pPad4->getTheta(); //fPhiOfPadCenter4 = pPad4->getPhi(sector);//for later use } else { cout<<"ERROR: no pointer to pad 4"<getSector(),pHit->iRingX,pHit->iRingY, pHit->fRingRadius); cout<<" PadX: "< 0.5) { dFittedCenterPhi = (dFittedCenterX-0.5-nPadX0)* (fPhiOfPadCenter3-fPhiOfPadCenter0) + fPhiOfPadCenter0; } if (dFittedCenterX-nPadX0 < 0.5) { dFittedCenterPhi = (dFittedCenterX+0.5-nPadX0)* (fPhiOfPadCenter0-fPhiOfPadCenter2) + fPhiOfPadCenter2; } // theta interpolation //cout<<"theta interpolation"< 0.5) { dFittedCenterTheta = (dFittedCenterY-0.5-nPadY0)* (fThetaOfPadCenter4-fThetaOfPadCenter0) + fThetaOfPadCenter0; } if (dFittedCenterY-nPadY0 < 0.5) { dFittedCenterTheta = (dFittedCenterY+0.5-nPadY0)* (fThetaOfPadCenter0-fThetaOfPadCenter1) + fThetaOfPadCenter1; } // FIXME: if e.g. theta of 3 and 0 are not equal, one has to calc // the difference and add to dFittedCenterTheta according to the phi !! // but this should be a very small effect } else cout<<"ERROR: no pointer to RTDB"<