File indexing completed on 2024-04-06 11:56:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <algorithm>
0012
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include "FWCore/Utilities/interface/Parse.h"
0015
0016 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
0017 #include "Alignment/CommonAlignment/interface/Alignable.h"
0018 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
0019 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
0020 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
0021 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
0022 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
0023
0024 #include "MomentumDependentPedeLabeler.h"
0025
0026
0027 MomentumDependentPedeLabeler::MomentumDependentPedeLabeler(const PedeLabelerBase::TopLevelAlignables &alignables,
0028 const edm::ParameterSet &config)
0029 : PedeLabelerBase(alignables, config),
0030 theOpenMomentumRange(std::pair<float, float>(0.0, 10000.0)),
0031 theMaxNumberOfParameterInstances(0) {
0032 align::Alignables alis;
0033 alis.push_back(alignables.aliTracker_);
0034 alis.push_back(alignables.aliMuon_);
0035
0036 if (alignables.aliExtras_) {
0037 for (const auto &ali : alignables.aliExtras_->components()) {
0038 alis.push_back(ali);
0039 }
0040 }
0041
0042 this->buildMomentumDependencyMap(alignables.aliTracker_, alignables.aliMuon_, alignables.aliExtras_, config);
0043 this->buildMap(alis);
0044 this->buildReverseMap();
0045 }
0046
0047
0048
0049 MomentumDependentPedeLabeler::~MomentumDependentPedeLabeler() {}
0050
0051
0052
0053 unsigned int MomentumDependentPedeLabeler::alignableLabel(const Alignable *alignable) const {
0054 if (!alignable)
0055 return 0;
0056
0057 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
0058 if (position != theAlignableToIdMap.end()) {
0059 return position->second;
0060 } else {
0061 const DetId detId(alignable->id());
0062
0063 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::alignableLabel"
0064 << "Alignable " << typeid(*alignable).name()
0065 << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
0066 << detId.subdetId() << "/" << alignable->alignableObjectId();
0067 return 0;
0068 }
0069 }
0070
0071
0072
0073 unsigned int MomentumDependentPedeLabeler::alignableLabelFromParamAndInstance(const Alignable *alignable,
0074 unsigned int param,
0075 unsigned int instance) const {
0076 if (!alignable)
0077 return 0;
0078
0079 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
0080 if (position != theAlignableToIdMap.end()) {
0081 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
0082 if (positionAli != theAlignableToMomentumRangeMap.end()) {
0083 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(param);
0084 if (positionParam != (*positionAli).second.end()) {
0085 if (instance >= (*positionParam).second.size()) {
0086 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::alignableLabelFromParamAndMomentum"
0087 << "iovIdx out of bounds";
0088 }
0089 return position->second + instance * theParamInstanceOffset;
0090 } else {
0091 return position->second;
0092 }
0093 } else {
0094 return position->second;
0095 }
0096 } else {
0097 const DetId detId(alignable->id());
0098
0099 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::alignableLabel"
0100 << "Alignable " << typeid(*alignable).name()
0101 << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
0102 << detId.subdetId() << "/" << alignable->alignableObjectId();
0103 return 0;
0104 }
0105 }
0106
0107
0108 unsigned int MomentumDependentPedeLabeler::lasBeamLabel(unsigned int lasBeamId) const {
0109 UintUintMap::const_iterator position = theLasBeamToLabelMap.find(lasBeamId);
0110 if (position != theLasBeamToLabelMap.end()) {
0111 return position->second;
0112 } else {
0113
0114 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::lasBeamLabel"
0115 << "No label for beam Id " << lasBeamId;
0116 return 0;
0117 }
0118 }
0119
0120
0121 unsigned int MomentumDependentPedeLabeler::parameterLabel(unsigned int aliLabel, unsigned int parNum) const {
0122 if (parNum >= theMaxNumParam) {
0123 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::parameterLabel"
0124 << "Parameter number " << parNum << " out of range 0 <= num < " << theMaxNumParam;
0125 }
0126 return aliLabel + parNum;
0127 }
0128
0129
0130 unsigned int MomentumDependentPedeLabeler::parameterLabel(Alignable *alignable,
0131 unsigned int parNum,
0132 const AlignmentAlgorithmBase::EventInfo &eventInfo,
0133 const TrajectoryStateOnSurface &tsos) const {
0134 if (!alignable)
0135 return 0;
0136
0137 if (parNum >= theMaxNumParam) {
0138 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::parameterLabel"
0139 << "Parameter number " << parNum << " out of range 0 <= num < " << theMaxNumParam;
0140 }
0141
0142 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
0143 if (position != theAlignableToIdMap.end()) {
0144 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
0145 if (positionAli != theAlignableToMomentumRangeMap.end()) {
0146 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(parNum);
0147 if (positionParam != (*positionAli).second.end()) {
0148 int offset = 0;
0149 float mom = tsos.globalMomentum().mag();
0150 const MomentumRangeVector &momentumRanges = (*positionParam).second;
0151 for (const auto &iMomentum : momentumRanges) {
0152 if (iMomentum.first <= mom && mom < iMomentum.second) {
0153 return position->second + offset * theParamInstanceOffset + parNum;
0154 }
0155 offset++;
0156 }
0157 const DetId detId(alignable->id());
0158 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::alignableLabel"
0159 << "Alignable " << typeid(*alignable).name()
0160 << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
0161 << detId.subdetId() << "/" << alignable->alignableObjectId();
0162 return 0;
0163 } else {
0164 return position->second + parNum;
0165 }
0166
0167 } else {
0168 return position->second + parNum;
0169 }
0170 } else {
0171 const DetId detId(alignable->id());
0172
0173 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::alignableLabel"
0174 << "Alignable " << typeid(*alignable).name()
0175 << " not in map, det/subdet/alignableStructureType = " << detId.det() << "/"
0176 << detId.subdetId() << "/" << alignable->alignableObjectId();
0177 return 0;
0178 }
0179 }
0180
0181
0182 bool MomentumDependentPedeLabeler::hasSplitParameters(Alignable *alignable) const {
0183 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
0184 if (positionAli != theAlignableToMomentumRangeMap.end())
0185 return true;
0186 return false;
0187 }
0188
0189
0190 unsigned int MomentumDependentPedeLabeler::numberOfParameterInstances(Alignable *alignable, int param) const {
0191 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
0192 if (positionAli != theAlignableToMomentumRangeMap.end()) {
0193 size_t nMomentums = 1;
0194 if (param == -1) {
0195 for (const auto &iParam : (*positionAli).second) {
0196 nMomentums = std::max(nMomentums, iParam.second.size());
0197 }
0198 return nMomentums;
0199 } else {
0200 MomentumRangeParamMap::const_iterator iParam = (*positionAli).second.find(param);
0201 if (iParam != (*positionAli).second.end()) {
0202 return iParam->second.size();
0203 } else {
0204 return 1;
0205 }
0206 }
0207 }
0208
0209 return 1;
0210 }
0211
0212
0213 unsigned int MomentumDependentPedeLabeler::paramNumFromLabel(unsigned int paramLabel) const {
0214 if (paramLabel < theMinLabel) {
0215 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::paramNumFromLabel"
0216 << "Label " << paramLabel << " should be >= " << theMinLabel;
0217 return 0;
0218 }
0219 return (paramLabel - theMinLabel) % theParamInstanceOffset;
0220 }
0221
0222
0223 unsigned int MomentumDependentPedeLabeler::alignableLabelFromLabel(unsigned int paramLabel) const {
0224 return paramLabel - this->paramNumFromLabel(paramLabel);
0225 }
0226
0227
0228 Alignable *MomentumDependentPedeLabeler::alignableFromLabel(unsigned int label) const {
0229 const unsigned int aliLabel = this->alignableLabelFromLabel(label);
0230 if (aliLabel < theMinLabel)
0231 return nullptr;
0232
0233 IdToAlignableMap::const_iterator position = theIdToAlignableMap.find(aliLabel);
0234 if (position != theIdToAlignableMap.end()) {
0235 return position->second;
0236 } else {
0237
0238 UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
0239 if (position == theLabelToLasBeamMap.end()) {
0240 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::alignableFromLabel"
0241 << "Alignable label " << aliLabel << " not in map.";
0242 }
0243 return nullptr;
0244 }
0245 }
0246
0247
0248 unsigned int MomentumDependentPedeLabeler::lasBeamIdFromLabel(unsigned int label) const {
0249 const unsigned int aliLabel = this->alignableLabelFromLabel(label);
0250 if (aliLabel < theMinLabel)
0251 return 0;
0252
0253 UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
0254 if (position != theLabelToLasBeamMap.end()) {
0255 return position->second;
0256 } else {
0257 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::lasBeamIdFromLabel"
0258 << "Alignable label " << aliLabel << " not in map.";
0259 return 0;
0260 }
0261 }
0262
0263
0264 std::vector<std::string> MomentumDependentPedeLabeler::decompose(const std::string &s,
0265 std::string::value_type delimiter) const {
0266 std::vector<std::string> result;
0267
0268 std::string::size_type previousPos = 0;
0269 while (true) {
0270 const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
0271 if (delimiterPos == std::string::npos) {
0272 result.push_back(s.substr(previousPos));
0273 break;
0274 }
0275 result.push_back(s.substr(previousPos, delimiterPos - previousPos));
0276 previousPos = delimiterPos + 1;
0277 }
0278
0279 return result;
0280 }
0281
0282
0283 std::vector<unsigned int> MomentumDependentPedeLabeler::convertParamSel(const std::string &selString) const {
0284 std::vector<unsigned int> result;
0285 for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
0286 if (selString[pos] == '1')
0287 result.push_back(pos);
0288 }
0289 return result;
0290 }
0291
0292 unsigned int MomentumDependentPedeLabeler::buildMomentumDependencyMap(AlignableTracker *aliTracker,
0293 AlignableMuon *aliMuon,
0294 AlignableExtras *aliExtras,
0295 const edm::ParameterSet &config) {
0296 theAlignableToMomentumRangeMap.clear();
0297
0298 AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
0299
0300 std::vector<char> paramSelDumthe(6, '1');
0301
0302 const auto parameterInstancesVPSet = config.getParameter<std::vector<edm::ParameterSet> >("parameterInstances");
0303
0304 for (const auto &iter : parameterInstancesVPSet) {
0305 const auto tempMomentumRanges = iter.getParameter<std::vector<std::string> >("momentumRanges");
0306 if (tempMomentumRanges.empty()) {
0307 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
0308 << "MomentumRanges empty\n";
0309 }
0310
0311 MomentumRangeVector MomentumRanges;
0312 float lower;
0313 float upper;
0314 for (unsigned int iMomentum = 0; iMomentum < tempMomentumRanges.size(); ++iMomentum) {
0315 std::vector<std::string> tokens = edm::tokenize(tempMomentumRanges[iMomentum], ":");
0316
0317 lower = strtod(tokens[0].c_str(), nullptr);
0318 upper = strtod(tokens[1].c_str(), nullptr);
0319
0320 MomentumRanges.push_back(std::pair<float, float>(lower, upper));
0321 }
0322
0323 const auto selStrings = iter.getParameter<std::vector<std::string> >("selector");
0324 for (const auto &iSel : selStrings) {
0325 std::vector<std::string> decompSel(this->decompose(iSel, ','));
0326
0327 if (decompSel.size() != 2) {
0328 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
0329 << iSel << " should have at least 2 ','-separated parts\n";
0330 }
0331
0332 std::vector<unsigned int> selParam = this->convertParamSel(decompSel[1]);
0333 selector.clear();
0334 selector.addSelection(decompSel[0], paramSelDumthe);
0335
0336 const auto &alis = selector.selectedAlignables();
0337 for (const auto &iAli : alis) {
0338 if (iAli->alignmentParameters() == nullptr) {
0339 throw cms::Exception("BadConfig")
0340 << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
0341 << "Momentum dependence configured for alignable of type "
0342 << objectIdProvider().idToString(iAli->alignableObjectId()) << " at (" << iAli->globalPosition().x()
0343 << "," << iAli->globalPosition().y() << "," << iAli->globalPosition().z() << "), "
0344 << "but that has no parameters. Please check that all run "
0345 << "momentum parameters are also selected for alignment.\n";
0346 }
0347
0348 for (const auto &iParam : selParam) {
0349 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(iAli);
0350 if (positionAli != theAlignableToMomentumRangeMap.end()) {
0351 AlignmentParameters *AliParams = (*positionAli).first->alignmentParameters();
0352 if (static_cast<int>(selParam[selParam.size() - 1]) >= AliParams->size()) {
0353 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
0354 << "mismatch in number of parameters\n";
0355 }
0356
0357 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(iParam);
0358 if (positionParam != (*positionAli).second.end()) {
0359 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
0360 << "Momentum range for parameter specified twice\n";
0361 }
0362 }
0363
0364 theAlignableToMomentumRangeMap[iAli][iParam] = MomentumRanges;
0365 }
0366 }
0367 }
0368 }
0369
0370 return theAlignableToMomentumRangeMap.size();
0371 }
0372
0373
0374 unsigned int MomentumDependentPedeLabeler::buildMap(const align::Alignables &alis) {
0375 theAlignableToIdMap.clear();
0376
0377 align::Alignables allComps;
0378
0379 for (const auto &iAli : alis) {
0380 if (iAli) {
0381 allComps.push_back(iAli);
0382 iAli->recursiveComponents(allComps);
0383 }
0384 }
0385
0386 unsigned int id = theMinLabel;
0387 for (const auto &iter : allComps) {
0388 theAlignableToIdMap.insert(AlignableToIdPair(iter, id));
0389 id += theMaxNumParam;
0390 }
0391
0392
0393 theLasBeamToLabelMap.clear();
0394
0395
0396 unsigned int beamIds[] = {0, 10, 20, 30, 40, 50, 60, 70,
0397 1, 11, 21, 31, 41, 51, 61, 71,
0398 100, 110, 120, 130, 140, 150, 160, 170,
0399 101, 111, 121, 131, 141, 151, 161, 171,
0400 200, 210, 220, 230, 240, 250, 260, 270};
0401
0402 const size_t nBeams = sizeof(beamIds) / sizeof(beamIds[0]);
0403 for (size_t iBeam = 0; iBeam < nBeams; ++iBeam) {
0404
0405 theLasBeamToLabelMap[beamIds[iBeam]] = id;
0406 id += theMaxNumParam;
0407 }
0408
0409 if (id > theParamInstanceOffset) {
0410 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::buildMap: "
0411 << "Too many labels per instance (" << id - 1 << ") leading to double use, "
0412 << "increase PedeLabelerBase::theParamInstanceOffset!\n";
0413 }
0414
0415 return theAlignableToIdMap.size() + theLasBeamToLabelMap.size();
0416 }
0417
0418
0419 unsigned int MomentumDependentPedeLabeler::buildReverseMap() {
0420
0421 theIdToAlignableMap.clear();
0422
0423 for (const auto &it : theAlignableToIdMap) {
0424 const unsigned int key = it.second;
0425 Alignable *ali = it.first;
0426 const unsigned int nInstances = this->numberOfParameterInstances(ali, -1);
0427 theMaxNumberOfParameterInstances = std::max(nInstances, theMaxNumberOfParameterInstances);
0428 for (unsigned int iInstance = 0; iInstance < nInstances; ++iInstance) {
0429 theIdToAlignableMap[key + iInstance * theParamInstanceOffset] = ali;
0430 }
0431 }
0432
0433
0434 theLabelToLasBeamMap.clear();
0435
0436 for (const auto &it : theLasBeamToLabelMap) {
0437 theLabelToLasBeamMap[it.second] = it.first;
0438 }
0439
0440
0441 return theIdToAlignableMap.size() + theLabelToLasBeamMap.size();
0442 }
0443
0444 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerPluginFactory.h"
0445 DEFINE_EDM_PLUGIN(PedeLabelerPluginFactory, MomentumDependentPedeLabeler, "MomentumDependentPedeLabeler");