CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/Calibration/Tools/src/HouseholderDecomposition.cc

Go to the documentation of this file.
00001 
00009 #include "Calibration/Tools/interface/HouseholderDecomposition.h"
00010 #include <cfloat>
00011 #include <cmath>
00012 #include <cstdlib>
00013 
00014 HouseholderDecomposition::HouseholderDecomposition(int squareMode_, int mineta_, int maxeta_, int minphi_, int maxphi_)
00015   :squareMode(squareMode_), countEvents(0),mineta(mineta_), maxeta(maxeta_), minphi(minphi_), maxphi(maxphi_)
00016 {
00017   Neta = maxeta - mineta + 1;
00018   if (mineta * maxeta < 0) Neta--; // there's no eta index = 0
00019   Nphi = maxphi - minphi + 1;
00020   if (Nphi <0) Nphi += 360;
00021   
00022   Nchannels = Neta * Nphi; // no. of channels, get it from edges of the region
00023 
00024   Nxtals = squareMode*squareMode; // no. of xtals in one event
00025 
00026   sigmaReplacement = 0.00001; // the sum of columns is replaced by this value in case it is zero (e.g. dead crystal)
00027 
00028 }
00029 
00030 HouseholderDecomposition::~HouseholderDecomposition()
00031 {
00032 }
00033 
00034 
00035 std::vector<float> HouseholderDecomposition::runRegional(const std::vector<std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi, const std::vector<float>& energyVector, const int& nIter, const int& regLength)
00036 {
00037   // make regions
00038   makeRegions(regLength);
00039 
00040   Nevents = eventMatrix.size(); // Number of events to calibrate with
00041 
00042   std::vector<float> totalSolution(Nchannels,1.);
00043   std::vector<float> iterSolution(Nchannels,1.);
00044   std::vector<std::vector<float> > myEventMatrix(eventMatrix);
00045   std::vector<float> myEnergyVector(energyVector);
00046 
00047   // loop over nIter
00048   for (int iter=1;iter<=nIter;iter++) 
00049     {
00050       // loop over regions
00051       for (unsigned int ireg=0; ireg<regMinEta.size(); ireg++)
00052         {
00053           std::vector<float> regIterSolution, regEnergyVector;
00054           std::vector<int> regVmaxCeta, regVmaxCphi;
00055           std::vector<std::vector<float> > regEventMatrix;
00056 
00057           // initialize new instance with regional min,max indices
00058           HouseholderDecomposition regionalHH(squareMode,regMinEta[ireg],regMaxEta[ireg],regMinPhi[ireg],regMaxPhi[ireg]);
00059 
00060           // copy all events in region into new eventmatrix, energyvector, VmaxCeta, VmaxCphi
00061           for (unsigned int ia=0; ia<VmaxCeta.size(); ia++)
00062             {
00063               if ((VmaxCeta[ia] >= regMinEta[ireg]) && (VmaxCeta[ia] <= regMaxEta[ireg])
00064                   && (VmaxCphi[ia] >= regMinPhi[ireg]) && (VmaxCphi[ia] <= regMaxPhi[ireg]))
00065                 {
00066                   // save event, calculate new eventmatrix(truncated) and energy
00067                   regVmaxCeta.push_back(VmaxCeta[ia]);
00068                   regVmaxCphi.push_back(VmaxCphi[ia]);
00069 
00070                   std::vector<float> regEvent = myEventMatrix[ia];
00071                   float regEnergy = energyVector[ia];
00072                   for (int i2=0; i2<Nxtals; i2++)
00073                     {
00074                       int iFullReg = regionalHH.indexSqr2Reg(i2, VmaxCeta[ia], VmaxCphi[ia]);
00075                       if (iFullReg <0) // crystal outside
00076                         {
00077                           regEnergy -= regEvent[i2];
00078                           regEvent[i2] = 0.;
00079                         }
00080                     }
00081                   regEventMatrix.push_back(regEvent);
00082                   regEnergyVector.push_back(regEnergy);
00083                 }
00084             }
00085 
00086           // calibrate
00087           //      std::cout << "HouseholderDecomposition::runRegional - Starting calibration of region " << ireg << ": eta " 
00088           //           << regMinEta[ireg] << " to " << regMaxEta[ireg] << ", phi " << regMinPhi[ireg] << " to " << regMaxPhi[ireg] << std::endl;
00089           regIterSolution = regionalHH.iterate(regEventMatrix, regVmaxCeta, regVmaxCphi, regEnergyVector);
00090           //      std::cout << "HouseholderDecomposition::runRegional - calibration of region finished. " << std::endl;
00091 
00092           // save solution into global iterSolution
00093           // don't forget to delete the ones that are on the border !
00094           for (unsigned int i1=0; i1<regIterSolution.size(); i1++)
00095             {
00096               int regFrame = regLength/2;
00097               int currRegPhiRange = regMaxPhi[ireg] - regMinPhi[ireg] + 1;
00098               int currRegEta = i1 / currRegPhiRange + regMinEta[ireg];
00099               int currRegPhi = i1 % currRegPhiRange + regMinPhi[ireg];
00100               int newindex = -100;
00101               // if crystal well inside:
00102               if ( (currRegEta >= (regMinEta[ireg]+regFrame*(!(regMinEta[ireg]==mineta))) ) &&
00103                    (currRegEta <= (regMaxEta[ireg]-regFrame*(!(regMaxEta[ireg]==maxeta))) ) &&
00104                    (currRegPhi >= (regMinPhi[ireg]+regFrame*(!(regMinPhi[ireg]==minphi))) ) &&
00105                    (currRegPhi <= (regMaxPhi[ireg]-regFrame*(!(regMaxPhi[ireg]==maxphi))) ) )
00106                 {
00107                   newindex = (currRegEta-mineta)*Nphi + currRegPhi-minphi;
00108                   iterSolution[newindex] = regIterSolution[i1];
00109                 }
00110             }
00111         } // end loop over regions
00112 
00113       if (iterSolution.empty()) return iterSolution;
00114       
00115       // re-calibrate eventMatrix with solution
00116       for (int ievent = 0; ievent<Nevents; ievent++)
00117         {
00118           myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], VmaxCeta[ievent], VmaxCphi[ievent], iterSolution);
00119         }
00120       
00121       // save solution into theCalibVector
00122       for (int i=0; i<Nchannels; i++) 
00123         {
00124           totalSolution[i] *= iterSolution[i];
00125         }
00126       
00127     } // end loop over nIter
00128 
00129   return totalSolution;
00130 
00131 }
00132 
00133 
00134 std::vector<float> HouseholderDecomposition::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi, const std::vector<float>& energyVector, const int& nIter, const bool& normalizeFlag)
00135 {
00136   Nevents = eventMatrix.size(); // Number of events to calibrate with
00137 
00138   std::vector<float> totalSolution(Nchannels,1.);
00139   std::vector<float> iterSolution;
00140   std::vector<std::vector<float> > myEventMatrix(eventMatrix);
00141   std::vector<float> myEnergyVector(energyVector);
00142 
00143   int i, j;
00144 
00145   // Iterate the correction
00146   for (int iter=1;iter<=nIter;iter++) 
00147     {
00148 
00149       // if normalization flag is set, normalize energies
00150       float sumOverEnergy;
00151       if (normalizeFlag)
00152         {
00153           float scale = 0.;
00154           
00155           for (i=0; i<Nevents; i++)
00156             {
00157               sumOverEnergy = 0.;
00158               for (j=0; j<Nxtals; j++) {sumOverEnergy += myEventMatrix[i][j];}
00159               sumOverEnergy /= myEnergyVector[i];
00160               scale += sumOverEnergy;
00161             }
00162           scale /= Nevents;
00163           
00164           for (i=0; i<Nevents; i++) {myEnergyVector[i] *= scale;}         
00165         } // end normalize energies
00166 
00167 
00168 
00169       // now the real work starts:
00170       iterSolution = iterate(myEventMatrix,VmaxCeta,VmaxCphi,myEnergyVector);
00171 
00172       if (iterSolution.empty()) return iterSolution;
00173 
00174       // re-calibrate eventMatrix with solution
00175       for (int ievent = 0; ievent<Nevents; ievent++)
00176         {
00177           myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], VmaxCeta[ievent], VmaxCphi[ievent], iterSolution);
00178         }
00179 
00180       for (int i=0; i<Nchannels; i++) 
00181         {
00182           // save solution into theCalibVector
00183           totalSolution[i] *= iterSolution[i];
00184         }
00185 
00186     } // end iterate correction
00187 
00188   return totalSolution;
00189 }
00190 
00191 
00192 
00193 std::vector<float> HouseholderDecomposition::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi, const std::vector<float>& energyVectorOrig)
00194 {
00195   std::vector<float> solution; 
00196 
00197   Nevents=eventMatrix.size();      // Number of events to calibrate with
00198 
00199   if (Nchannels > Nevents)
00200     {
00201       std::cout << "Householder::runIter(): more channels to calibrate than events available. " << std::endl;
00202       std::cout << "  Nchannels=" << Nchannels << std::endl;
00203       std::cout << "  Nevents=" << Nevents << std::endl;
00204       std::cout << " ******************    ERROR   *********************" << std::endl;
00205       return solution; // empty vector
00206     }
00207 
00208   // input: eventMatrixOrig - the unzipped matrix
00209   eventMatrixOrig = unzipMatrix(eventMatrix,VmaxCeta,VmaxCphi);
00210 
00211  if (eventMatrixOrig.size() != energyVectorOrig.size())
00212     {
00213       std::cout << "Householder::runIter(): matrix dimensions non-conformant. " << std::endl;
00214       std::cout << "  energyVectorOrig.size()=" << energyVectorOrig.size() << std::endl;
00215       std::cout << "  eventMatrixOrig.size()=" << eventMatrixOrig.size() << std::endl;
00216       std::cout << " ******************    ERROR   *********************" << std::endl;
00217       return solution; // empty vector
00218     }
00219 
00220 
00221   int i,j;
00222   eventMatrixProc = eventMatrixOrig;
00223   energyVectorProc = energyVectorOrig; // copy energyVectorOrig vector
00224   std::vector<float> e(Nchannels);
00225   alpha.assign(Nchannels,0.);
00226   pivot.assign(Nchannels,0);
00227   
00228 
00229   //--------------------
00230   bool decomposeSuccess = decompose();
00231 
00232   if( !decomposeSuccess ) 
00233     {
00234       std::cout << "Householder::runIter(): Failed: Singular condition in decomposition."<< std::endl;
00235       std::cout << "***************** PROBLEM in DECOMPOSITION *************************"<<std::endl;
00236       return solution; // empty vector
00237     }
00238 
00239   /* DBL_EPSILON: Difference between 1.0 and the minimum float greater than 1.0 */
00240   float mydbleps = 2.22045e-16;  //DBL_EPSILON;
00241   float etasqr = mydbleps*mydbleps; 
00242   //  std::cout << "LOOK at DBL_EPSILON :" << mydbleps <<std::endl;
00243 
00244 
00245   //--------------------
00246   // apply transformations to rhs - find solution vector
00247   solution.assign(Nchannels,0.);
00248   solve(solution);
00249 
00250 
00251   // compute residual vector energyVectorProc
00252   for (i=0;i<Nevents;i++) 
00253     {
00254       energyVectorProc[i] = energyVectorOrig[i];
00255       for (j=0; j<Nchannels; j++)
00256         {
00257           energyVectorProc[i]-=eventMatrixOrig[i][j]*solution[j];
00258         }
00259     }
00260 
00261 
00262   //--------------------
00263   // compute first correction vector e
00264   solve(e);
00265 
00266   float normy0=0.;
00267   float norme1=0.;
00268   float norme0;
00269     
00270 
00271 
00272 
00273   for (i=0;i<Nchannels;i++) 
00274     {
00275       normy0 += solution[i] * solution[i];
00276       norme1 += e[i] * e[i];
00277     }
00278   
00279 //  std::cout << "Householder::runIter(): applying first correction";
00280 //  std::cout << " normy0 = " << normy0;
00281 //  std::cout << " norme1 = " << norme1 << std::endl;
00282 
00283   // not attempt at obtaining the solution is made unless the norm of the first
00284   // correction  is significantly smaller than the norm of the initial solution
00285   if (norme1>(0.0625*normy0)) 
00286     {
00287       //      std::cout << "Householder::runIter(): first correction is too large. Failed." << std::endl;
00288     }
00289 
00290   // improve the solution
00291   for (i=0; i<Nchannels; i++)
00292     {
00293       solution[i]+=e[i];
00294     }
00295 
00296   //  std::cout << "Householder::runIter(): improving solution...." << std::endl;
00297 
00298   //--------------------
00299   // only continue iteration if the correction was significant
00300   while (norme1>(etasqr*normy0)) 
00301     {
00302       //      std::cout << "Householder::runIter(): norme1 = " << norme1 << std::endl;
00303     
00304       for (i=0; i<Nevents; i++) 
00305         {
00306           energyVectorProc[i] = energyVectorOrig[i];
00307           for (j=0; j<Nchannels; j++)
00308             {
00309               energyVectorProc[i] -= eventMatrixOrig[i][j] * solution[j];
00310             }
00311         }
00312 
00313     // compute next correction vector
00314     solve(e);
00315 
00316     norme0 = norme1;
00317     norme1 = 0.;
00318 
00319     for (i=0;i<Nchannels;i++)
00320       {
00321         norme1+=e[i]*e[i];
00322       }
00323 
00324     // terminate iteration if the norm of the new correction failed to decrease
00325     // significantly compared to the norm of the previous correction
00326     if (norme1>(0.0625*norme0)) break;
00327 
00328     // apply correction vector
00329     for (i=0;i<Nchannels;i++)
00330       {
00331         solution[i]+=e[i];
00332       }
00333   }
00334 
00335   //clean up
00336   eventMatrixOrig.clear();
00337   eventMatrixProc.clear();
00338   energyVectorProc.clear();
00339   alpha.clear();
00340   pivot.clear();
00341 
00342   
00343   return solution;
00344 }
00345 
00346 
00347 bool HouseholderDecomposition::decompose()
00348 {
00349   int i,j,jbar,k;
00350   float beta,sigma,alphak,eventMatrixkk;
00351   std::vector<float> y(Nchannels);
00352   std::vector<float> sum(Nchannels);
00353 
00354   //  std::cout << "Householder::decompose() started" << std::endl;
00355   
00356   for (j=0;j<Nchannels;j++) 
00357     {
00358       // jth column sum: squared sum for each crystal
00359       sum[j]=0.;
00360       for (i=0;i<Nevents;i++)
00361         sum[j]+=eventMatrixProc[i][j]*eventMatrixProc[i][j];
00362       
00363       // bookkeeping vector
00364       pivot[j] = j;
00365     }
00366   
00367   for (k=0;k<Nchannels;k++) 
00368     {
00369       // kth Householder transformation
00370       sigma = sum[k];
00371       jbar = k;
00372       
00373       // go through all following columns
00374       // find the largest sumSquared in the following columns
00375       for (j=k+1;j<Nchannels;j++) 
00376         {
00377           if (sum[j] > sigma) 
00378             {
00379               sigma = sum[j];
00380               jbar=j;
00381             }
00382         }
00383 
00384       if (jbar != k) 
00385         {
00386           // column interchange:
00387           //     interchange within: bookkeeping vector, squaredSum, eventMatrixProc 
00388 
00389           i = pivot[k];
00390           pivot[k]=pivot[jbar];
00391           pivot[jbar]=i;
00392 
00393           sum[jbar]=sum[k];
00394           sum[k]=sigma;
00395           
00396           for (i=0;i<Nevents;i++) 
00397             {
00398               sigma=eventMatrixProc[i][k];
00399               eventMatrixProc[i][k]=eventMatrixProc[i][jbar];
00400               eventMatrixProc[i][jbar]=sigma;
00401             }
00402         } // end column interchange
00403 
00404       // now store in sigma the squared sum of the readoutEnergies for this column(crystal)
00405       sigma=0.;
00406       for (i=k;i<Nevents;i++)
00407         {
00408           sigma+=eventMatrixProc[i][k]*eventMatrixProc[i][k];
00409         }
00410 
00411       // found a zero-column, bail out
00412       if (sigma == 0.) 
00413         {
00414 //        std::cout << "Householder::decompose() failed" << std::endl;
00415 //        return false;
00416           // rof 14.12.2006: workaround to avoid failure of algorithm because of dead crystals:
00417           sigma = sigmaReplacement;
00418           //      std::cout << "Householder::decompose - found zero column " << jbar << ", replacing sum of column elements by " << sigma << std::endl;
00419         }
00420 
00421 
00422       // the following paragraph acts only on the diagonal element:
00423       // if element=0, then calculate alpha & beta
00424 
00425       // take the diagonal element
00426       eventMatrixkk = eventMatrixProc[k][k];
00427 
00428       if (eventMatrixkk < 0.) 
00429         alpha[k] = sqrt(sigma);
00430       else
00431         alpha[k] = sqrt(sigma) * (-1.);
00432 
00433       alphak = alpha[k];
00434 
00435       beta = 1 / (sigma - eventMatrixkk * alphak);
00436       // replace it
00437       eventMatrixProc[k][k] = eventMatrixkk - alphak;
00438 
00439       for (j=k+1; j<Nchannels; j++) 
00440         {
00441           y[j] = 0.;
00442 
00443           for (i=k; i<Nevents; i++)
00444             {
00445               y[j] += eventMatrixProc[i][k] * eventMatrixProc[i][j];
00446             }
00447 
00448           y[j] *= beta;
00449         }
00450 
00451       for (j=k+1; j<Nchannels; j++) 
00452         {
00453           for (i=k; i<Nevents; i++) 
00454             {
00455               eventMatrixProc[i][j] -= eventMatrixProc[i][k] * y[j];
00456               sum[j] -= eventMatrixProc[k][j] * eventMatrixProc[k][j];
00457             }
00458         }
00459     } // end of kth householder transformation
00460   
00461   //  std::cout << "Householder::decompose() finished" << std::endl;
00462   
00463   return true;
00464 }
00465 
00466 
00467 void HouseholderDecomposition::solve(std::vector<float> &y)
00468 {
00469   std::vector<float> z(Nchannels,0.);
00470 
00471   float gamma;
00472   int i,j;
00473 
00474   //  std::cout << "Householder::solve() begin" << std::endl;
00475 
00476   for (j=0; j<Nchannels; j++) 
00477     {
00478       // apply jth transformation to the right hand side
00479       gamma = 0.;
00480       for (i=j; i<Nevents; i++)
00481         {
00482           gamma += eventMatrixProc[i][j] * energyVectorProc[i];
00483         }
00484       gamma /= (alpha[j] * eventMatrixProc[j][j]);
00485 
00486       for (i=j; i<Nevents; i++)
00487         {
00488           energyVectorProc[i] += gamma * eventMatrixProc[i][j];
00489         }
00490     }
00491 
00492   z[Nchannels-1] = energyVectorProc[Nchannels-1] / alpha[Nchannels-1];
00493 
00494   for (i=Nchannels-2; i>=0; i--) 
00495     {
00496       z[i] = energyVectorProc[i];
00497       for (j=i+1; j<Nchannels; j++)
00498         {
00499           z[i] -= eventMatrixProc[i][j]*z[j];
00500         }
00501       z[i] /= alpha[i];
00502     }
00503   
00504   for (i=0; i<Nchannels; i++)
00505     {
00506       y[pivot[i]] = z[i];
00507     }
00508   
00509   //  std::cout << "Householder::solve() finished." << std::endl;
00510   
00511 }
00512 
00513 
00514 std::vector<float> HouseholderDecomposition::recalibrateEvent(const std::vector<float>& eventSquare, const int& maxCeta, const int& maxCphi, const std::vector<float>& recalibrateVector)
00515 {
00516   std::vector<float> newEventSquare(eventSquare);
00517   int iFull;
00518 
00519   for (int i=0; i<Nxtals; i++) 
00520     {
00521       iFull = indexSqr2Reg(i, maxCeta, maxCphi);
00522       if (iFull >=0)
00523         newEventSquare[i] *= recalibrateVector[iFull];
00524     }
00525   return newEventSquare;
00526 }
00527 
00528 
00529 int HouseholderDecomposition::indexSqr2Reg(const int& sqrIndex, const int& maxCeta, const int& maxCphi)
00530 {
00531   int regionIndex;
00532 
00533   // get the current eta, phi indices
00534   int curr_eta = maxCeta - squareMode/2 + sqrIndex%squareMode;
00535   if (curr_eta * maxCeta <= 0) {if (maxCeta > 0) curr_eta--; else curr_eta++; }  // JUMP over 0
00536 
00537   int curr_phi = maxCphi - squareMode/2 + sqrIndex/squareMode;
00538   if (curr_phi < 1) curr_phi += 360;
00539   if (curr_phi > 360) curr_phi -= 360;
00540 
00541   bool negPhiDirection = (maxphi < minphi);
00542   int iFullphi;
00543 
00544   regionIndex = -1;
00545 
00546   if (curr_eta >= mineta && curr_eta <= maxeta)
00547     if ( (!negPhiDirection && (curr_phi >= minphi && curr_phi <= maxphi)) ||
00548          (negPhiDirection && !(curr_phi >= minphi && curr_phi <= maxphi))      ) 
00549       {
00550         iFullphi = curr_phi - minphi;
00551         if (iFullphi < 0) iFullphi += 360;
00552         regionIndex = (curr_eta - mineta) * (maxphi - minphi + 1 + 360*negPhiDirection) + iFullphi;
00553       }
00554 
00555   return regionIndex;
00556 }
00557 
00558 std::vector<std::vector<float> > HouseholderDecomposition::unzipMatrix(const std::vector< std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi)
00559 {
00560   std::vector< std::vector<float> > fullMatrix;
00561 
00562   int iFull;
00563 
00564   for (int i=0; i<Nevents; i++)
00565     {
00566       std::vector<float> foo(Nchannels,0.);
00567       for (int k=0; k<Nxtals; k++)
00568         {
00569           iFull = indexSqr2Reg(k, VmaxCeta[i], VmaxCphi[i]);
00570           if (iFull >=0)
00571             foo[iFull] = eventMatrix[i][k];
00572         }
00573       fullMatrix.push_back(foo);
00574     }
00575 
00576   return fullMatrix;
00577 }
00578 
00579 void HouseholderDecomposition::makeRegions(const int& regLength)
00580 {
00581   //  int regFrame = regLength/2;
00582   int regFrame = squareMode/2;
00583   // first eta:
00584   int remEta = Neta % regLength;
00585   if (remEta > regLength/2) remEta -= regLength;
00586   int numSubRegEta = Neta / regLength + (remEta < 0)*1;
00587 
00588   int addtoEta = remEta / numSubRegEta;
00589   int addtomoreEta = remEta % numSubRegEta; // add "addtomore" number of times (addto+1), remaining times add just (addto)
00590 
00591   // then phi:
00592   int remPhi = Nphi % regLength;
00593   if (remPhi > regLength/2) remPhi -= regLength;
00594   int numSubRegPhi = Nphi / regLength + (remPhi < 0)*1;
00595 
00596   int addtoPhi = remPhi / numSubRegPhi;
00597   int addtomorePhi = remPhi % numSubRegPhi; // add "addtomore" number of times (addto+-1), remaining times add just (addto)
00598 
00599   // now put it all together
00600   int addedLengthEta = 0;
00601   int addedLengthPhi = 0;
00602   int startIndexEta = mineta;
00603   int startIndexPhi;
00604   int endIndexEta = 0;
00605   int endIndexPhi;
00606   for (int i=0; i < numSubRegEta; i++)
00607     {
00608       addedLengthEta = regLength + addtoEta + addtomoreEta/abs(addtomoreEta)*(i<abs(addtomoreEta));
00609       endIndexEta = startIndexEta + addedLengthEta - 1;
00610 
00611       startIndexPhi = minphi;
00612       endIndexPhi = 0;
00613       for (int j=0; j < numSubRegPhi; j++)
00614         {
00615           addedLengthPhi = regLength + addtoPhi + addtomorePhi/abs(addtomorePhi)*(j<abs(addtomorePhi));
00616           endIndexPhi = startIndexPhi + addedLengthPhi - 1;
00617 
00618           regMinPhi.push_back(startIndexPhi - regFrame*(j!=0) );
00619           regMaxPhi.push_back(endIndexPhi + regFrame*(j!=(numSubRegPhi-1)) );
00620           regMinEta.push_back(startIndexEta - regFrame*(i!=0) );
00621           regMaxEta.push_back(endIndexEta + regFrame*(i!=(numSubRegEta-1)) );
00622 
00623           startIndexPhi = endIndexPhi + 1;
00624         }
00625       startIndexEta = endIndexEta + 1;
00626     }
00627 
00628 //  // print it all
00629 //  std::cout << "Householder::makeRegions created the following regions for calibration:" << std::endl;
00630 //  for (int i=0; i<regMinEta.size(); i++)
00631 //    std::cout << "Region " << i << ": eta = " << regMinEta[i] << " to " << regMaxEta[i] << ", phi = " << regMinPhi[i] << " to " << regMaxPhi[i] << std::endl;
00632 
00633 }