// $Id: hrichphotonfinder.cc,v 1.9 2009-09-09 14:11:39 jurkovic Exp $ // Last update by Thomas Eberl: 02/09/25 17:43:51 // //********************************************************** // this class is meant to identify photon hit locations on // the padplane //********************************************************** #include "hrichphotonfinder.h" #include "hrichphotonhit.h" #include "hrichphotonhitheader.h" #include "hruntimedb.h" #include "hevent.h" #include "hspectrometer.h" #include "hdetector.h" #include "hrichdetector.h" #include "hrichgeometrypar.h" #include "hrichcalpar.h" #include "hrichcalparcell.h" #include "hrichhit.h" #include "hrichcal.h" #include "hcategory.h" #include "hiterator.h" #include "hlinearcategory.h" #include "hmatrixcatiter.h" #include "hlocation.h" #include "hdebug.h" #include "hades.h" #include "richdef.h" #include "TMath.h" ClassImp(HRichPhotonFinder) HRichPhotonFinder::HRichPhotonFinder(const Text_t *name,const Text_t *title) : HReconstructor(name,title) { pIterCal=NULL; pIterHit=NULL; // pIterPhotonHit=NULL; fs = 6; //size of square to be cut out around hit point evtcounter=0; pCalCat=NULL; pHitCat=NULL; pPhotonHitCat=NULL; pGeomPar=NULL; } HRichPhotonFinder::~HRichPhotonFinder(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; // if (dX) delete dX; // if (dY) delete dY; // if (dCh) delete dCh; } Bool_t HRichPhotonFinder::init() { HRichDetector *pRichDet = (HRichDetector*)gHades->getSetup() ->getDetector("Rich"); HRuntimeDb* rtdb=gHades->getRuntimeDb(); // GEOMETRY PARAMETER CONTAINER HRichGeometryPar *pGeomPar = (HRichGeometryPar*)rtdb->getContainer("RichGeometryParameters"); // if (!pGeomPar) { // pGeomPar = new HRichGeometryPar; // rtdb->addContainer(pGeomPar); // } setGeometryPar(pGeomPar); if (!getGeometryPar()) { cout<<"ERROR in init: no pointer to geom container" <getCurrentEvent()->getCategory(catRichCal); if (!pCalCat) { pCalCat=pRichDet->buildCategory(catRichCal); if (!pCalCat) return kFALSE; else gHades->getCurrentEvent() ->addCategory(catRichCal, pCalCat, "Rich"); } pIterCal = (HMatrixCatIter*)getCalCat()->MakeIterator(); // RICH HIT container pHitCat=gHades->getCurrentEvent()->getCategory(catRichHit); if (!pHitCat) { pHitCat=pRichDet->buildCategory(catRichHit); if (!pHitCat) return kFALSE; else gHades->getCurrentEvent() ->addCategory(catRichHit, pHitCat, "Rich"); } pIterHit = (HIterator*)getHitCat()->MakeIterator(); // 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"); } // RICH PHOTON HIT HEADER container pPhotonHitHeaderCat=gHades->getCurrentEvent() ->getCategory(catRichPhotonHitHeader); if (!pPhotonHitHeaderCat) { pPhotonHitHeaderCat=pRichDet->buildCategory(catRichPhotonHitHeader); if (!pPhotonHitHeaderCat) return kFALSE; else gHades->getCurrentEvent() ->addCategory(catRichPhotonHitHeader, pPhotonHitHeaderCat , "Rich"); } //cout<<"end of init()"<getObject(loc); cout<<"SEC: "<getOffset()<<" SIGMA : "<< calparcell->getSigma()<<" SLOPE : "<getSlope()<< endl; } void HRichPhotonFinder::initCalPar() { HRuntimeDb* rtdb=gHades->getRuntimeDb(); pCalPar = rtdb->getContainer("RichCalPar"); if (!pCalPar) { pCalPar= new HRichCalPar; pCalPar->SetName("RichCalPar"); if (pCalPar) { rtdb->addContainer(pCalPar); } } } Bool_t HRichPhotonFinder::finalize() { return kTRUE; } Int_t HRichPhotonFinder::execute() { //cout<<"in execute()"<Reset(); // an area of (2*fs+1)^2 is cut around the ring center Int_t arraysize = (2*fs+1)*(2*fs+1); Int_t *nX = new Int_t[arraysize]; Int_t *nY = new Int_t[arraysize]; Float_t *fCh = new Float_t[arraysize]; Float_t *fSigCh = new Float_t[arraysize]; // loop over each ring in event while((pHit = (HRichHit *)pIterHit->Next())) { //cout<getSector(); Int_t nHitX = pHit->iRingX; Int_t nHitY = pHit->iRingY; HRichCal* pCal; for (Int_t i=0;iReset(); Int_t nPadCounter=0; // loop over fired pads in fs*fs sized square around hit // and store them for loc max search while((pCal = (HRichCal *)pIterCal->Next())) { // HLocation calLoc = pIterCal->getLocation(); // this method returns an ill HLocation, why ?? if (pCal && 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) { // pads on a square of size fs*fs around // the hit point are stored // the charge is stored // and the charge reduced by the 3 sigma // threshold in the frontends is stored // these charges are used for calcImpactByGravity HLocation cloc; cloc.set(3,0,0,0); cloc.setOffset(nCalCol); cloc.setIndex(1,nCalRow); cloc.setIndex(0,nHitSector); nX[nPadCounter] = nCalCol; nY[nPadCounter] = nCalRow; fCh[nPadCounter] = pCal->getCharge(); // printCalParCell(cloc); fSigCh[nPadCounter] = pCal->getCharge() - 3*(((HRichCalParCell*)((HRichCalPar*)getCalPar())->getObject(cloc))->getSigma()); if (fSigCh[nPadCounter]<0.) fSigCh[nPadCounter]=0.; //cout<iRingX; Int_t yr = pHit->iRingY; Float_t phir = pHit->getPhi(); Float_t thetar = pHit->getTheta(); Int_t sec = pHit->getSector(); // cout<<"Evt: "<getNewSlot(loc); if(photon) { photon = new (photon) HRichPhotonHit; photon->setX(fPhotonParams[0]); photon->setY(fPhotonParams[1]); photon->setCharge(fPhotonParams[2]); photon->setSector(sec); photon->setRingX(xr); photon->setRingY(yr); setThetaPhi(photon); nPhotonCounter++; } }//endif isPhoton else {} }//endif isLocalMaxOfFive else {} }//endif isLocalMaxOnBorder else {} } //end loop over pads //cout<<"Evt: "<= 3) //otherwise it makes no sense trying to fit later { HLocation loc; loc.set(1,sec); HRichPhotonHitHeader *phhitheader = (HRichPhotonHitHeader*) ((HLinearCategory*)getPhotonHitHeaderCat()) ->getNewSlot(loc); if(phhitheader) { phhitheader = new (phhitheader) HRichPhotonHitHeader; phhitheader->setSector(sec); phhitheader->setRingX(xr); phhitheader->setRingY(yr); // # warning "findLocMax():passing floats through Int_t arguments. fix me." phhitheader->setRingPhi(phir); phhitheader->setRingTheta(thetar); phhitheader->setNbPhotons(nPhotonCounter); } return kTRUE; } else return kFALSE; } Bool_t HRichPhotonFinder::isLocalMaxOnBorder(Int_t xmax, Int_t ymax, Int_t xr,Int_t yr){ // is the local max candidate on the border of the search area ? Int_t xshifted = xmax-(xr-fs); Int_t yshifted = ymax-(yr-fs); //cout<<"xshifted :"<0 && xshifted1 && yshifted fChargeUpper && fChargeCenter > fChargeLower && fChargeCenter > fChargeRight && fChargeCenter > fChargeLeft ){ return kTRUE; }else{ return kFALSE; } } //void HRichPhotonFinder::subtractThreshold(){ // in order to improve the spatial resolution when constructing // the photon impact point by wheighted sums, one should // subtract the threshold that was set in the electronics when taking data. // This increases the pulse height ratios contributing to the averaging. // cf.: Schneider, R.; Diploma Thesis 1991; TU Muenchen; unpublished // Float_t fChOffset = 1.0; // change this later to real calculated sigmas // for (Int_t i=0;igetPadsPar(); Float_t fPhotonX = photon->getX(); Float_t fPhotonY = photon->getY(); Int_t nPadX0 = (Int_t) TMath::Floor(fPhotonX); Int_t nPadY0 = (Int_t) TMath::Floor(fPhotonY); Float_t fPhotonPhi = 0.; Float_t fPhotonTheta = 0.; if (pPadsPar) { Float_t fThetaOfPadCenter0 = 0; Float_t fPhiOfPadCenter0 = 0; HRichPad *pPad0 = pPadsPar->getPad(nPadX0,nPadY0); if (pPad0) { fThetaOfPadCenter0 = pPad0->getTheta(); fPhiOfPadCenter0 = pPad0->getPhi(photon->getSector()); } else { cout<<"ERROR: no pointer to pad 0"<getPad(nPadX0,nPadY0-1); if (pPad1) { fThetaOfPadCenter1 = pPad1->getTheta(); //fPhiOfPadCenter1 = pPad1->getPhi(sector);//for later use } else { cout<<"ERROR: no pointer to pad 1"<getPad(nPadX0-1,nPadY0); if (pPad2) { //fThetaOfPadCenter2 = pPad2->getTheta();//for later use fPhiOfPadCenter2 = pPad2->getPhi(photon->getSector()); } else { cout<<"ERROR: no pointer to pad 2"<getPad(nPadX0+1,nPadY0); if (pPad3) { // fThetaOfPadCenter3 = pPad3->getTheta();//for later use fPhiOfPadCenter3 = pPad3->getPhi(photon->getSector()); } else { cout<<"ERROR: no pointer to pad 3"<getPad(nPadX0,nPadY0+1); if (pPad4) { fThetaOfPadCenter4 = pPad4->getTheta(); //fPhiOfPadCenter4 = pPad4->getPhi(sector);//for later use } else { cout<<"ERROR: no pointer to pad 4"< 0.5) { fPhotonPhi = (fPhotonX-0.5-nPadX0)* (fPhiOfPadCenter3-fPhiOfPadCenter0) + fPhiOfPadCenter0; } if (fPhotonX-nPadX0 < 0.5) { fPhotonPhi = (fPhotonX+0.5-nPadX0)* (fPhiOfPadCenter0-fPhiOfPadCenter2) + fPhiOfPadCenter2; } // theta interpolation //cout<<"theta interpolation"< 0.5) { fPhotonTheta = (fPhotonY-0.5-nPadY0)* (fThetaOfPadCenter4-fThetaOfPadCenter0) + fThetaOfPadCenter0; } if (fPhotonY-nPadY0 < 0.5) { fPhotonTheta = (fPhotonY+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"<setTheta(fPhotonTheta); photon->setPhi(fPhotonPhi); }