CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/Alignment/MillePedeAlignmentAlgorithm/src/PedeReader.cc

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