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 <map>
00027 #include <string>
00028
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::map<Alignable*,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;
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 isAllOk = false;
00101 continue;
00102 }
00103 uniqueList[alignable] = alignable;
00104 ++nParam;
00105 }
00106
00107
00108 for ( std::map<Alignable*,Alignable*>::const_iterator iAli = uniqueList.begin();
00109 iAli != uniqueList.end(); ++iAli) {
00110 alignables.push_back((*iAli).first);
00111 }
00112
00113 edm::LogInfo("Alignment") << "@SUB=PedeReader::read" << nParam << " parameters for "
00114 << alignables.size() << " alignables and " << nParamCalib
00115 << " for calibrations.";
00116
00117 return isAllOk && (nParam + nParamCalib);
00118 }
00119
00120
00121
00122 template<class T>
00123 bool PedeReader::readIfSameLine(std::ifstream &aStream, T &outValue) const
00124 {
00125
00126 while (true) {
00127 const int aChar = aStream.get();
00128 if (!aStream.good()) return false;
00129
00130 switch(aChar) {
00131 case ' ':
00132 case '\t':
00133 continue;
00134 case '\n':
00135 return false;
00136 default:
00137 aStream.unget();
00138 aStream >> outValue;
00139 if (aStream.fail()) {
00140 aStream.clear();
00141 while (aStream.good() && aStream.get() != '\n');
00142 return false;
00143 } else {
00144 return true;
00145 }
00146 }
00147 }
00148
00149 edm::LogError("Alignment") << "@SUB=PedeReader::readIfSameLine" << "Should never come here!";
00150 return false;
00151 }
00152
00153
00154 Alignable* PedeReader::setParameter(unsigned int paramLabel,
00155 unsigned int bufLength, const float *buf,
00156 bool setUserVars) const
00157 {
00158 Alignable *alignable = myLabels.alignableFromLabel(paramLabel);
00159 const unsigned int paramNum = myLabels.paramNumFromLabel(paramLabel);
00160 const double cmsToPede = mySteerer.cmsToPedeFactor(paramNum);
00161 if (alignable) {
00162 AlignmentParameters *params = this->checkAliParams(alignable, setUserVars);
00163 MillePedeVariables *userParams =
00164 (setUserVars ? static_cast<MillePedeVariables*>(params->userVariables()) : 0);
00165
00166 if (userParams && userParams->label() != myLabels.alignableLabel(alignable)) {
00167 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00168 << "Label mismatch: paramLabel " << paramLabel
00169 << " for alignableLabel " << userParams->label();
00170 }
00171
00172 AlgebraicVector parVec(params->parameters());
00173 AlgebraicSymMatrix covMat(params->covariance());
00174
00175 if (userParams) userParams->setAllDefault(paramNum);
00176
00177 switch (bufLength) {
00178 case 5:
00179 if (userParams) userParams->globalCor()[paramNum] = buf[4];
00180 case 4:
00181 if (userParams) userParams->sigma()[paramNum] = buf[3] / cmsToPede;
00182 covMat[paramNum][paramNum] = buf[3]*buf[3] / (cmsToPede*cmsToPede);
00183
00184 case 3:
00185 if (userParams) userParams->diffBefore()[paramNum] = buf[2] / cmsToPede;
00186
00187 case 2:
00188 params->setValid(true);
00189 parVec[paramNum] = buf[0] / cmsToPede * mySteerer.parameterSign();
00190 if (userParams) {
00191 userParams->parameter()[paramNum] = parVec[paramNum];
00192 userParams->preSigma()[paramNum] = buf[1];
00193 if (!userParams->isFixed(paramNum)) {
00194 userParams->preSigma()[paramNum] /= cmsToPede;
00195 if (bufLength == 2) {
00196 edm::LogWarning("Alignment") << "@SUB=PedeReader::setParameter"
00197 << "Param " << paramLabel << " (from "
00198 << typeid(*alignable).name() << ") without result!";
00199 userParams->isValid()[paramNum] = false;
00200 params->setValid(false);
00201 }
00202 }
00203 }
00204 break;
00205 case 0:
00206 case 1:
00207 default:
00208 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00209 << "Expect 2 to 5 values, got " << bufLength
00210 << " for label " << paramLabel;
00211 break;
00212 }
00213 alignable->setAlignmentParameters(params->clone(parVec, covMat));
00214 } else {
00215 unsigned int lasBeamId = myLabels.lasBeamIdFromLabel(paramLabel);
00216 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00217 << "No alignable for paramLabel " << paramLabel
00218 << ", probably LasBeam with Id " << lasBeamId
00219 << ",\nparam " << paramNum << ": "
00220 << buf[0] / cmsToPede * mySteerer.parameterSign()
00221 << " += " << (bufLength >= 4 ? buf[3] / cmsToPede : -99.);
00222 }
00223
00224 return alignable;
00225 }
00226
00227
00228 bool PedeReader::setCalibrationParameter(IntegratedCalibrationBase* calib, unsigned int paramNum,
00229 unsigned int bufLength, const float *buf) const
00230 {
00231 if (!calib || !buf) return false;
00232
00233
00234
00235 switch (bufLength) {
00236 case 5:
00237 case 4:
00238 calib->setParameterError(paramNum, buf[3]);
00239 case 3:
00240 case 2:
00241 if (bufLength == 2 && buf[1] >= 0.) {
00242 edm::LogWarning("Alignment") << "@SUB=PedeReader::setCalibrationParameter"
00243 << "Param " << paramNum << " of calibration '"
00244 << calib->name() << "' without result!";
00245 }
00246 return calib->setParameter(paramNum, buf[0] * mySteerer.parameterSign());
00247 case 0:
00248 case 1:
00249 default:
00250 edm::LogError("Alignment") << "@SUB=PedeReader::setCalibrationParameter"
00251 << "Expect 2 to 5 values, got " << bufLength << ".";
00252 return false;
00253 }
00254
00255 }
00256
00257
00258 AlignmentParameters* PedeReader::checkAliParams(Alignable *alignable, bool createUserVars) const
00259 {
00260
00261 AlignmentParameters *params = alignable->alignmentParameters();
00262 if (!params) {
00263 throw cms::Exception("BadConfig") << "PedeReader::checkAliParams: "
00264 << "Alignable without parameters.";
00265
00266 }
00267
00268
00269 if (createUserVars && !dynamic_cast<MillePedeVariables*>(params->userVariables())) {
00270 edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
00271 << "Add user variables for alignable with label "
00272 << myLabels.alignableLabel(alignable);
00273 params->setUserVariables(new MillePedeVariables(params->size(), myLabels.alignableLabel(alignable)));
00274 }
00275
00276 return params;
00277 }