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 (iRunRange->first<=eventInfo.eventId_.run() && iRunRange->second>=eventInfo.eventId_.run()) {
00163 return position->second + offset * theParamInstanceOffset + parNum;
00164 }
00165 offset++;
00166 }
00167 const DetId detId(alignable->id());
00168 edm::LogError("LogicError")
00169 << "@SUB=RunRangeDependentPedeLabeler::alignableLabel" << "Alignable "
00170 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00171 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00172 return 0;
00173 } else {
00174 return position->second + parNum;
00175 }
00176
00177 } else {
00178 return position->second + parNum;
00179 }
00180 } else {
00181 const DetId detId(alignable->id());
00182
00183 edm::LogError("LogicError")
00184 << "@SUB=RunRangeDependentPedeLabeler::alignableLabel" << "Alignable "
00185 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00186 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00187 return 0;
00188 }
00189 }
00190
00191
00192 bool RunRangeDependentPedeLabeler::hasSplitParameters(Alignable *alignable) const
00193 {
00194 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
00195 if (positionAli != theAlignableToRunRangeRangeMap.end()) return true;
00196 return false;
00197 }
00198
00199
00200 unsigned int RunRangeDependentPedeLabeler::numberOfParameterInstances(Alignable *alignable, int param) const
00201 {
00202 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(alignable);
00203 if (positionAli != theAlignableToRunRangeRangeMap.end()) {
00204
00205 size_t nRunRanges = 1;
00206 if (param==-1) {
00207 for (RunRangeParamMap::const_iterator iParam = (*positionAli).second.begin();
00208 iParam != (*positionAli).second.end();
00209 ++iParam) {
00210 nRunRanges = std::max(nRunRanges, iParam->second.size());
00211 }
00212 return nRunRanges;
00213 } else {
00214 RunRangeParamMap::const_iterator iParam = (*positionAli).second.find(param);
00215 if (iParam != (*positionAli).second.end()) {
00216 return iParam->second.size();
00217 } else {
00218 return 1;
00219 }
00220 }
00221 }
00222
00223 return 1;
00224 }
00225
00226
00227 unsigned int RunRangeDependentPedeLabeler::paramNumFromLabel(unsigned int paramLabel) const
00228 {
00229 if (paramLabel < theMinLabel) {
00230 edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::paramNumFromLabel"
00231 << "Label " << paramLabel << " should be >= " << theMinLabel;
00232 return 0;
00233 }
00234 return (paramLabel - theMinLabel) % theMaxNumParam;
00235 }
00236
00237
00238 unsigned int RunRangeDependentPedeLabeler::alignableLabelFromLabel(unsigned int paramLabel) const
00239 {
00240 return paramLabel - this->paramNumFromLabel(paramLabel);
00241 }
00242
00243
00244 Alignable* RunRangeDependentPedeLabeler::alignableFromLabel(unsigned int label) const
00245 {
00246 const unsigned int aliLabel = this->alignableLabelFromLabel(label);
00247 if (aliLabel < theMinLabel) return 0;
00248
00249 if (theIdToAlignableMap.empty()) const_cast<RunRangeDependentPedeLabeler*>(this)->buildReverseMap();
00250 IdToAlignableMap::const_iterator position = theIdToAlignableMap.find(aliLabel);
00251 if (position != theIdToAlignableMap.end()) {
00252 return position->second;
00253 } else {
00254
00255 UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
00256 if (position == theLabelToLasBeamMap.end()) {
00257 edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::alignableFromLabel"
00258 << "Alignable label " << aliLabel << " not in map.";
00259 }
00260 return 0;
00261 }
00262 }
00263
00264
00265 unsigned int RunRangeDependentPedeLabeler::lasBeamIdFromLabel(unsigned int label) const
00266 {
00267 const unsigned int aliLabel = this->alignableLabelFromLabel(label);
00268 if (aliLabel < theMinLabel) return 0;
00269
00270 if (theLabelToLasBeamMap.empty()) const_cast<RunRangeDependentPedeLabeler*>(this)->buildReverseMap();
00271 UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
00272 if (position != theLabelToLasBeamMap.end()) {
00273 return position->second;
00274 } else {
00275 edm::LogError("LogicError") << "@SUB=RunRangeDependentPedeLabeler::lasBeamIdFromLabel"
00276 << "Alignable label " << aliLabel << " not in map.";
00277 return 0;
00278 }
00279 }
00280
00281 unsigned int RunRangeDependentPedeLabeler::runRangeIndexFromLabel(unsigned int label) const
00282 {
00283 Alignable* ali = alignableFromLabel(label);
00284 unsigned int firstLabel = alignableLabel(ali);
00285 return (label-firstLabel)/theMaxNumParam;
00286 }
00287
00288 const RunRangeDependentPedeLabeler::RunRange&
00289 RunRangeDependentPedeLabeler::runRangeFromLabel(unsigned int label) const
00290 {
00291 Alignable* ali = alignableFromLabel(label);
00292
00293 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(ali);
00294 if (positionAli==theAlignableToRunRangeRangeMap.end())
00295 return theOpenRunRange;
00296
00297 unsigned int firstLabel = alignableLabel(ali);
00298 unsigned int runRangeIndex = (label-firstLabel)/theParamInstanceOffset;
00299 unsigned int paramNum = this->paramNumFromLabel(label);
00300
00301 RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(paramNum);
00302 if (positionParam==(*positionAli).second.end()) {
00303 return theOpenRunRange;
00304 }
00305
00306 return positionParam->second[runRangeIndex];
00307 }
00308
00309
00310 std::vector<std::string> RunRangeDependentPedeLabeler::decompose(const std::string &s,
00311 std::string::value_type delimiter) const
00312 {
00313 std::vector<std::string> result;
00314
00315 std::string::size_type previousPos = 0;
00316 while (true) {
00317 const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
00318 if (delimiterPos == std::string::npos) {
00319 result.push_back(s.substr(previousPos));
00320 break;
00321 }
00322 result.push_back(s.substr(previousPos, delimiterPos - previousPos));
00323 previousPos = delimiterPos + 1;
00324 }
00325
00326 return result;
00327 }
00328
00329
00330 std::vector<unsigned int> RunRangeDependentPedeLabeler::convertParamSel(const std::string &selString) const
00331 {
00332 std::vector<unsigned int> result;
00333 for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
00334 if (selString[pos]=='1') result.push_back(pos);
00335 }
00336 return result;
00337 }
00338
00339 unsigned int RunRangeDependentPedeLabeler::buildRunRangeDependencyMap(AlignableTracker *aliTracker,
00340 AlignableMuon* aliMuon,
00341 AlignableExtras *aliExtras,
00342 const edm::ParameterSet &config)
00343 {
00344 theAlignableToRunRangeRangeMap.clear();
00345
00346 AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
00347
00348 std::vector<char> paramSelDummy(6, '1');
00349
00350 const std::vector<edm::ParameterSet> RunRangeSelectionVPSet =
00351 config.getUntrackedParameter<std::vector<edm::ParameterSet> >("RunRangeSelection");
00352
00353 for (std::vector<edm::ParameterSet>::const_iterator iter = RunRangeSelectionVPSet.begin();
00354 iter != RunRangeSelectionVPSet.end();
00355 ++iter) {
00356
00357 const std::vector<std::string> tempRunRanges = (*iter).getParameter<std::vector<std::string> >("RunRanges");
00358 if (tempRunRanges.size()==0) {
00359 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00360 << "RunRanges empty\n";
00361 }
00362
00363 RunRangeVector RunRanges;
00364 cond::Time_t first;
00365 cond::Time_t last;
00366 for (unsigned int iRunRange=0;iRunRange<tempRunRanges.size();++iRunRange) {
00367 std::vector<std::string> tokens = edm::tokenize(tempRunRanges[iRunRange], ":");
00368 long int temp;
00369
00370 first = cond::timeTypeSpecs[cond::runnumber].beginValue;
00371 temp = strtol(tokens[0].c_str(), 0, 0);
00372 if (temp!=-1) first = temp;
00373
00374 last = cond::timeTypeSpecs[cond::runnumber].endValue;
00375 temp = strtol(tokens[1].c_str(), 0, 0);
00376 if (temp!=-1) last = temp;
00377
00378 RunRanges.push_back(std::pair<cond::Time_t,cond::Time_t>(first, last));
00379 }
00380
00381 const std::vector<std::string> selStrings = (*iter).getParameter<std::vector<std::string> >("selector");
00382 for (std::vector<std::string>::const_iterator iSel = selStrings.begin();
00383 iSel != selStrings.end();
00384 ++iSel) {
00385 std::vector<std::string> decompSel(this->decompose(*iSel, ','));
00386
00387 if (decompSel.size()!=2) {
00388 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00389 << *iSel <<" should have at least 2 ','-separated parts\n";
00390 }
00391
00392 std::vector<unsigned int> selParam = this->convertParamSel(decompSel[1]);
00393 selector.clear();
00394 selector.addSelection(decompSel[0], paramSelDummy);
00395
00396 const std::vector<Alignable*> &alis = selector.selectedAlignables();
00397 for (std::vector<Alignable*>::const_iterator iAli = alis.begin();
00398 iAli != alis.end();
00399 ++iAli) {
00400 for (std::vector<unsigned int>::const_iterator iParam = selParam.begin();
00401 iParam != selParam.end();
00402 ++iParam) {
00403 AlignableToRunRangeRangeMap::const_iterator positionAli = theAlignableToRunRangeRangeMap.find(*iAli);
00404 if (positionAli!=theAlignableToRunRangeRangeMap.end()) {
00405
00406 AlignmentParameters *AliParams = (*positionAli).first->alignmentParameters();
00407 if (static_cast<int>(selParam[selParam.size()-1]) >= AliParams->size()) {
00408 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00409 << "mismatch in number of parameters\n";
00410 }
00411
00412 RunRangeParamMap::const_iterator positionParam = (*positionAli).second.find(*iParam);
00413 if (positionParam!=(*positionAli).second.end()) {
00414 throw cms::Exception("BadConfig") << "@SUB=RunRangeDependentPedeLabeler::buildRunRangeDependencyMap\n"
00415 << "RunRange range for parameter specified twice\n";
00416 }
00417 }
00418
00419 theAlignableToRunRangeRangeMap[*iAli][*iParam] = RunRanges;
00420 }
00421 }
00422 }
00423 }
00424
00425 return theAlignableToRunRangeRangeMap.size();
00426 }
00427
00428
00429 unsigned int RunRangeDependentPedeLabeler::buildMap(const std::vector<Alignable*> &alis)
00430 {
00431 theAlignableToIdMap.clear();
00432
00433 std::vector<Alignable*> allComps;
00434
00435 for (std::vector<Alignable*>::const_iterator iAli = alis.begin(); iAli != alis.end(); ++iAli) {
00436 if (*iAli) {
00437 allComps.push_back(*iAli);
00438 (*iAli)->recursiveComponents(allComps);
00439 }
00440 }
00441
00442 unsigned int id = theMinLabel;
00443 for (std::vector<Alignable*>::const_iterator iter = allComps.begin();
00444 iter != allComps.end(); ++iter) {
00445 theAlignableToIdMap.insert(AlignableToIdPair(*iter, id));
00446 id += theMaxNumParam;
00447 }
00448
00449
00450 theLasBeamToLabelMap.clear();
00451
00452
00453 unsigned int beamIds[] = { 0, 10, 20, 30, 40, 50, 60, 70,
00454 1, 11, 21, 31, 41, 51, 61, 71,
00455 100, 110, 120, 130, 140, 150, 160, 170,
00456 101, 111, 121, 131, 141, 151, 161, 171,
00457 200, 210, 220, 230, 240, 250, 260, 270};
00458
00459 const size_t nBeams = sizeof(beamIds)/sizeof(beamIds[0]);
00460 for (size_t iBeam = 0; iBeam < nBeams; ++iBeam) {
00461
00462 theLasBeamToLabelMap[beamIds[iBeam]] = id;
00463 id += theMaxNumParam;
00464 }
00465
00466
00467 return theAlignableToIdMap.size() + theLasBeamToLabelMap.size();
00468 }
00469
00470
00471 unsigned int RunRangeDependentPedeLabeler::buildReverseMap()
00472 {
00473
00474
00475 theIdToAlignableMap.clear();
00476
00477 for (AlignableToIdMap::iterator it = theAlignableToIdMap.begin();
00478 it != theAlignableToIdMap.end(); ++it) {
00479 const unsigned int key = (*it).second;
00480 Alignable *ali = (*it).first;
00481 const unsigned int nInstances = this->numberOfParameterInstances(ali, -1);
00482 for (unsigned int iInstance=0;iInstance<nInstances;++iInstance) {
00483 theIdToAlignableMap[key+iInstance*theParamInstanceOffset] = ali;
00484 }
00485 }
00486
00487
00488 theLabelToLasBeamMap.clear();
00489
00490 for (UintUintMap::const_iterator it = theLasBeamToLabelMap.begin();
00491 it != theLasBeamToLabelMap.end(); ++it) {
00492 theLabelToLasBeamMap[it->second] = it->first;
00493 }
00494
00495
00496 return theIdToAlignableMap.size() + theLabelToLasBeamMap.size();
00497 }
00498
00499 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerPluginFactory.h"
00500 DEFINE_EDM_PLUGIN(PedeLabelerPluginFactory, RunRangeDependentPedeLabeler, "RunRangeDependentPedeLabeler");