CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/Alignment/MuonAlignmentAlgorithms/plugins/CSCChamberFitter.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 
00003 #include "CLHEP/Matrix/Matrix.h"
00004 #include "TMatrixDEigen.h"
00005 
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 
00008 #include "Alignment/MuonAlignmentAlgorithms/plugins/CSCChamberFitter.h"
00009 
00010 const double infinity = 0.1;  // this is huge because all alignments are angles in radians; but we need a not-too-large value for numerical stability
00011                               // should become a parameter someday
00012 
00013 CSCChamberFitter::CSCChamberFitter(const edm::ParameterSet &iConfig, std::vector<CSCPairResidualsConstraint*> &residualsConstraints) {
00014   m_name = iConfig.getParameter<std::string>("name");
00015   m_alignables = iConfig.getParameter<std::vector<std::string> >("alignables");
00016   if (m_alignables.size() == 0) {
00017     throw cms::Exception("BadConfig") << "Fitter " << m_name << " has no alignables!" << std::endl;
00018   }
00019 
00020   int i = 0;
00021   for (std::vector<std::string>::const_iterator alignable = m_alignables.begin();  alignable != m_alignables.end();  ++alignable) {
00022     if (alignableId(*alignable) == -1) m_frames.push_back(i);
00023     i++;
00024   }
00025 
00026   m_fixed = -1;
00027   std::string fixed = iConfig.getParameter<std::string>("fixed");
00028   if (fixed != "") {
00029     int i = 0;
00030     for (std::vector<std::string>::const_iterator alignable = m_alignables.begin();  alignable != m_alignables.end();  ++alignable) {
00031       if (fixed == *alignable) {
00032         m_fixed = i;
00033       }
00034       i++;
00035     }
00036     if (m_fixed == -1) throw cms::Exception("BadConfig") << "Cannot fix unrecognized alignable " << fixed << std::endl;
00037   }
00038 
00039   int numConstraints = 0;
00040   std::vector<edm::ParameterSet> constraints = iConfig.getParameter<std::vector<edm::ParameterSet> >("constraints");
00041   for (std::vector<edm::ParameterSet>::const_iterator constraint = constraints.begin();  constraint != constraints.end();  ++constraint) {
00042     int i = index(constraint->getParameter<std::string>("i"));
00043     int j = index(constraint->getParameter<std::string>("j"));
00044     double value = constraint->getParameter<double>("value");
00045     double error = constraint->getParameter<double>("error");
00046     
00047     if (i < 0) throw cms::Exception("BadConfig") << "Unrecognized alignable " << constraint->getParameter<std::string>("i") << " in constraint " << numConstraints << " of fitter " << m_name << std::endl;
00048     if (j < 0) throw cms::Exception("BadConfig") << "Unrecognized alignable " << constraint->getParameter<std::string>("j") << " in constraint " << numConstraints << " of fitter " << m_name << std::endl;
00049     if (error <= 0.) throw cms::Exception("BadConfig") << "Non-positive uncertainty in constraint " << numConstraints << " of fitter " << m_name << std::endl;
00050     if (i == j) throw cms::Exception("BadConfig") << "Self-connection from " << constraint->getParameter<std::string>("i") << " to " << constraint->getParameter<std::string>("j") << " is not allowed in constraint " << numConstraints << " of fitter " << m_name << std::endl;
00051 
00052     m_constraints.push_back(new CSCPairConstraint(i, j, value, error));
00053     numConstraints++;
00054   }
00055 
00056   // insert CSCPairResidualsConstraints
00057   for (unsigned int i = 0;  i < m_alignables.size();  i++) {
00058     std::string alignable_i = m_alignables[i];
00059     long id_i = alignableId(alignable_i);
00060     if (id_i != -1) {
00061       CSCDetId cscid_i(id_i);
00062 
00063       for (unsigned int j = 0;  j < m_alignables.size();  j++) {
00064         std::string alignable_j = m_alignables[j];
00065         long id_j = alignableId(alignable_j);
00066         if (i != j  &&  id_j != -1) {
00067           CSCDetId cscid_j(id_j);
00068 
00069           if (!(cscid_i.station() == 1  &&  cscid_i.ring() == 3  &&  cscid_j.station() == 1  &&  cscid_j.ring() == 3)) {
00070 
00071              int next_chamber = cscid_i.chamber() + 1;
00072              if (cscid_i.station() > 1  &&  cscid_i.ring() == 1  &&  next_chamber == 19) next_chamber = 1;
00073              else if (!(cscid_i.station() > 1  &&  cscid_i.ring() == 1)  &&  next_chamber == 37) next_chamber = 1;
00074              if (cscid_i.endcap() == cscid_j.endcap()  &&  cscid_i.station() == cscid_j.station()  &&  cscid_i.ring() == cscid_j.ring()  &&  next_chamber == cscid_j.chamber()) {
00075             
00076                 CSCPairResidualsConstraint *residualsConstraint = new CSCPairResidualsConstraint(residualsConstraints.size(), i, j, cscid_i, cscid_j);
00077                 m_constraints.push_back(residualsConstraint);
00078                 residualsConstraints.push_back(residualsConstraint);
00079                 numConstraints++;           
00080              }
00081           }
00082         }
00083       }
00084     }
00085   }
00086 
00087   std::map<int,bool> touched;
00088   for (unsigned int i = 0;  i < m_alignables.size();  i++) touched[i] = false;
00089   walk(touched, 0);
00090   for (unsigned int i = 0;  i < m_alignables.size();  i++) {
00091     if (!touched[i]) throw cms::Exception("BadConfig") << "Fitter " << m_name << " is not a connected graph (no way to get to " << m_alignables[i] << " from " << m_alignables[0] << ", for instance)" << std::endl;
00092   }
00093 }
00094 
00095 int CSCChamberFitter::index(std::string alignable) const {
00096   int i = 0;
00097   for (std::vector<std::string>::const_iterator a = m_alignables.begin();  a != m_alignables.end();  ++a) {
00098     if (*a == alignable) return i;
00099     i++;
00100   }
00101   return -1;
00102 }
00103 
00104 void CSCChamberFitter::walk(std::map<int,bool> &touched, int alignable) const {
00105   touched[alignable] = true;
00106 
00107   for (std::vector<CSCPairConstraint*>::const_iterator constraint = m_constraints.begin();  constraint != m_constraints.end();  ++constraint) {
00108     if (alignable == (*constraint)->i()  ||  alignable == (*constraint)->j()) {
00109       if (!touched[(*constraint)->i()]) walk(touched, (*constraint)->i());
00110       if (!touched[(*constraint)->j()]) walk(touched, (*constraint)->j());
00111     }
00112   }
00113 }
00114 
00115 long CSCChamberFitter::alignableId(std::string alignable) const {
00116   if (alignable.size() != 9) return -1;
00117 
00118   if (alignable[0] == 'M'  &&  alignable[1] == 'E') {
00119     int endcap = -1;
00120     if (alignable[2] == '+') endcap = 1;
00121     else if (alignable[2] == '-') endcap = 2;
00122 
00123     if (endcap != -1) {
00124       int station = -1;
00125       if (alignable[3] == '1') station = 1;
00126       else if (alignable[3] == '2') station = 2;
00127       else if (alignable[3] == '3') station = 3;
00128       else if (alignable[3] == '4') station = 4;
00129 
00130       if (alignable[4] == '/'  &&  station != -1) {
00131         int ring = -1;
00132         if (alignable[5] == '1') ring = 1;
00133         else if (alignable[5] == '2') ring = 2;
00134         else if (alignable[5] == '3') ring = 3;
00135         else if (alignable[5] == '4') ring = 4;
00136         if (station > 1  &&  ring > 2) return -1;
00137 
00138         if (alignable[6] == '/'  &&  ring != -1) {
00139           int chamber = -1;
00140           if      (alignable[7] == '0'  &&  alignable[8] == '1') chamber = 1;
00141           else if (alignable[7] == '0'  &&  alignable[8] == '2') chamber = 2;
00142           else if (alignable[7] == '0'  &&  alignable[8] == '3') chamber = 3;
00143           else if (alignable[7] == '0'  &&  alignable[8] == '4') chamber = 4;
00144           else if (alignable[7] == '0'  &&  alignable[8] == '5') chamber = 5;
00145           else if (alignable[7] == '0'  &&  alignable[8] == '6') chamber = 6;
00146           else if (alignable[7] == '0'  &&  alignable[8] == '7') chamber = 7;
00147           else if (alignable[7] == '0'  &&  alignable[8] == '8') chamber = 8;
00148           else if (alignable[7] == '0'  &&  alignable[8] == '9') chamber = 9;
00149           else if (alignable[7] == '1'  &&  alignable[8] == '0') chamber = 10;
00150           else if (alignable[7] == '1'  &&  alignable[8] == '1') chamber = 11;
00151           else if (alignable[7] == '1'  &&  alignable[8] == '2') chamber = 12;
00152           else if (alignable[7] == '1'  &&  alignable[8] == '3') chamber = 13;
00153           else if (alignable[7] == '1'  &&  alignable[8] == '4') chamber = 14;
00154           else if (alignable[7] == '1'  &&  alignable[8] == '5') chamber = 15;
00155           else if (alignable[7] == '1'  &&  alignable[8] == '6') chamber = 16;
00156           else if (alignable[7] == '1'  &&  alignable[8] == '7') chamber = 17;
00157           else if (alignable[7] == '1'  &&  alignable[8] == '8') chamber = 18;
00158           else if (alignable[7] == '1'  &&  alignable[8] == '9') chamber = 19;
00159           else if (alignable[7] == '2'  &&  alignable[8] == '0') chamber = 20;
00160           else if (alignable[7] == '2'  &&  alignable[8] == '1') chamber = 21;
00161           else if (alignable[7] == '2'  &&  alignable[8] == '2') chamber = 22;
00162           else if (alignable[7] == '2'  &&  alignable[8] == '3') chamber = 23;
00163           else if (alignable[7] == '2'  &&  alignable[8] == '4') chamber = 24;
00164           else if (alignable[7] == '2'  &&  alignable[8] == '5') chamber = 25;
00165           else if (alignable[7] == '2'  &&  alignable[8] == '6') chamber = 26;
00166           else if (alignable[7] == '2'  &&  alignable[8] == '7') chamber = 27;
00167           else if (alignable[7] == '2'  &&  alignable[8] == '8') chamber = 28;
00168           else if (alignable[7] == '2'  &&  alignable[8] == '9') chamber = 29;
00169           else if (alignable[7] == '3'  &&  alignable[8] == '0') chamber = 30;
00170           else if (alignable[7] == '3'  &&  alignable[8] == '1') chamber = 31;
00171           else if (alignable[7] == '3'  &&  alignable[8] == '2') chamber = 32;
00172           else if (alignable[7] == '3'  &&  alignable[8] == '3') chamber = 33;
00173           else if (alignable[7] == '3'  &&  alignable[8] == '4') chamber = 34;
00174           else if (alignable[7] == '3'  &&  alignable[8] == '5') chamber = 35;
00175           else if (alignable[7] == '3'  &&  alignable[8] == '6') chamber = 36;
00176 
00177           if (station > 1  &&  ring == 1  &&  chamber > 18) return -1;
00178 
00179           if (chamber != -1) {
00180             return CSCDetId(endcap, station, ring, chamber, 0).rawId();
00181           }
00182         }
00183       }
00184     }
00185   }
00186 
00187   return -1;
00188 }
00189 
00190 bool CSCChamberFitter::isFrame(int i) const {
00191   for (std::vector<int>::const_iterator frame = m_frames.begin();  frame != m_frames.end();  ++frame) {
00192     if (i == *frame) return true;
00193   }
00194   return false;
00195 }
00196 
00197 double CSCChamberFitter::chi2(AlgebraicVector A, double lambda) const {
00198   double sumFixed = 0.;
00199 
00200   if (m_fixed == -1) {
00201     for (unsigned int i = 0;  i < m_alignables.size();  i++) {
00202       if (!isFrame(i)) {
00203         sumFixed += A[i];
00204       }
00205     }
00206   }
00207   else {
00208     sumFixed = A[m_fixed];
00209   }
00210 
00211   double s = lambda * sumFixed*sumFixed;
00212   for (std::vector<CSCPairConstraint*>::const_iterator constraint = m_constraints.begin();  constraint != m_constraints.end();  ++constraint) {
00213      if ((*constraint)->valid()) {
00214         s += pow((*constraint)->value() - A[(*constraint)->i()] + A[(*constraint)->j()], 2)/(*constraint)->error()/(*constraint)->error();
00215      }
00216   }
00217   return s;
00218 }
00219 
00220 double CSCChamberFitter::lhsVector(int k) const {
00221   double s = 0.;
00222   for (std::vector<CSCPairConstraint*>::const_iterator constraint = m_constraints.begin();  constraint != m_constraints.end();  ++constraint) {
00223      if ((*constraint)->valid()) {
00224         double d = 2.*(*constraint)->value()/(*constraint)->error()/(*constraint)->error();
00225         if ((*constraint)->i() == k) s += d;
00226         if ((*constraint)->j() == k) s -= d;
00227      }
00228   }
00229   return s;
00230 }
00231 
00232 double CSCChamberFitter::hessian(int k, int l, double lambda) const {
00233   double s = 0.;
00234 
00235   if (m_fixed == -1) {
00236     if (!isFrame(k)  &&  !isFrame(l)) s += 2.*lambda;
00237   }
00238   else {
00239     if (k == l  &&  l == m_fixed) s += 2.*lambda;
00240   }
00241 
00242   for (std::vector<CSCPairConstraint*>::const_iterator constraint = m_constraints.begin();  constraint != m_constraints.end();  ++constraint) {
00243      double d = 2./infinity/infinity;
00244      if ((*constraint)->valid()) {
00245         d = 2./(*constraint)->error()/(*constraint)->error();
00246      }
00247 
00248      if (k == l  &&  ((*constraint)->i() == k  ||  (*constraint)->j() == k)) s += d;
00249      if (((*constraint)->i() == k  &&  (*constraint)->j() == l)  ||  ((*constraint)->j() == k  &&  (*constraint)->i() == l)) s -= d;
00250   }
00251   return s;
00252 }
00253 
00254 bool CSCChamberFitter::fit(std::vector<CSCAlignmentCorrections*> &corrections) const {
00255   double lambda = 1./infinity/infinity;
00256 
00257   AlgebraicVector A(m_alignables.size());
00258   AlgebraicVector V(m_alignables.size());
00259   AlgebraicMatrix M(m_alignables.size(), m_alignables.size());
00260 
00261   for (unsigned int k = 0;  k < m_alignables.size();  k++) {
00262     A[k] = 0.;
00263     V[k] = lhsVector(k);
00264     for (unsigned int l = 0;  l < m_alignables.size();  l++) {
00265       M[k][l] = hessian(k, l, lambda);
00266     }
00267   }
00268 
00269   double oldchi2 = chi2(A, lambda);
00270 
00271   int ierr;
00272   M.invert(ierr);
00273   if (ierr != 0) {
00274     edm::LogError("CSCOverlapsAlignmentAlgorithm") << "Matrix inversion failed for fitter " << m_name << " matrix is " << M << std::endl;
00275     return false;
00276   }
00277 
00278   A = M * V;  // that's the alignment step
00279 
00281   CSCAlignmentCorrections *correction = new CSCAlignmentCorrections(m_name, oldchi2, chi2(A, lambda));
00282 
00283   for (unsigned int i = 0;  i < m_alignables.size();  i++) {
00284     if (!isFrame(i)) {
00285       correction->insertCorrection(m_alignables[i], CSCDetId(alignableId(m_alignables[i])), A[i]);
00286     }
00287   }
00288 
00289   // we have to switch to a completely different linear algebrea
00290   // package because CLHEP doesn't compute
00291   // eigenvectors/diagonalization (?!?)
00292   TMatrixD tmatrix(m_alignables.size(), m_alignables.size());
00293   for (unsigned int i = 0;  i < m_alignables.size();  i++) {
00294     for (unsigned int j = 0;  j < m_alignables.size();  j++) {
00295       tmatrix[i][j] = M[i][j];
00296     }
00297   }
00298   TMatrixDEigen tmatrixdeigen(tmatrix); 
00299   TMatrixD basis = tmatrixdeigen.GetEigenVectors();
00300   TMatrixD invbasis = tmatrixdeigen.GetEigenVectors();
00301   invbasis.Invert();
00302   TMatrixD diagonalized = invbasis * (tmatrix * basis);
00303 
00304   for (unsigned int i = 0;  i < m_alignables.size();  i++) {
00305     std::vector<double> coefficient;
00306     std::vector<std::string> modename;
00307     std::vector<long> modeid;
00308     for (unsigned int j = 0;  j < m_alignables.size();  j++) {
00309       coefficient.push_back(invbasis[i][j]);
00310       modename.push_back(m_alignables[j]);
00311       modeid.push_back(alignableId(m_alignables[j]));
00312     }
00313 
00314     correction->insertMode(coefficient, modename, modeid, sqrt(2. * fabs(diagonalized[i][i])) * (diagonalized[i][i] >= 0. ? 1. : -1.));
00315   }
00316 
00317   for (std::vector<CSCPairConstraint*>::const_iterator constraint = m_constraints.begin();  constraint != m_constraints.end();  ++constraint) {
00318      if ((*constraint)->valid()) {
00319         double residual = (*constraint)->value() - A[(*constraint)->i()] + A[(*constraint)->j()];
00320         correction->insertResidual(m_alignables[(*constraint)->i()], m_alignables[(*constraint)->j()], (*constraint)->value(), (*constraint)->error(), residual, residual/(*constraint)->error());
00321      }
00322   }
00323 
00324   corrections.push_back(correction);
00325   return true;
00326 }
00327 
00328 void CSCChamberFitter::radiusCorrection(AlignableNavigator *alignableNavigator, AlignmentParameterStore *alignmentParameterStore, bool combineME11) const {
00329    double sum_phipos_residuals = 0.;
00330    double num_valid = 0.;
00331    double sum_radius = 0.;
00332    double num_total = 0.;
00333    for (std::vector<CSCPairConstraint*>::const_iterator constraint = m_constraints.begin();  constraint != m_constraints.end();  ++constraint) {
00334       CSCPairResidualsConstraint *residualsConstraint = dynamic_cast<CSCPairResidualsConstraint*>(*constraint);
00335       if (residualsConstraint != NULL) {
00336 
00337          if (residualsConstraint->valid()) {
00338             sum_phipos_residuals += residualsConstraint->value();
00339             num_valid += 1.;
00340          }
00341 
00342          sum_radius += residualsConstraint->radius(true);
00343          num_total += 1.;
00344       }
00345    }
00346    if (num_valid == 0.  ||  num_total == 0.) return;
00347    double average_phi_residual = sum_phipos_residuals / num_valid;
00348    double average_radius = sum_radius / num_total;
00349 
00350    double radial_correction = average_phi_residual * average_radius * num_total / (2.*M_PI);
00351 
00352    for (std::vector<CSCPairConstraint*>::const_iterator constraint = m_constraints.begin();  constraint != m_constraints.end();  ++constraint) {
00353       CSCPairResidualsConstraint *residualsConstraint = dynamic_cast<CSCPairResidualsConstraint*>(*constraint);
00354       if (residualsConstraint != NULL) {
00355 
00356          const DetId id(residualsConstraint->id_i());
00357          Alignable *alignable = alignableNavigator->alignableFromDetId(id).alignable();
00358          Alignable *also = NULL;
00359          if (combineME11  &&  residualsConstraint->id_i().station() == 1  &&  residualsConstraint->id_i().ring() == 1) {
00360             CSCDetId alsoid(residualsConstraint->id_i().endcap(), 1, 4, residualsConstraint->id_i().chamber(), 0);
00361             const DetId alsoid2(alsoid);
00362             also = alignableNavigator->alignableFromDetId(alsoid2).alignable();
00363          }
00364       
00365          AlgebraicVector params(6);
00366          AlgebraicSymMatrix cov(6);
00367 
00368          params[1] = radial_correction;
00369          cov[1][1] = 1e-6;
00370 
00371          AlignmentParameters *parnew = alignable->alignmentParameters()->cloneFromSelected(params, cov);
00372          alignable->setAlignmentParameters(parnew);
00373          alignmentParameterStore->applyParameters(alignable);
00374          alignable->alignmentParameters()->setValid(true);
00375          if (also != NULL) {
00376             AlignmentParameters *parnew2 = also->alignmentParameters()->cloneFromSelected(params, cov);
00377             also->setAlignmentParameters(parnew2);
00378             alignmentParameterStore->applyParameters(also);
00379             also->alignmentParameters()->setValid(true);
00380          }
00381       }
00382    }
00383 }