CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/Alignment/MillePedeAlignmentAlgorithm/src/PedeReader.cc

Go to the documentation of this file.
00001 
00011 #include "PedeReader.h"
00012 #include "PedeSteerer.h"
00013 #include "PedeLabeler.h"
00014 
00015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 
00018 #include "Alignment/CommonAlignment/interface/Alignable.h"
00019 #include "Alignment/CommonAlignment/interface/AlignmentParameters.h"
00020 
00021 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00022 
00023 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeVariables.h"
00024 
00025 #include <map>
00026 #include <string>
00027 
00028 
00029 const unsigned int PedeReader::myMaxNumValPerParam = 5;
00030 
00031 //__________________________________________________________________________________________________
00032 PedeReader::PedeReader(const edm::ParameterSet &config, const PedeSteerer &steerer,
00033                        const PedeLabeler &labels) 
00034   : mySteerer(steerer), myLabels(labels)
00035 {
00036   std::string pedeResultFile(config.getUntrackedParameter<std::string>("fileDir"));
00037   if (pedeResultFile.empty()) pedeResultFile = steerer.directory(); // includes final '/'
00038   else if (pedeResultFile.find_last_of('/') != pedeResultFile.size() - 1) {
00039     pedeResultFile += '/'; // directory may need '/'
00040   }
00041 
00042   pedeResultFile += config.getParameter<std::string>("readFile");
00043   myPedeResult.open(pedeResultFile.c_str(), std::ios::in);
00044   if (!myPedeResult.is_open()) {
00045     edm::LogError("Alignment") << "@SUB=PedeReader"
00046                                << "Problem opening pede output file " << pedeResultFile;
00047   }
00048 }
00049 
00050 //__________________________________________________________________________________________________
00051 bool PedeReader::read(std::vector<Alignable*> &alignables, bool setUserVars)
00052 {
00053   alignables.clear();
00054   myPedeResult.seekg(0, std::ios::beg); // back to start
00055   bool isAllOk = true;
00056 
00057   std::map<Alignable*,Alignable*> uniqueList; // Probably should use a std::set here...
00058   
00059   // loop on lines of text file
00060   unsigned int nParam = 0;
00061   while (myPedeResult.good() && !myPedeResult.eof()) {
00062     // read label
00063     unsigned int paramLabel = 0;
00064     if (!this->readIfSameLine<unsigned int>(myPedeResult, paramLabel)) continue; // empty line?
00065 
00066     // read up to maximal number of pede result per parameter
00067     float buffer[myMaxNumValPerParam] = {0.};
00068     unsigned int bufferPos = 0;
00069     for ( ; bufferPos < myMaxNumValPerParam; ++bufferPos) {
00070       if (!this->readIfSameLine<float>(myPedeResult, buffer[bufferPos])) break;
00071     }
00072 
00073     Alignable *alignable = this->setParameter(paramLabel, bufferPos, buffer, setUserVars);
00074     if (!alignable) {
00075       isAllOk = false;  // or error?
00076       continue;
00077     }
00078     uniqueList[alignable] = alignable;
00079     ++nParam;
00080   }
00081 
00082   // add Alignables to output
00083   for ( std::map<Alignable*,Alignable*>::const_iterator iAli = uniqueList.begin();
00084         iAli != uniqueList.end(); ++iAli) {
00085     alignables.push_back((*iAli).first);
00086   }
00087 
00088   edm::LogInfo("Alignment") << "@SUB=PedeReader::read" << nParam << " parameters for "
00089                             << alignables.size() << " alignables";
00090 
00091   return isAllOk && nParam; // nParam == 0: empty or bad file
00092 }
00093 
00094 
00095 //__________________________________________________________________________________________________
00096 template<class T> 
00097 bool PedeReader::readIfSameLine(std::ifstream &aStream, T &outValue) const
00098 {
00099 
00100   while (true) {
00101     const int aChar = aStream.get();
00102     if (!aStream.good()) return false;
00103 
00104     switch(aChar) {
00105     case ' ':
00106     case '\t':
00107       continue; // to next character
00108     case '\n':
00109       return false; // end of line
00110     default:
00111       aStream.unget();
00112       aStream >> outValue;
00113       if (aStream.fail()) {// not correct type 'T' (!aStream.good() is true also in case of EOF)
00114         aStream.clear();
00115         while (aStream.good() && aStream.get() != '\n'); // forward to end of line
00116         return false; 
00117       } else {
00118         return true;
00119       }
00120     } // switch
00121   } // while
00122 
00123   edm::LogError("Alignment") << "@SUB=PedeReader::readIfSameLine" << "Should never come here!";
00124   return false;
00125 }
00126 
00127 //__________________________________________________________________________________________________
00128 Alignable* PedeReader::setParameter(unsigned int paramLabel,
00129                                     unsigned int bufLength, float *buf, bool setUserVars) const
00130 {
00131   Alignable *alignable = myLabels.alignableFromLabel(paramLabel);
00132   const unsigned int paramNum = myLabels.paramNumFromLabel(paramLabel);
00133   const double cmsToPede = mySteerer.cmsToPedeFactor(paramNum);
00134   if (alignable) {
00135     AlignmentParameters *params = this->checkAliParams(alignable, setUserVars);
00136     MillePedeVariables *userParams = // static cast ensured by previous checkAliParams
00137       (setUserVars ? static_cast<MillePedeVariables*>(params->userVariables()) : 0);
00138     if (userParams && userParams->label() != myLabels.alignableLabelFromLabel(paramLabel)) {
00139       edm::LogError("Alignment") << "@SUB=PedeReader::setParameter" 
00140                                  << "Label mismatch: paramLabel " << paramLabel 
00141                                  << " for alignableLabel " << userParams->label();
00142     }
00143 
00144     AlgebraicVector parVec(params->parameters());
00145     AlgebraicSymMatrix covMat(params->covariance());
00146 
00147     if (userParams) userParams->setAllDefault(paramNum);
00148 
00149     switch (bufLength) {
00150     case 5: // global correlation
00151       if (userParams) userParams->globalCor()[paramNum] = buf[4]; // no break
00152     case 4: // uncertainty
00153       if (userParams) userParams->sigma()[paramNum] = buf[3] / cmsToPede;
00154       covMat[paramNum][paramNum] = buf[3]*buf[3] / (cmsToPede*cmsToPede);
00155       // no break;
00156     case 3: // difference to start value
00157       if (userParams) userParams->diffBefore()[paramNum] = buf[2] / cmsToPede;
00158       // no break
00159     case 2: 
00160       params->setValid(true);
00161       parVec[paramNum] = buf[0] / cmsToPede * mySteerer.parameterSign(); // parameter
00162       if (userParams) {
00163         userParams->parameter()[paramNum] = parVec[paramNum]; // duplicate in millepede parameters
00164         userParams->preSigma()[paramNum] = buf[1];  // presigma given, probably means fixed
00165         if (!userParams->isFixed(paramNum)) {
00166           userParams->preSigma()[paramNum] /= cmsToPede;
00167           if (bufLength == 2) {
00168             edm::LogWarning("Alignment") << "@SUB=PedeReader::setParameter"
00169                                          << "Param " << paramLabel << " (from "
00170                                          << typeid(*alignable).name() << ") without result!";
00171             userParams->isValid()[paramNum] = false;
00172             params->setValid(false);
00173           }
00174         }
00175       }
00176       break;
00177     case 0:
00178     case 1:
00179     default:
00180       edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00181                                  << "Expect 2 to 5 values, got " << bufLength 
00182                                  << " for label " << paramLabel;
00183       break;
00184     }
00185     alignable->setAlignmentParameters(params->clone(parVec, covMat));//transferred mem. responsib.
00186   } else {
00187     unsigned int lasBeamId = myLabels.lasBeamIdFromLabel(paramLabel);
00188     edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00189                                << "No alignable for paramLabel " << paramLabel
00190                                << ", probably LasBeam with Id " << lasBeamId
00191                                << ",\nparam " << paramNum << ": " 
00192                                << buf[0] / cmsToPede * mySteerer.parameterSign()
00193                                << " += " << (bufLength >= 4 ? buf[3] / cmsToPede : -99.);
00194   }
00195 
00196   return alignable;
00197 }
00198 
00199 //__________________________________________________________________________________________________
00200 AlignmentParameters* PedeReader::checkAliParams(Alignable *alignable, bool createUserVars) const
00201 {
00202   // first check that we have parameters
00203   AlignmentParameters *params = alignable->alignmentParameters();
00204   if (!params) {
00205     throw cms::Exception("BadConfig") << "PedeReader::checkAliParams"
00206                                       << "Alignable without parameters.";
00207 
00208   }
00209   
00210   // now check that we have user parameters of correct type if requested:
00211   if (createUserVars && !dynamic_cast<MillePedeVariables*>(params->userVariables())) {
00212     edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
00213                               << "Add user variables for alignable with label " 
00214                               << myLabels.alignableLabel(alignable);
00215     params->setUserVariables(new MillePedeVariables(params->size(), myLabels.alignableLabel(alignable)));
00216   }
00217   
00218   return params;
00219 }