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