00001
00011 #include <algorithm>
00012
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 #include "FWCore/Utilities/interface/Parse.h"
00015
00016 #include "Alignment/CommonAlignment/interface/Alignable.h"
00017 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00018 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
00019 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
00020 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
00021 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00022
00023 #include "RunRangeDependentPedeLabeler.h"
00024
00025
00026 RunRangeDependentPedeLabeler::RunRangeDependentPedeLabeler(const PedeLabelerBase::TopLevelAlignables& alignables,
00027 const edm::ParameterSet& config)
00028 :PedeLabelerBase(alignables, config)
00029 {
00030 std::vector<Alignable*> alis;
00031 alis.push_back(alignables.aliTracker_);
00032 alis.push_back(alignables.aliMuon_);
00033
00034 if (alignables.aliExtras_) {
00035 align::Alignables allExtras = alignables.aliExtras_->components();
00036 for ( std::vector<Alignable*>::iterator it = allExtras.begin(); it != allExtras.end(); ++it ) {
00037 alis.push_back(*it);
00038 }
00039 }
00040
00041 this->buildRunRangeDependencyMap(alignables.aliTracker_,
00042 alignables.aliMuon_,
00043 alignables.aliExtras_,
00044 config);
00045 this->buildMap(alis);
00046 }
00047
00048
00049
00050 RunRangeDependentPedeLabeler::~RunRangeDependentPedeLabeler()
00051 {
00052 }
00053
00054
00056 unsigned int RunRangeDependentPedeLabeler::alignableLabel(Alignable *alignable) const
00057 {
00058 if (!alignable) return 0;
00059
00060 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00061 if (position != theAlignableToIdMap.end()) {
00062 return position->second;
00063 } else {
00064 const DetId detId(alignable->id());
00065
00066 edm::LogError("LogicError")
00067 << "@SUB=RunRangeDependentPedeLabeler::alignableLabel" << "Alignable "
00068 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00069 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00070 return 0;
00071 }
00072 }
00073
00074
00075
00076 unsigned int RunRangeDependentPedeLabeler::alignableLabelFromParamAndInstance(Alignable *alignable,
00077 unsigned int param,
00078 unsigned int instance) const
00079 {
00080 if (!alignable) return 0;
00081
00082 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00083 if (position != theAlignableToIdMap.end()) {
00084 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
00085 if (positionAli != theAlignableToRunRangeRangeMap.end()) {
00086 RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(param);
00087 if (positionParam!=(*positionAli).second.end()) {
00088 if (instance>=(*positionParam).second.size()) {
00089 throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::alignableLabelFromParamAndRunRange"
00090 << "RunRangeIdx out of bounds";
00091 }
00092 return position->second + instance * theParamInstanceOffset;
00093 } else {
00094 return position->second;
00095 }
00096 } else {
00097 return position->second;
00098 }
00099 } else {
00100 const DetId detId(alignable->id());
00101
00102 edm::LogError("LogicError")
00103 << "@SUB=RunRangeDependentPedeLabeler::alignableLabel" << "Alignable "
00104 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00105 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00106 return 0;
00107 }
00108 }
00109
00110
00111 unsigned int RunRangeDependentPedeLabeler::lasBeamLabel(unsigned int lasBeamId) const
00112 {
00113 UintUintMap::const_iterator position = theLasBeamToLabelMap.find(lasBeamId);
00114 if (position != theLasBeamToLabelMap.end()) {
00115 return position->second;
00116 } else {
00117
00118 edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::lasBeamLabel"
00119 << "No label for beam Id " << lasBeamId;
00120 return 0;
00121 }
00122 }
00123
00124
00125 unsigned int RunRangeDependentPedeLabeler::parameterLabel(unsigned int aliLabel, unsigned int parNum) const
00126 {
00127 if (parNum >= theMaxNumParam) {
00128 throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
00129 << "Parameter number " << parNum
00130 << " out of range 0 <= num < " << theMaxNumParam;
00131 }
00132 return aliLabel + parNum;
00133 }
00134
00135
00136 unsigned int RunRangeDependentPedeLabeler::parameterLabel(Alignable *alignable, unsigned int parNum,
00137 const AlignmentAlgorithmBase::EventInfo &eventInfo,
00138 const TrajectoryStateOnSurface &tsos) const
00139 {
00140 if (!alignable) return 0;
00141
00142 if (parNum >= theMaxNumParam) {
00143 throw cms::Exception("Alignment") << "@SUB=RunRangeDependentPedeLabeler::parameterLabel"
00144 << "Parameter number " << parNum
00145 << " out of range 0 <= num < " << theMaxNumParam;
00146 }
00147
00148 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00149 if (position != theAlignableToIdMap.end()) {
00150
00151 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
00152 if (positionAli != theAlignableToRunRangeRangeMap.end()) {
00153
00154 RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(parNum);
00155 if (positionParam!=(*positionAli).second.end()) {
00156
00157 int offset = 0;
00158 const RunRangeVector & runRanges = (*positionParam).second;
00159 for (RunRangeVector::const_iterator iRunRange = runRanges.begin();
00160 iRunRange != runRanges.end();
00161 ++iRunRange) {
00162 if (eventInfo.eventId_.run() >= iRunRange->first &&
00163 eventInfo.eventId_.run() <= iRunRange->second) {
00164 return position->second + offset * theParamInstanceOffset + parNum;
00165 }
00166 offset++;
00167 }
00168 const DetId detId(alignable->id());
00169 edm::LogError("LogicError")
00170 << "@SUB=RunRangeDependentPedeLabeler::parameterLabel" << "Instance for Alignable "
00171 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00172 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId()
00173 << " for run " << eventInfo.eventId_.run();
00174 return 0;
00175 } else {
00176 return position->second + parNum;
00177 }
00178
00179 } else {
00180 return position->second + parNum;
00181 }
00182 } else {
00183 const DetId detId(alignable->id());
00184
00185 edm::LogError("LogicError")
00186 << "@SUB=RunRangeDependentPedeLabeler::parameterLabel" << "Alignable "
00187 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00188 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00189 return 0;
00190 }
00191 }
00192
00193
00194 bool RunRangeDependentPedeLabeler::hasSplitParameters(Alignable *alignable) const
00195 {
00196 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
00197 if (positionAli != theAlignableToRunRangeRangeMap.end()) return true;
00198 return false;
00199 }
00200
00201
00202 unsigned int RunRangeDependentPedeLabeler::numberOfParameterInstances(Alignable *alignable, int param) const
00203 {
00204 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
00205 if (positionAli != theAlignableToRunRangeRangeMap.end()) {
00206
00207 size_t nRunRanges = 1;
00208 if (param==-1) {
00209 for (RunRangeParamMap::const_iterator iParam = (*positionAli).second.begin();
00210 iParam != (*positionAli).second.end();
00211 ++iParam) {
00212 nRunRanges = std::max(nRunRanges, iParam->second.size());
00213 }
00214 return nRunRanges;
00215 } else {
00216 RunRangeParamMap::const_iterator iParam = (*positionAli).second.find(param);
00217 if (iParam != (*positionAli).second.end()) {
00218 return iParam->second.size();
00219 } else {
00220 return 1;
00221 }
00222 }
00223 }
00224
00225 return 1;
00226 }
00227
00228
00229 unsigned int RunRangeDependentPedeLabeler::paramNumFromLabel(unsigned int paramLabel) const
00230 {
00231 if (paramLabel < theMinLabel) {
00232 edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::paramNumFromLabel"
00233 << "Label " << paramLabel << " should be >= " << theMinLabel;
00234 return 0;
00235 }
00236 return (paramLabel - theMinLabel) % theMaxNumParam;
00237 }
00238
00239
00240 unsigned int RunRangeDependentPedeLabeler::alignableLabelFromLabel(unsigned int paramLabel) const
00241 {
00242 return paramLabel - this->paramNumFromLabel(paramLabel);
00243 }
00244
00245
00246 Alignable* RunRangeDependentPedeLabeler::alignableFromLabel(unsigned int label) const
00247 {
00248 const unsigned int aliLabel = this->alignableLabelFromLabel(label);
00249 if (aliLabel < theMinLabel) return 0;
00250
00251 if (theIdToAlignableMap.empty()) const_cast<RunRangeDependentPedeLabeler*>(this)->buildReverseMap();
00252 IdToAlignableMap::const_iterator position = theIdToAlignableMap.find(aliLabel);
00253 if (position != theIdToAlignableMap.end()) {
00254 return position->second;
00255 } else {
00256
00257 UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
00258 if (position == theLabelToLasBeamMap.end()) {
00259 edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::alignableFromLabel"
00260 << "Alignable label " << aliLabel << " not in map.";
00261 }
00262 return 0;
00263 }
00264 }
00265
00266
00267 unsigned int RunRangeDependentPedeLabeler::lasBeamIdFromLabel(unsigned int label) const
00268 {
00269 const unsigned int aliLabel = this->alignableLabelFromLabel(label);
00270 if (aliLabel < theMinLabel) return 0;
00271
00272 if (theLabelToLasBeamMap.empty()) const_cast<RunRangeDependentPedeLabeler*>(this)->buildReverseMap();
00273 UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
00274 if (position != theLabelToLasBeamMap.end()) {
00275 return position->second;
00276 } else {
00277 edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::lasBeamIdFromLabel"
00278 << "Alignable label " << aliLabel << " not in map.";
00279 return 0;
00280 }
00281 }
00282
00283 unsigned int RunRangeDependentPedeLabeler::runRangeIndexFromLabel(unsigned int label) const
00284 {
00285 Alignable* ali = alignableFromLabel(label);
00286 unsigned int firstLabel = alignableLabel(ali);
00287 return (label-firstLabel)/theMaxNumParam;
00288 }
00289
00290 const RunRangeDependentPedeLabeler::RunRange&
00291 RunRangeDependentPedeLabeler::runRangeFromLabel(unsigned int label) const
00292 {
00293 Alignable* ali = alignableFromLabel(label);
00294
00295 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(ali);
00296 if (positionAli==theAlignableToRunRangeRangeMap.end())
00297 return theOpenRunRange;
00298
00299 unsigned int firstLabel = alignableLabel(ali);
00300 unsigned int runRangeIndex = (label-firstLabel)/theParamInstanceOffset;
00301 unsigned int paramNum = this->paramNumFromLabel(label);
00302
00303 RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(paramNum);
00304 if (positionParam==(*positionAli).second.end()) {
00305 return theOpenRunRange;
00306 }
00307
00308 return positionParam->second[runRangeIndex];
00309 }
00310
00311
00312 std::vector<std::string> RunRangeDependentPedeLabeler::decompose(const std::string &s,
00313 std::string::value_type delimiter) const
00314 {
00315 std::vector<std::string> result;
00316
00317 std::string::size_type previousPos = 0;
00318 while (true) {
00319 const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
00320 if (delimiterPos == std::string::npos) {
00321 result.push_back(s.substr(previousPos));
00322 break;
00323 }
00324 result.push_back(s.substr(previousPos, delimiterPos - previousPos));
00325 previousPos = delimiterPos + 1;
00326 }
00327
00328 return result;
00329 }
00330
00331
00332 std::vector<unsigned int> RunRangeDependentPedeLabeler::convertParamSel(const std::string &selString) const
00333 {
00334 std::vector<unsigned int> result;
00335 for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
00336 if (selString[pos]=='1') result.push_back(pos);
00337 }
00338 return result;
00339 }
00340
00341 unsigned int RunRangeDependentPedeLabeler::buildRunRangeDependencyMap(AlignableTracker *aliTracker,
00342 AlignableMuon* aliMuon,
00343 AlignableExtras *aliExtras,
00344 const edm::ParameterSet &config)
00345 {
00346 static bool oldRunRangeSelectionWarning = false;
00347
00348 theAlignableToRunRangeRangeMap.clear();
00349
00350 AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
00351
00352 std::vector<char> paramSelDummy(6, '1');
00353
00354 const std::vector<edm::ParameterSet> RunRangeSelectionVPSet =
00355 config.getUntrackedParameter<std::vector<edm::ParameterSet> >("RunRangeSelection");
00356
00357 for (std::vector<edm::ParameterSet>::const_iterator iter = RunRangeSelectionVPSet.begin();
00358 iter != RunRangeSelectionVPSet.end();
00359 ++iter) {
00360
00361 const std::vector<std::string> tempRunRanges = (*iter).getParameter<std::vector<std::string> >("RunRanges");
00362 if (tempRunRanges.size()==0) {
00363 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00364 << "RunRanges empty\n";
00365 }
00366
00367 RunRangeVector RunRanges;
00368 cond::Time_t first;
00369 long int temp;
00370 for (std::vector<std::string>::const_iterator iRunRange = tempRunRanges.begin();
00371 iRunRange != tempRunRanges.end();
00372 ++iRunRange) {
00373 if ((*iRunRange).find(':')==std::string::npos) {
00374
00375 first = cond::timeTypeSpecs[cond::runnumber].beginValue;
00376 temp = strtol((*iRunRange).c_str(), 0, 0);
00377 if (temp!=-1) first = temp;
00378
00379 } else {
00380
00381 if (!oldRunRangeSelectionWarning) {
00382 edm::LogWarning("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap"
00383 << "Config file contains old format for 'RunRangeSelection'. Only the start run\n"
00384 << "number is used internally. The number of the last run is ignored and can be\n"
00385 << "safely removed from the config file.\n";
00386 oldRunRangeSelectionWarning = true;
00387 }
00388
00389 std::vector<std::string> tokens = edm::tokenize(*iRunRange, ":");
00390 first = cond::timeTypeSpecs[cond::runnumber].beginValue;
00391 temp = strtol(tokens[0].c_str(), 0, 0);
00392 if (temp!=-1) first = temp;
00393
00394 }
00395
00396 RunRanges.push_back(std::pair<cond::Time_t,cond::Time_t>(first, cond::timeTypeSpecs[cond::runnumber].endValue));
00397 }
00398
00399 for (unsigned int i = 0;i<RunRanges.size()-1;++i) {
00400 RunRanges[i].second = RunRanges[i+1].first - 1;
00401 if (RunRanges[i].first > RunRanges[i].second) {
00402 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00403 << "Inconsistency in 'RunRangeSelection' parameter set.";
00404 }
00405 }
00406
00407 const std::vector<std::string> selStrings = (*iter).getParameter<std::vector<std::string> >("selector");
00408 for (std::vector<std::string>::const_iterator iSel = selStrings.begin();
00409 iSel != selStrings.end();
00410 ++iSel) {
00411 std::vector<std::string> decompSel(this->decompose(*iSel, ','));
00412
00413 if (decompSel.size()!=2) {
00414 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00415 << *iSel <<" should have at least 2 ','-separated parts\n";
00416 }
00417
00418 std::vector<unsigned int> selParam = this->convertParamSel(decompSel[1]);
00419 selector.clear();
00420 selector.addSelection(decompSel[0], paramSelDummy);
00421
00422 const std::vector<Alignable*> &alis = selector.selectedAlignables();
00423 for (std::vector<Alignable*>::const_iterator iAli = alis.begin();
00424 iAli != alis.end();
00425 ++iAli) {
00426 for (std::vector<unsigned int>::const_iterator iParam = selParam.begin();
00427 iParam != selParam.end();
00428 ++iParam) {
00429 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(*iAli);
00430 if (positionAli!=theAlignableToRunRangeRangeMap.end()) {
00431
00432 AlignmentParameters *AliParams = (*positionAli).first->alignmentParameters();
00433 if (static_cast<int>(selParam[selParam.size()-1]) >= AliParams->size()) {
00434 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00435 << "mismatch in number of parameters\n";
00436 }
00437
00438 RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(*iParam);
00439 if (positionParam!=(*positionAli).second.end()) {
00440 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00441 << "RunRange range for parameter specified twice\n";
00442 }
00443 }
00444
00445 theAlignableToRunRangeRangeMap[*iAli][*iParam] = RunRanges;
00446 }
00447 }
00448 }
00449 }
00450
00451 return theAlignableToRunRangeRangeMap.size();
00452 }
00453
00454
00455 unsigned int RunRangeDependentPedeLabeler::buildMap(const std::vector<Alignable*> &alis)
00456 {
00457 theAlignableToIdMap.clear();
00458
00459 std::vector<Alignable*> allComps;
00460
00461 for (std::vector<Alignable*>::const_iterator iAli = alis.begin(); iAli != alis.end(); ++iAli) {
00462 if (*iAli) {
00463 allComps.push_back(*iAli);
00464 (*iAli)->recursiveComponents(allComps);
00465 }
00466 }
00467
00468 unsigned int id = theMinLabel;
00469 for (std::vector<Alignable*>::const_iterator iter = allComps.begin();
00470 iter != allComps.end(); ++iter) {
00471 theAlignableToIdMap.insert(AlignableToIdPair(*iter, id));
00472 id += theMaxNumParam;
00473 }
00474
00475
00476 theLasBeamToLabelMap.clear();
00477
00478
00479 unsigned int beamIds[] = { 0, 10, 20, 30, 40, 50, 60, 70,
00480 1, 11, 21, 31, 41, 51, 61, 71,
00481 100, 110, 120, 130, 140, 150, 160, 170,
00482 101, 111, 121, 131, 141, 151, 161, 171,
00483 200, 210, 220, 230, 240, 250, 260, 270};
00484
00485 const size_t nBeams = sizeof(beamIds)/sizeof(beamIds[0]);
00486 for (size_t iBeam = 0; iBeam < nBeams; ++iBeam) {
00487
00488 theLasBeamToLabelMap[beamIds[iBeam]] = id;
00489 id += theMaxNumParam;
00490 }
00491
00492
00493 return theAlignableToIdMap.size() + theLasBeamToLabelMap.size();
00494 }
00495
00496
00497 unsigned int RunRangeDependentPedeLabeler::buildReverseMap()
00498 {
00499
00500
00501 theIdToAlignableMap.clear();
00502
00503 for (AlignableToIdMap::iterator it = theAlignableToIdMap.begin();
00504 it != theAlignableToIdMap.end(); ++it) {
00505 const unsigned int key = (*it).second;
00506 Alignable *ali = (*it).first;
00507 const unsigned int nInstances = this->numberOfParameterInstances(ali, -1);
00508 for (unsigned int iInstance=0;iInstance<nInstances;++iInstance) {
00509 theIdToAlignableMap[key+iInstance*theParamInstanceOffset] = ali;
00510 }
00511 }
00512
00513
00514 theLabelToLasBeamMap.clear();
00515
00516 for (UintUintMap::const_iterator it = theLasBeamToLabelMap.begin();
00517 it != theLasBeamToLabelMap.end(); ++it) {
00518 theLabelToLasBeamMap[it->second] = it->first;
00519 }
00520
00521
00522 return theIdToAlignableMap.size() + theLabelToLasBeamMap.size();
00523 }
00524
00525 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerPluginFactory.h"
00526 DEFINE_EDM_PLUGIN(PedeLabelerPluginFactory, RunRangeDependentPedeLabeler, "RunRangeDependentPedeLabeler");