CMS 3D CMS Logo

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   if (alignable) {
00133     AlignmentParameters *params = this->checkAliParams(alignable, setUserVars);
00134     MillePedeVariables *userParams = // static cast ensured by previous checkAliParams
00135       (setUserVars ? static_cast<MillePedeVariables*>(params->userVariables()) : 0);
00136     if (userParams) userParams->setLabel(myLabels.alignableLabelFromLabel(paramLabel));
00137 
00138     AlgebraicVector parVec(params->parameters());
00139     AlgebraicSymMatrix covMat(params->covariance());
00140     const unsigned int paramNum = myLabels.paramNumFromLabel(paramLabel);
00141 
00142     if (userParams) userParams->setAllDefault(paramNum);
00143     const double cmsToPede = mySteerer.cmsToPedeFactor(paramNum);
00144 
00145     switch (bufLength) {
00146     case 5: // global correlation
00147       if (userParams) userParams->globalCor()[paramNum] = buf[4]; // no break
00148     case 4: // uncertainty
00149       if (userParams) userParams->sigma()[paramNum] = buf[3] / cmsToPede;
00150       covMat[paramNum][paramNum] = buf[3]*buf[3] / (cmsToPede*cmsToPede);
00151       // no break;
00152     case 3: // difference to start value
00153       if (userParams) userParams->diffBefore()[paramNum] = buf[2] / cmsToPede;
00154       // no break
00155     case 2: 
00156       parVec[paramNum] = buf[0] / cmsToPede * mySteerer.parameterSign(); // parameter
00157       if (userParams) {
00158         userParams->parameter()[paramNum] = parVec[paramNum]; // duplicate in millepede parameters
00159         userParams->preSigma()[paramNum] = buf[1];  // presigma given, probably means fixed
00160         if (!userParams->isFixed(paramNum)) {
00161           userParams->preSigma()[paramNum] /= cmsToPede;
00162           if (bufLength == 2) {
00163             edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00164                                        << "Param " << paramLabel << " (from "
00165                                        << typeid(*alignable).name() << ") without result!";
00166             userParams->isValid()[paramNum] = false;
00167           }
00168         }
00169       }
00170       break;
00171     case 0:
00172     case 1:
00173     default:
00174       edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00175                                  << "Expect 2 to 5 values, got " << bufLength 
00176                                  << " for label " << paramLabel;
00177       break;
00178     }
00179     alignable->setAlignmentParameters(params->clone(parVec, covMat));//transferred mem. responsib.
00180   }
00181   return alignable;
00182 }
00183 
00184 //__________________________________________________________________________________________________
00185 AlignmentParameters* PedeReader::checkAliParams(Alignable *alignable, bool createUserVars) const
00186 {
00187   // first check that we have parameters
00188   AlignmentParameters *params = alignable->alignmentParameters();
00189   if (!params) {
00190     // How to check in future what kind of parameters are needed?
00191     params = new RigidBodyAlignmentParameters(alignable, false);
00192 
00193     edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
00194                               << "Build RigidBodyAlignmentParameters for alignable with label "
00195                               << myLabels.alignableLabel(alignable);
00196     alignable->setAlignmentParameters(params); // transferred memory responsibility
00197   }
00198   
00199   // now check that we have user parameters of correct type if requested:
00200   if (createUserVars && !dynamic_cast<MillePedeVariables*>(params->userVariables())) {
00201     edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
00202                               << "Add user variables for alignable with label " 
00203                               << myLabels.alignableLabel(alignable);
00204     params->setUserVariables(new MillePedeVariables(params->size()));
00205   }
00206   
00207   return params;
00208 }

Generated on Tue Jun 9 17:24:11 2009 for CMSSW by  doxygen 1.5.4