CMS 3D CMS Logo

HouseholderDecomposition.cc

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

Generated on Tue Jun 9 17:25:43 2009 for CMSSW by  doxygen 1.5.4