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/CommonAlignmentAlgorithm/interface/IntegratedCalibrationBase.h"
00021
00022 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00023
00024 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeVariables.h"
00025
00026 #include <set>
00027 #include <string>
00028 #include <sstream>
00029
00030 const unsigned int PedeReader::myMaxNumValPerParam = 5;
00031
00032
00033 PedeReader::PedeReader(const edm::ParameterSet &config, const PedeSteerer &steerer,
00034 const PedeLabelerBase &labels, const RunRange &runrange)
00035 : mySteerer(steerer), myLabels(labels), myRunRange(runrange)
00036 {
00037 std::string pedeResultFile(config.getUntrackedParameter<std::string>("fileDir"));
00038 if (pedeResultFile.empty()) pedeResultFile = steerer.directory();
00039 else if (pedeResultFile.find_last_of('/') != pedeResultFile.size() - 1) {
00040 pedeResultFile += '/';
00041 }
00042
00043 pedeResultFile += config.getParameter<std::string>("readFile");
00044 myPedeResult.open(pedeResultFile.c_str(), std::ios::in);
00045 if (!myPedeResult.is_open()) {
00046 edm::LogError("Alignment") << "@SUB=PedeReader"
00047 << "Problem opening pede output file " << pedeResultFile;
00048 }
00049 }
00050
00051
00052 bool PedeReader::read(std::vector<Alignable*> &alignables, bool setUserVars)
00053 {
00054 alignables.clear();
00055 myPedeResult.seekg(0, std::ios::beg);
00056 bool isAllOk = true;
00057
00058 std::set<Alignable*> uniqueList;
00059
00060 edm::LogInfo("Alignment") << "@SUB=PedeReader::read"
00061 << "will read parameters for run range "
00062 << myRunRange.first << " - " << myRunRange.second;
00063
00064
00065 unsigned int nParam = 0, nParamCalib = 0, nParamUnknown = 0;
00066 while (myPedeResult.good() && !myPedeResult.eof()) {
00067
00068 unsigned int paramLabel = 0;
00069 if (!this->readIfSameLine<unsigned int>(myPedeResult, paramLabel)) continue;
00070
00071
00072 float buffer[myMaxNumValPerParam] = {0.};
00073 unsigned int bufferPos = 0;
00074 for ( ; bufferPos < myMaxNumValPerParam; ++bufferPos) {
00075 if (!this->readIfSameLine<float>(myPedeResult, buffer[bufferPos])) break;
00076 }
00077
00078
00079
00080
00081 std::pair<IntegratedCalibrationBase*, unsigned int> calibParam
00082 = myLabels.calibrationParamFromLabel(paramLabel);
00083 if (calibParam.first) {
00084 if (this->setCalibrationParameter(calibParam.first, calibParam.second, bufferPos, buffer)) {
00085 ++nParamCalib;
00086 } else {
00087 edm::LogError("Alignment") << "@SUB=PedeReader::read" << "Problems setting results of "
00088 << "parameter " << calibParam.second << " to calibration '"
00089 << calibParam.first->name() << "' ("<< calibParam.first << ").";
00090 isAllOk = false;
00091 }
00092 continue;
00093 }
00094
00095 const RunRange & runRange = myLabels.runRangeFromLabel(paramLabel);
00096 if (!(runRange.first<=myRunRange.first && myRunRange.second<=runRange.second)) continue;
00097
00098 Alignable *alignable = this->setParameter(paramLabel, bufferPos, buffer, setUserVars);
00099 if (!alignable) {
00100
00101 ++nParamUnknown;
00102 continue;
00103 }
00104 uniqueList.insert(alignable);
00105 ++nParam;
00106 }
00107
00108
00109 alignables.insert(alignables.end(), uniqueList.begin(), uniqueList.end());
00110
00111 std::stringstream out;
00112 out << nParam << " parameters for " << alignables.size() << " alignables and " << nParamCalib
00113 << " for calibrations, " << nParamUnknown << " parameters are unknown.\n";
00114 if (nParamUnknown) {
00115 edm::LogWarning("Alignment") << "@SUB=PedeReader::read" << out.str();
00116 } else {
00117 edm::LogInfo("Alignment") << "@SUB=PedeReader::read" << out.str();
00118 }
00119
00120 return isAllOk && (nParam + nParamCalib);
00121 }
00122
00123
00124
00125 template<class T>
00126 bool PedeReader::readIfSameLine(std::ifstream &aStream, T &outValue) const
00127 {
00128
00129 while (true) {
00130 const int aChar = aStream.get();
00131 if (!aStream.good()) return false;
00132
00133 switch(aChar) {
00134 case ' ':
00135 case '\t':
00136 continue;
00137 case '\n':
00138 return false;
00139 default:
00140 aStream.unget();
00141 aStream >> outValue;
00142 if (aStream.fail()) {
00143 aStream.clear();
00144 while (aStream.good() && aStream.get() != '\n');
00145 return false;
00146 } else {
00147 return true;
00148 }
00149 }
00150 }
00151
00152 edm::LogError("Alignment") << "@SUB=PedeReader::readIfSameLine" << "Should never come here!";
00153 return false;
00154 }
00155
00156
00157 Alignable* PedeReader::setParameter(unsigned int paramLabel,
00158 unsigned int bufLength, const float *buf,
00159 bool setUserVars) const
00160 {
00161 Alignable *alignable = myLabels.alignableFromLabel(paramLabel);
00162 const unsigned int paramNum = myLabels.paramNumFromLabel(paramLabel);
00163 const double cmsToPede = mySteerer.cmsToPedeFactor(paramNum);
00164 if (alignable) {
00165 AlignmentParameters *params = this->checkAliParams(alignable, setUserVars);
00166 MillePedeVariables *userParams =
00167 (setUserVars ? static_cast<MillePedeVariables*>(params->userVariables()) : 0);
00168
00169 if (userParams && userParams->label() != myLabels.alignableLabel(alignable)) {
00170 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00171 << "Label mismatch: paramLabel " << paramLabel
00172 << " for alignableLabel " << userParams->label();
00173 }
00174
00175 AlgebraicVector parVec(params->parameters());
00176 AlgebraicSymMatrix covMat(params->covariance());
00177
00178 if (userParams) userParams->setAllDefault(paramNum);
00179
00180 switch (bufLength) {
00181 case 5:
00182 if (userParams) userParams->globalCor()[paramNum] = buf[4];
00183 case 4:
00184 if (userParams) userParams->sigma()[paramNum] = buf[3] / cmsToPede;
00185 covMat[paramNum][paramNum] = buf[3]*buf[3] / (cmsToPede*cmsToPede);
00186
00187 case 3:
00188 if (userParams) userParams->diffBefore()[paramNum] = buf[2] / cmsToPede;
00189
00190 case 2:
00191 params->setValid(true);
00192 parVec[paramNum] = buf[0] / cmsToPede * mySteerer.parameterSign();
00193 if (userParams) {
00194 userParams->parameter()[paramNum] = parVec[paramNum];
00195 userParams->preSigma()[paramNum] = buf[1];
00196 if (!userParams->isFixed(paramNum)) {
00197 userParams->preSigma()[paramNum] /= cmsToPede;
00198 if (bufLength == 2) {
00199 edm::LogWarning("Alignment") << "@SUB=PedeReader::setParameter"
00200 << "Param " << paramLabel << " (from "
00201 << typeid(*alignable).name() << ") without result!";
00202 userParams->isValid()[paramNum] = false;
00203 params->setValid(false);
00204 }
00205 }
00206 }
00207 break;
00208 case 0:
00209 case 1:
00210 default:
00211 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00212 << "Expect 2 to 5 values, got " << bufLength
00213 << " for label " << paramLabel;
00214 break;
00215 }
00216 alignable->setAlignmentParameters(params->clone(parVec, covMat));
00217 } else {
00218 unsigned int lasBeamId = myLabels.lasBeamIdFromLabel(paramLabel);
00219 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00220 << "No alignable for paramLabel " << paramLabel
00221 << ", probably LasBeam with Id " << lasBeamId
00222 << ",\nparam " << paramNum << ": "
00223 << buf[0] / cmsToPede * mySteerer.parameterSign()
00224 << " += " << (bufLength >= 4 ? buf[3] / cmsToPede : -99.);
00225 }
00226
00227 return alignable;
00228 }
00229
00230
00231 bool PedeReader::setCalibrationParameter(IntegratedCalibrationBase* calib, unsigned int paramNum,
00232 unsigned int bufLength, const float *buf) const
00233 {
00234 if (!calib || !buf) return false;
00235
00236
00237
00238 switch (bufLength) {
00239 case 5:
00240 case 4:
00241 calib->setParameterError(paramNum, buf[3]);
00242 case 3:
00243 case 2:
00244 if (bufLength == 2 && buf[1] >= 0.) {
00245 edm::LogWarning("Alignment") << "@SUB=PedeReader::setCalibrationParameter"
00246 << "Param " << paramNum << " of calibration '"
00247 << calib->name() << "' without result!";
00248 }
00249 return calib->setParameter(paramNum, buf[0] * mySteerer.parameterSign());
00250 case 0:
00251 case 1:
00252 default:
00253 edm::LogError("Alignment") << "@SUB=PedeReader::setCalibrationParameter"
00254 << "Expect 2 to 5 values, got " << bufLength << ".";
00255 return false;
00256 }
00257
00258 }
00259
00260
00261 AlignmentParameters* PedeReader::checkAliParams(Alignable *alignable, bool createUserVars) const
00262 {
00263
00264 AlignmentParameters *params = alignable->alignmentParameters();
00265 if (!params) {
00266 throw cms::Exception("BadConfig") << "PedeReader::checkAliParams: "
00267 << "Alignable without parameters.";
00268
00269 }
00270
00271
00272 if (createUserVars && !dynamic_cast<MillePedeVariables*>(params->userVariables())) {
00273 edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
00274 << "Add user variables for alignable with label "
00275 << myLabels.alignableLabel(alignable);
00276 params->setUserVariables(new MillePedeVariables(params->size(), myLabels.alignableLabel(alignable)));
00277 }
00278
00279 return params;
00280 }