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