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();
00037 else if (pedeResultFile.find_last_of('/') != pedeResultFile.size() - 1) {
00038 pedeResultFile += '/';
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);
00054 bool isAllOk = true;
00055
00056 std::map<Alignable*,Alignable*> uniqueList;
00057
00058 edm::LogInfo("Alignment") << "@SUB=PedeReader::read"
00059 << "will read parameters for run range "
00060 << myRunRange.first << " - " << myRunRange.second;
00061
00062
00063 unsigned int nParam = 0;
00064 while (myPedeResult.good() && !myPedeResult.eof()) {
00065
00066 unsigned int paramLabel = 0;
00067 if (!this->readIfSameLine<unsigned int>(myPedeResult, paramLabel)) continue;
00068
00069
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;
00082 continue;
00083 }
00084 uniqueList[alignable] = alignable;
00085 ++nParam;
00086 }
00087
00088
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;
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;
00114 case '\n':
00115 return false;
00116 default:
00117 aStream.unget();
00118 aStream >> outValue;
00119 if (aStream.fail()) {
00120 aStream.clear();
00121 while (aStream.good() && aStream.get() != '\n');
00122 return false;
00123 } else {
00124 return true;
00125 }
00126 }
00127 }
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 =
00143 (setUserVars ? static_cast<MillePedeVariables*>(params->userVariables()) : 0);
00144
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:
00158 if (userParams) userParams->globalCor()[paramNum] = buf[4];
00159 case 4:
00160 if (userParams) userParams->sigma()[paramNum] = buf[3] / cmsToPede;
00161 covMat[paramNum][paramNum] = buf[3]*buf[3] / (cmsToPede*cmsToPede);
00162
00163 case 3:
00164 if (userParams) userParams->diffBefore()[paramNum] = buf[2] / cmsToPede;
00165
00166 case 2:
00167 params->setValid(true);
00168 parVec[paramNum] = buf[0] / cmsToPede * mySteerer.parameterSign();
00169 if (userParams) {
00170 userParams->parameter()[paramNum] = parVec[paramNum];
00171 userParams->preSigma()[paramNum] = buf[1];
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));
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
00210 AlignmentParameters *params = alignable->alignmentParameters();
00211 if (!params) {
00212 throw cms::Exception("BadConfig") << "PedeReader::checkAliParams"
00213 << "Alignable without parameters.";
00214
00215 }
00216
00217
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 }