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