• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

beamtime/cern-oct12/go4/RICH/CbmRichRingFinderHoughImpl.cxx (r4864/r3568)

Go to the documentation of this file.
00001 
00008 #include "CbmRichRingFinderHoughImpl.h"
00009 #include "CbmRichRingLight.h"
00010 #include "CbmRichRingFitterCOP.h"
00011 
00012 #include <iostream>
00013 #include <cmath>
00014 #include <set>
00015 #include <algorithm>
00016 #include <iostream>
00017 
00018 using std::cout;
00019 using std::endl;
00020 using std::vector;
00021 using std::set;
00022 using std::sort;
00023 
00024 CbmRichRingFinderHoughImpl::CbmRichRingFinderHoughImpl():
00025    fNofParts(0),
00026 
00027    fMaxDistance(0.f),
00028    fMinDistance(0.f),
00029    fMinDistanceSq(0.f),
00030    fMaxDistanceSq(0.f),
00031 
00032    fMinRadius(0.f),
00033    fMaxRadius(0.f),
00034 
00035    fDx(0.f),
00036    fDy(0.f),
00037    fDr(0.f),
00038    fNofBinsX(0),
00039    fNofBinsY(0),
00040    fNofBinsXY(0),
00041 
00042    fHTCut(0),
00043 
00044    fNofBinsR(0),
00045    fHTCutR(0),
00046 
00047    fMinNofHitsInArea(0),
00048 
00049    fRmsCoeffCOP(0.f),
00050    fMaxCutCOP(0.f),
00051 
00052    fCurMinX(0.f),
00053    fCurMinY(0.f),
00054 
00055    fData(),
00056    fHist(),
00057    fHistR(),
00058    fHitInd(),
00059    fFoundRings(),
00060    fFitCOP(NULL)
00061 {
00062    SetParameters();
00063 
00064    fHist.resize(fNofBinsXY);
00065    fHistR.resize(fNofBinsR);
00066    fHitInd.resize(fNofParts);
00067 
00068    fFitCOP = new CbmRichRingFitterCOP();
00069 }
00070 
00071 CbmRichRingFinderHoughImpl::~CbmRichRingFinderHoughImpl()
00072 {
00073         if (NULL != fFitCOP) delete fFitCOP;
00074 }
00075 
00076 void CbmRichRingFinderHoughImpl::DoFind(
00077                 const vector<CbmRichHitLight>& hits)
00078 {
00079         for (int i = 0 ; i < fFoundRings.size(); i++){
00080                 if (fFoundRings[i] != NULL) delete fFoundRings[i];
00081         }
00082         fFoundRings.clear();
00083         fData.clear();
00084 
00085         if (hits.size() < 1) return;
00086 
00087         if (fData.size() > MAX_NOF_HITS) {
00088            cout << endl << endl << "-E- CbmRichRingFinderHoughImpl::DoFind"
00089                  << ". Number of hits is more than " << MAX_NOF_HITS << endl << endl;
00090            return;
00091         }
00092 
00093         for (int iH = 0; iH < hits.size(); iH++){
00094                 CbmRichHoughHit tempPoint;
00095                 tempPoint.fHit.fX = hits[iH].fX;
00096                 tempPoint.fHit.fY = hits[iH].fY;
00097                 tempPoint.fX2plusY2 = hits[iH].fX * hits[iH].fX + hits[iH].fY * hits[iH].fY;
00098                 tempPoint.fId = iH;
00099                 tempPoint.fIsUsed = false;
00100                 fData.push_back(tempPoint);
00101         }
00102 
00103 
00104         std::sort(fData.begin(), fData.end(), CbmRichHoughHitCmpUp());
00105         HoughTransformReconstruction();
00106         fData.clear();
00107 }
00108 
00109 void CbmRichRingFinderHoughImpl::SetParameters()
00110 {
00111         fMaxDistance = 115.;
00112         fMinDistance = 10.;
00113         fMinDistanceSq = fMinDistance*fMinDistance;
00114         fMaxDistanceSq = fMaxDistance*fMaxDistance;
00115 
00116         fMinRadius = 20.;
00117         fMaxRadius = 65.;
00118 
00119         fHTCut = 7;
00120         fHTCutR = 5;
00121         fMinNofHitsInArea = 4;
00122 
00123         fNofBinsX = 25;
00124         fNofBinsY = 25;
00125         fNofBinsR = 32;
00126 
00127         fRmsCoeffCOP = 3.;
00128         fMaxCutCOP = 10.;
00129 
00130         fNofParts = 1;
00131    fDx = 2.f * fMaxDistance / (float)fNofBinsX;
00132    fDy = 2.f * fMaxDistance / (float)fNofBinsY;
00133    fDr = fMaxRadius / (float)fNofBinsR;
00134    fNofBinsXY = fNofBinsX * fNofBinsY;
00135 }
00136 
00137 void CbmRichRingFinderHoughImpl::HoughTransformReconstruction()
00138 {
00139    int indmin, indmax;
00140    unsigned int size = fData.size();
00141 
00142    fCurMinX = fData[0].fHit.fX - fMaxDistance;
00143    fCurMinY = fData[0].fHit.fY - fMaxDistance;
00144 
00145    DefineLocalAreaAndHits(fData[0].fHit.fX, fData[0].fHit.fY , &indmin, &indmax);
00146    HoughTransform(indmin, indmax);
00147    FindPeak(indmin, indmax);
00148 
00149    DefineLocalAreaAndHits(fData[0].fHit.fX, fData[0].fHit.fY , &indmin, &indmax);
00150    HoughTransform(indmin, indmax);
00151    FindPeak(indmin, indmax);
00152 }
00153 
00154 void CbmRichRingFinderHoughImpl::DefineLocalAreaAndHits(
00155       float x0,
00156       float y0,
00157       int *indmin,
00158           int *indmax)
00159 {
00160    CbmRichHoughHit mpnt;
00161    vector<CbmRichHoughHit>::iterator itmin, itmax;
00162 
00163         //find all hits which are in the corridor
00164         mpnt.fHit.fX = x0 - fMaxDistance;
00165         itmin = std::lower_bound(fData.begin(), fData.end(), mpnt, CbmRichHoughHitCmpUp());
00166 
00167         mpnt.fHit.fX = x0 + fMaxDistance;
00168         itmax = std::lower_bound(fData.begin(), fData.end(), mpnt, CbmRichHoughHitCmpUp()) - 1;
00169 
00170         *indmin = itmin - fData.begin();
00171         *indmax = itmax - fData.begin();
00172 
00173         int arSize = *indmax - *indmin + 1;
00174         if (arSize <= fMinNofHitsInArea) return;
00175 
00176         for (unsigned short i = 0; i < fNofParts; i++){
00177                 fHitInd[i].clear();
00178                 fHitInd[i].reserve( (*indmax-*indmin) / fNofParts);
00179         }
00180 
00181         unsigned short indmin1 = (unsigned short)(*indmin);
00182         unsigned short indmax1 = (unsigned short)(*indmax);
00183 
00184    for (unsigned short i = indmin1; i <= indmax1; i++) {
00185       if (fData[i].fIsUsed == true) continue;
00186       float ry = y0 - fData[i].fHit.fY;
00187       if (fabs(ry) > fMaxDistance) continue;
00188       float rx = x0 - fData[i].fHit.fX;
00189       float d = rx * rx + ry * ry;
00190       if (d > fMaxDistanceSq) continue;
00191            fHitInd[i % fNofParts].push_back(i);
00192    }
00193 
00194         for (unsigned short j = 0; j < fNofBinsXY; j++){
00195                 fHist[j] = 0;
00196         }
00197 
00198         for (unsigned short k = 0; k < fNofBinsR; k++) {
00199                 fHistR[k] = 0;
00200         }
00201 }
00202 
00203 void CbmRichRingFinderHoughImpl::HoughTransform(
00204       unsigned short int indmin,
00205       unsigned short int indmax)
00206 {
00207     for (int iPart = 0; iPart < fNofParts; iPart++){
00208          HoughTransformGroup(indmin, indmax, iPart);
00209     }//iPart
00210 }
00211 
00212 void CbmRichRingFinderHoughImpl::HoughTransformGroup(
00213       unsigned short int indmin,
00214                 unsigned short int indmax,
00215                 int iPart)
00216 {
00217    unsigned short nofHits = fHitInd[iPart].size();
00218    float xcs, ycs; // xcs = xc - fCurMinX
00219    float dx = 1.0f/fDx, dy = 1.0f/fDy, dr = 1.0f/fDr;
00220 
00221    vector<CbmRichHoughHit> data;
00222    data.resize(nofHits);
00223    for (int i = 0; i < nofHits; i++){
00224       data[i] = fData[ fHitInd[iPart][i] ];
00225    }
00226 
00227    typedef vector<CbmRichHoughHit>::iterator iH;
00228 
00229         for (iH iHit1 = data.begin(); iHit1 != data.end(); iHit1++) {
00230            float iH1X = iHit1->fHit.fX;
00231                 float iH1Y = iHit1->fHit.fY;
00232 
00233       for (iH iHit2 = iHit1 + 1; iHit2 != data.end(); iHit2++) {
00234          float iH2X = iHit2->fHit.fX;
00235          float iH2Y = iHit2->fHit.fY;
00236 
00237          float rx0 = iH1X - iH2X;//rx12
00238          float ry0 = iH1Y- iH2Y;//ry12
00239          float r12 = rx0 * rx0 + ry0 * ry0;
00240          if (r12 < fMinDistanceSq || r12 > fMaxDistanceSq)      continue;
00241 
00242          float t10 = iHit1->fX2plusY2 - iHit2->fX2plusY2;
00243          for (iH iHit3 = iHit2 + 1; iHit3 != data.end(); iHit3++) {
00244             float iH3X = iHit3->fHit.fX;
00245             float iH3Y = iHit3->fHit.fY;
00246 
00247             float rx1 = iH1X - iH3X;//rx13
00248             float ry1 = iH1Y - iH3Y;//ry13
00249             float r13 = rx1 * rx1 + ry1 * ry1;
00250             if (r13 < fMinDistanceSq || r13 > fMaxDistanceSq)continue;
00251 
00252             float rx2 = iH2X - iH3X;//rx23
00253             float ry2 = iH2Y - iH3Y;//ry23
00254             float r23 = rx2 * rx2 + ry2 * ry2;
00255             if (r23     < fMinDistanceSq || r23 > fMaxDistanceSq)continue;
00256 
00257             float det = rx2*ry0 - rx0*ry2;
00258             if (det == 0.0f) continue;
00259             float t19 = 0.5f / det;
00260             float t5 = iHit2->fX2plusY2 - iHit3->fX2plusY2;
00261 
00262             float xc = (t5 * ry0 - t10 * ry2) * t19;
00263             xcs = xc - fCurMinX;
00264             int intX = int( xcs *dx);
00265             if (intX < 0 || intX >= fNofBinsX ) continue;
00266 
00267             float yc = (t10 * rx2 - t5 * rx0) * t19;
00268             ycs = yc - fCurMinY;
00269             int intY = int( ycs *dy);
00270             if (intY < 0 || intY >= fNofBinsY ) continue;
00271 
00272             //radius calculation
00273             float t6 = iH1X - xc;
00274             float t7 = iH1Y - yc;
00275             //if (t6 > fMaxRadius || t7 > fMaxRadius) continue;
00276             float r = sqrt(t6 * t6 + t7 * t7);
00277             //if (r < fMinRadius) continue;
00278             int intR = int(r *dr);
00279             if (intR < 0 || intR >= fNofBinsR) continue;
00280 
00281             fHist[intX * fNofBinsX + intY]++;
00282             fHistR[intR]++;
00283          }// iHit1
00284       }// iHit2
00285    }// iHit3
00286         //hitIndPart.clear();
00287 }
00288 
00289 void CbmRichRingFinderHoughImpl::FindPeak(
00290       int indmin,
00291       int indmax)
00292 {
00293    // Find MAX bin R and compare it with CUT
00294    int maxBinR = -1, maxR = -1;
00295    unsigned int size = fHistR.size();
00296    for (unsigned int k = 0; k < size; k++){
00297       if (fHistR[k] > maxBinR){
00298          maxBinR = fHistR[k];
00299          maxR = k;
00300       }
00301    }
00302         if (maxBinR < fHTCutR) return;
00303 
00304    // Find MAX bin XY and compare it with CUT
00305         int maxBinXY = -1, maxXY = -1;
00306    size = fHist.size();
00307    for (unsigned int k = 0; k < size; k++){
00308       if (fHist[k] > maxBinXY){
00309          maxBinXY = fHist[k];
00310          maxXY = k;
00311       }
00312    }
00313    if (maxBinXY < fHTCut) return;
00314 
00315         CbmRichRingLight* ring1 = new CbmRichRingLight();
00316 
00317    // Find Preliminary Xc, Yc, R
00318    float xc, yc, r;
00319    float rx, ry, dr;
00320         xc = (maxXY / fNofBinsX + 0.5f)* fDx + fCurMinX;
00321         yc = (maxXY % fNofBinsX + 0.5f)* fDy + fCurMinY;
00322         r = (maxR + 0.5f) * fDr;
00323         for (int j = indmin; j < indmax + 1; j++) {
00324                 rx = fData[j].fHit.fX - xc;
00325                 ry = fData[j].fHit.fY - yc;
00326 
00327                 dr = fabs(sqrt(rx * rx + ry * ry) - r);
00328                 if (dr > 6.) continue;
00329                 ring1->AddHit(fData[j].fHit, fData[j].fId);
00330         }
00331 
00332         if (ring1->GetNofHits() < 5) {
00333            delete ring1;
00334            return;
00335         }
00336 
00337         fFitCOP->DoFit(ring1);
00338         float drCOPCut = fRmsCoeffCOP * sqrt(ring1->GetChi2() / ring1->GetNofHits());
00339         if (drCOPCut > fMaxCutCOP)      drCOPCut = fMaxCutCOP;
00340 
00341         xc = ring1->GetCenterX();
00342         yc = ring1->GetCenterY();
00343         r = ring1->GetRadius();
00344 
00345         delete ring1;
00346 
00347         CbmRichRingLight* ring2 = new CbmRichRingLight();
00348         for (int j = indmin; j < indmax + 1; j++) {
00349                 rx = fData[j].fHit.fX - xc;
00350                 ry = fData[j].fHit.fY - yc;
00351 
00352                 dr = fabs(sqrt(rx * rx + ry * ry) - r);
00353                 if (dr > drCOPCut) continue;
00354                 fData[j].fIsUsed = true;
00355                 ring2->AddHit(fData[j].fHit, fData[j].fId);
00356         }
00357         if (ring2->GetNofHits() < 5) {
00358            delete ring2;
00359            return;
00360         }
00361 
00362    fFitCOP->DoFit(ring2);
00363    fFoundRings.push_back(ring2);
00364         ring2=NULL;
00365         delete ring2;
00366 }

Generated on Tue Dec 10 2013 04:52:17 for ROCsoft by  doxygen 1.7.1