File indexing completed on 2024-04-06 11:56:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "PedeReader.h"
0012 #include "PedeSteerer.h"
0013
0014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016
0017 #include "Alignment/CommonAlignment/interface/Alignable.h"
0018 #include "Alignment/CommonAlignment/interface/AlignmentParameters.h"
0019
0020 #include "Alignment/CommonAlignmentAlgorithm/interface/IntegratedCalibrationBase.h"
0021
0022 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
0023
0024 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeVariables.h"
0025
0026 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
0027
0028 #include <set>
0029 #include <string>
0030 #include <sstream>
0031
0032 const unsigned int PedeReader::myMaxNumValPerParam = 5;
0033
0034
0035 PedeReader::PedeReader(const edm::ParameterSet &config,
0036 const PedeSteerer &steerer,
0037 const PedeLabelerBase &labels,
0038 const RunRange &runrange)
0039 : mySteerer(steerer), myLabels(labels), myRunRange(runrange) {
0040 std::string pedeResultFile(config.getUntrackedParameter<std::string>("fileDir"));
0041 if (pedeResultFile.empty())
0042 pedeResultFile = steerer.directory();
0043 else if (pedeResultFile.find_last_of('/') != pedeResultFile.size() - 1) {
0044 pedeResultFile += '/';
0045 }
0046
0047 pedeResultFile += config.getParameter<std::string>("readFile");
0048 myPedeResult.open(pedeResultFile.c_str(), std::ios::in);
0049 if (!myPedeResult.is_open()) {
0050 edm::LogError("Alignment") << "@SUB=PedeReader"
0051 << "Problem opening pede output file " << pedeResultFile;
0052 }
0053 }
0054
0055
0056 bool PedeReader::read(align::Alignables &alignables, bool setUserVars) {
0057 alignables.clear();
0058 myPedeResult.seekg(0, std::ios::beg);
0059 bool isAllOk = true;
0060
0061 std::set<Alignable *> uniqueList;
0062
0063 edm::LogInfo("Alignment") << "@SUB=PedeReader::read"
0064 << "will read parameters for run range " << myRunRange.first << " - " << myRunRange.second;
0065
0066
0067 unsigned int nParam = 0, nParamCalib = 0, nParamUnknown = 0;
0068 while (myPedeResult.good() && !myPedeResult.eof()) {
0069
0070 unsigned int paramLabel = 0;
0071 if (!this->readIfSameLine<unsigned int>(myPedeResult, paramLabel))
0072 continue;
0073
0074
0075 float buffer[myMaxNumValPerParam] = {0.};
0076 unsigned int bufferPos = 0;
0077 for (; bufferPos < myMaxNumValPerParam; ++bufferPos) {
0078 if (!this->readIfSameLine<float>(myPedeResult, buffer[bufferPos]))
0079 break;
0080 }
0081
0082
0083
0084
0085 std::pair<IntegratedCalibrationBase *, unsigned int> calibParam = myLabels.calibrationParamFromLabel(paramLabel);
0086 if (calibParam.first) {
0087 if (this->setCalibrationParameter(calibParam.first, calibParam.second, bufferPos, buffer)) {
0088 ++nParamCalib;
0089 } else {
0090 edm::LogError("Alignment") << "@SUB=PedeReader::read"
0091 << "Problems setting results of "
0092 << "parameter " << calibParam.second << " to calibration '"
0093 << calibParam.first->name() << "' (" << calibParam.first << ").";
0094 isAllOk = false;
0095 }
0096 continue;
0097 }
0098
0099 const RunRange &runRange = myLabels.runRangeFromLabel(paramLabel);
0100 if (!(runRange.first <= myRunRange.first && myRunRange.second <= runRange.second))
0101 continue;
0102
0103 Alignable *alignable = this->setParameter(paramLabel, bufferPos, buffer, setUserVars);
0104 if (!alignable) {
0105
0106 ++nParamUnknown;
0107 continue;
0108 }
0109 uniqueList.insert(alignable);
0110 ++nParam;
0111 }
0112
0113
0114 alignables.insert(alignables.end(), uniqueList.begin(), uniqueList.end());
0115
0116 std::stringstream out;
0117 out << nParam << " parameters for " << alignables.size() << " alignables and " << nParamCalib << " for calibrations, "
0118 << nParamUnknown << " parameters are unknown.\n";
0119 if (nParamUnknown) {
0120 edm::LogWarning("Alignment") << "@SUB=PedeReader::read" << out.str();
0121 } else {
0122 edm::LogInfo("Alignment") << "@SUB=PedeReader::read" << out.str();
0123 }
0124
0125 return isAllOk && (nParam + nParamCalib);
0126 }
0127
0128
0129 template <class T>
0130 bool PedeReader::readIfSameLine(std::ifstream &aStream, T &outValue) const {
0131 while (true) {
0132 const int aChar = aStream.get();
0133 if (!aStream.good())
0134 return false;
0135
0136 switch (aChar) {
0137 case ' ':
0138 case '\t':
0139 continue;
0140 case '\n':
0141 return false;
0142 default:
0143 aStream.unget();
0144 aStream >> outValue;
0145 if (aStream.fail()) {
0146 aStream.clear();
0147 while (aStream.good() && aStream.get() != '\n')
0148 ;
0149 return false;
0150 } else {
0151 return true;
0152 }
0153 }
0154 }
0155
0156 edm::LogError("Alignment") << "@SUB=PedeReader::readIfSameLine"
0157 << "Should never come here!";
0158 return false;
0159 }
0160
0161
0162 Alignable *PedeReader::setParameter(unsigned int paramLabel,
0163 unsigned int bufLength,
0164 const float *buf,
0165 bool setUserVars) const {
0166 Alignable *alignable = myLabels.alignableFromLabel(paramLabel);
0167 const unsigned int paramNum = myLabels.paramNumFromLabel(paramLabel);
0168 const double cmsToPede = mySteerer.cmsToPedeFactor(paramNum);
0169 if (alignable) {
0170 AlignmentParameters *params = this->checkAliParams(alignable, setUserVars);
0171 MillePedeVariables *userParams =
0172 (setUserVars ? static_cast<MillePedeVariables *>(params->userVariables()) : nullptr);
0173
0174 if (userParams && userParams->label() != myLabels.alignableLabel(alignable)) {
0175 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
0176 << "Label mismatch: paramLabel " << paramLabel << " for alignableLabel "
0177 << userParams->label();
0178 }
0179
0180 AlgebraicVector parVec(params->parameters());
0181 AlgebraicSymMatrix covMat(params->covariance());
0182
0183 if (userParams)
0184 userParams->setAllDefault(paramNum);
0185
0186 switch (bufLength) {
0187 case 5:
0188 if (userParams)
0189 userParams->globalCor()[paramNum] = buf[4];
0190 [[fallthrough]];
0191 case 4:
0192 if (userParams)
0193 userParams->sigma()[paramNum] = buf[3] / cmsToPede;
0194 covMat[paramNum][paramNum] = buf[3] * buf[3] / (cmsToPede * cmsToPede);
0195 [[fallthrough]];
0196 case 3:
0197 if (userParams)
0198 userParams->diffBefore()[paramNum] = buf[2] / cmsToPede;
0199 [[fallthrough]];
0200 case 2:
0201 params->setValid(true);
0202 parVec[paramNum] = buf[0] / cmsToPede * mySteerer.parameterSign();
0203 if (userParams) {
0204 userParams->parameter()[paramNum] = parVec[paramNum];
0205 userParams->preSigma()[paramNum] = buf[1];
0206 if (!userParams->isFixed(paramNum)) {
0207 userParams->preSigma()[paramNum] /= cmsToPede;
0208 if (bufLength == 2) {
0209 edm::LogWarning("Alignment")
0210 << "@SUB=PedeReader::setParameter"
0211 << "Param " << paramLabel << " (from " << typeid(*alignable).name() << ") without result!";
0212 userParams->isValid()[paramNum] = false;
0213 params->setValid(false);
0214 }
0215 }
0216 }
0217 break;
0218 case 0:
0219 case 1:
0220 default:
0221 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
0222 << "Expect 2 to 5 values, got " << bufLength << " for label " << paramLabel;
0223 break;
0224 }
0225 alignable->setAlignmentParameters(params->clone(parVec, covMat));
0226 } else {
0227 unsigned int lasBeamId = myLabels.lasBeamIdFromLabel(paramLabel);
0228 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
0229 << "No alignable for paramLabel " << paramLabel << ", probably LasBeam with Id "
0230 << lasBeamId << ",\nparam " << paramNum << ": "
0231 << buf[0] / cmsToPede * mySteerer.parameterSign()
0232 << " += " << (bufLength >= 4 ? buf[3] / cmsToPede : -99.);
0233 }
0234
0235 return alignable;
0236 }
0237
0238
0239 bool PedeReader::setCalibrationParameter(IntegratedCalibrationBase *calib,
0240 unsigned int paramNum,
0241 unsigned int bufLength,
0242 const float *buf) const {
0243 if (!calib || !buf)
0244 return false;
0245
0246
0247
0248 switch (bufLength) {
0249 case 5:
0250 case 4:
0251 calib->setParameterError(paramNum, buf[3]);
0252 [[fallthrough]];
0253 case 3:
0254 case 2:
0255 if (bufLength == 2 && buf[1] >= 0.) {
0256 edm::LogWarning("Alignment") << "@SUB=PedeReader::setCalibrationParameter"
0257 << "Param " << paramNum << " of calibration '" << calib->name()
0258 << "' without result!";
0259 }
0260 return calib->setParameter(paramNum, buf[0] * mySteerer.parameterSign());
0261 case 0:
0262 case 1:
0263 default:
0264 edm::LogError("Alignment") << "@SUB=PedeReader::setCalibrationParameter"
0265 << "Expect 2 to 5 values, got " << bufLength << ".";
0266 return false;
0267 }
0268 }
0269
0270
0271 AlignmentParameters *PedeReader::checkAliParams(Alignable *alignable, bool createUserVars) const {
0272
0273 AlignmentParameters *params = alignable->alignmentParameters();
0274 if (!params) {
0275 throw cms::Exception("BadConfig") << "PedeReader::checkAliParams: "
0276 << "Alignable without parameters.";
0277 }
0278
0279
0280 if (createUserVars && !dynamic_cast<MillePedeVariables *>(params->userVariables())) {
0281 edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
0282 << "Add user variables for alignable with label " << myLabels.alignableLabel(alignable);
0283 params->setUserVariables(new MillePedeVariables(
0284 params->size(),
0285 myLabels.alignableLabel(alignable),
0286 myLabels.alignableTracker()->objectIdProvider().typeToName(alignable->alignableObjectId())));
0287 }
0288
0289 return params;
0290 }