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 "MomentumDependentPedeLabeler.h"
00024
00025
00026 MomentumDependentPedeLabeler::MomentumDependentPedeLabeler(const PedeLabelerBase::TopLevelAlignables &alignables,
00027 const edm::ParameterSet &config)
00028 :PedeLabelerBase(alignables, config),
00029 theOpenMomentumRange(std::pair<float,float>(0.0, 10000.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->buildMomentumDependencyMap(alignables.aliTracker_,
00043 alignables.aliMuon_,
00044 alignables.aliExtras_,
00045 config);
00046 this->buildMap(alis);
00047 }
00048
00049
00050
00051 MomentumDependentPedeLabeler::~MomentumDependentPedeLabeler()
00052 {
00053 }
00054
00055
00057 unsigned int MomentumDependentPedeLabeler::alignableLabel(Alignable *alignable) const
00058 {
00059 if (!alignable) return 0;
00060
00061 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00062 if (position != theAlignableToIdMap.end()) {
00063 return position->second;
00064 } else {
00065 const DetId detId(alignable->id());
00066
00067 edm::LogError("LogicError")
00068 << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00069 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00070 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00071 return 0;
00072 }
00073 }
00074
00075
00076
00077 unsigned int MomentumDependentPedeLabeler::alignableLabelFromParamAndInstance(Alignable *alignable,
00078 unsigned int param,
00079 unsigned int instance) const
00080 {
00081 if (!alignable) return 0;
00082
00083 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00084 if (position != theAlignableToIdMap.end()) {
00085 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00086 if (positionAli != theAlignableToMomentumRangeMap.end()) {
00087 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(param);
00088 if (positionParam!=(*positionAli).second.end()) {
00089 if (instance>=(*positionParam).second.size()) {
00090 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::alignableLabelFromParamAndMomentum"
00091 << "iovIdx out of bounds";
00092 }
00093 return position->second + instance * theParamInstanceOffset;
00094 } else {
00095 return position->second;
00096 }
00097 } else {
00098 return position->second;
00099 }
00100 } else {
00101 const DetId detId(alignable->id());
00102
00103 edm::LogError("LogicError")
00104 << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00105 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00106 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00107 return 0;
00108 }
00109 }
00110
00111
00112 unsigned int MomentumDependentPedeLabeler::lasBeamLabel(unsigned int lasBeamId) const
00113 {
00114 UintUintMap::const_iterator position = theLasBeamToLabelMap.find(lasBeamId);
00115 if (position != theLasBeamToLabelMap.end()) {
00116 return position->second;
00117 } else {
00118
00119 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::lasBeamLabel"
00120 << "No label for beam Id " << lasBeamId;
00121 return 0;
00122 }
00123 }
00124
00125
00126 unsigned int MomentumDependentPedeLabeler::parameterLabel(unsigned int aliLabel, unsigned int parNum) const
00127 {
00128 if (parNum >= theMaxNumParam) {
00129 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::parameterLabel"
00130 << "Parameter number " << parNum
00131 << " out of range 0 <= num < " << theMaxNumParam;
00132 }
00133 return aliLabel + parNum;
00134 }
00135
00136
00137 unsigned int MomentumDependentPedeLabeler::parameterLabel(Alignable *alignable, unsigned int parNum,
00138 const AlignmentAlgorithmBase::EventInfo &eventInfo,
00139 const TrajectoryStateOnSurface &tsos) const
00140 {
00141 if (!alignable) return 0;
00142
00143 if (parNum >= theMaxNumParam) {
00144 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::parameterLabel"
00145 << "Parameter number " << parNum
00146 << " out of range 0 <= num < " << theMaxNumParam;
00147 }
00148
00149 AlignableToIdMap::const_iterator position = theAlignableToIdMap.find(alignable);
00150 if (position != theAlignableToIdMap.end()) {
00151
00152 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00153 if (positionAli != theAlignableToMomentumRangeMap.end()) {
00154
00155 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(parNum);
00156 if (positionParam!=(*positionAli).second.end()) {
00157
00158 int offset = 0;
00159 float mom = tsos.globalMomentum().mag();
00160 const MomentumRangeVector & momentumRanges = (*positionParam).second;
00161 for (MomentumRangeVector::const_iterator iMomentum = momentumRanges.begin();
00162 iMomentum != momentumRanges.end();
00163 ++iMomentum) {
00164
00165 if (iMomentum->first<=mom && mom<iMomentum->second) {
00166 return position->second + offset * theParamInstanceOffset + parNum;
00167 }
00168 offset++;
00169 }
00170 const DetId detId(alignable->id());
00171 edm::LogError("LogicError")
00172 << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00173 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00174 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00175 return 0;
00176 } else {
00177 return position->second + parNum;
00178 }
00179
00180 } else {
00181 return position->second + parNum;
00182 }
00183 } else {
00184 const DetId detId(alignable->id());
00185
00186 edm::LogError("LogicError")
00187 << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00188 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00189 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
00190 return 0;
00191 }
00192 }
00193
00194
00195 bool MomentumDependentPedeLabeler::hasSplitParameters(Alignable *alignable) const
00196 {
00197 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00198 if (positionAli != theAlignableToMomentumRangeMap.end()) return true;
00199 return false;
00200 }
00201
00202
00203 unsigned int MomentumDependentPedeLabeler::numberOfParameterInstances(Alignable *alignable, int param) const
00204 {
00205 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00206 if (positionAli != theAlignableToMomentumRangeMap.end()) {
00207
00208 size_t nMomentums = 1;
00209 if (param==-1) {
00210 for (MomentumRangeParamMap::const_iterator iParam = (*positionAli).second.begin();
00211 iParam != (*positionAli).second.end();
00212 ++iParam) {
00213 nMomentums = std::max(nMomentums, iParam->second.size());
00214 }
00215 return nMomentums;
00216 } else {
00217 MomentumRangeParamMap::const_iterator iParam = (*positionAli).second.find(param);
00218 if (iParam != (*positionAli).second.end()) {
00219 return iParam->second.size();
00220 } else {
00221 return 1;
00222 }
00223 }
00224 }
00225
00226 return 1;
00227 }
00228
00229
00230 unsigned int MomentumDependentPedeLabeler::paramNumFromLabel(unsigned int paramLabel) const
00231 {
00232 if (paramLabel < theMinLabel) {
00233 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::paramNumFromLabel"
00234 << "Label " << paramLabel << " should be >= " << theMinLabel;
00235 return 0;
00236 }
00237 return (paramLabel - theMinLabel) % theParamInstanceOffset;
00238 }
00239
00240
00241 unsigned int MomentumDependentPedeLabeler::alignableLabelFromLabel(unsigned int paramLabel) const
00242 {
00243 return paramLabel - this->paramNumFromLabel(paramLabel);
00244 }
00245
00246
00247 Alignable* MomentumDependentPedeLabeler::alignableFromLabel(unsigned int label) const
00248 {
00249 const unsigned int aliLabel = this->alignableLabelFromLabel(label);
00250 if (aliLabel < theMinLabel) return 0;
00251
00252 if (theIdToAlignableMap.empty()) const_cast<MomentumDependentPedeLabeler*>(this)->buildReverseMap();
00253 IdToAlignableMap::const_iterator position = theIdToAlignableMap.find(aliLabel);
00254 if (position != theIdToAlignableMap.end()) {
00255 return position->second;
00256 } else {
00257
00258 UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
00259 if (position == theLabelToLasBeamMap.end()) {
00260 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::alignableFromLabel"
00261 << "Alignable label " << aliLabel << " not in map.";
00262 }
00263 return 0;
00264 }
00265 }
00266
00267
00268 unsigned int MomentumDependentPedeLabeler::lasBeamIdFromLabel(unsigned int label) const
00269 {
00270 const unsigned int aliLabel = this->alignableLabelFromLabel(label);
00271 if (aliLabel < theMinLabel) return 0;
00272
00273 if (theLabelToLasBeamMap.empty()) const_cast<MomentumDependentPedeLabeler*>(this)->buildReverseMap();
00274 UintUintMap::const_iterator position = theLabelToLasBeamMap.find(aliLabel);
00275 if (position != theLabelToLasBeamMap.end()) {
00276 return position->second;
00277 } else {
00278 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::lasBeamIdFromLabel"
00279 << "Alignable label " << aliLabel << " not in map.";
00280 return 0;
00281 }
00282 }
00283
00284
00285 std::vector<std::string> MomentumDependentPedeLabeler::decompose(const std::string &s,
00286 std::string::value_type delimiter) const
00287 {
00288 std::vector<std::string> result;
00289
00290 std::string::size_type previousPos = 0;
00291 while (true) {
00292 const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
00293 if (delimiterPos == std::string::npos) {
00294 result.push_back(s.substr(previousPos));
00295 break;
00296 }
00297 result.push_back(s.substr(previousPos, delimiterPos - previousPos));
00298 previousPos = delimiterPos + 1;
00299 }
00300
00301 return result;
00302 }
00303
00304
00305 std::vector<unsigned int> MomentumDependentPedeLabeler::convertParamSel(const std::string &selString) const
00306 {
00307 std::vector<unsigned int> result;
00308 for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
00309 if (selString[pos]=='1') result.push_back(pos);
00310 }
00311 return result;
00312 }
00313
00314 unsigned int MomentumDependentPedeLabeler::buildMomentumDependencyMap(AlignableTracker *aliTracker,
00315 AlignableMuon* aliMuon,
00316 AlignableExtras *aliExtras,
00317 const edm::ParameterSet &config)
00318 {
00319 theAlignableToMomentumRangeMap.clear();
00320
00321 AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
00322
00323 std::vector<char> paramSelDumthe(6, '1');
00324
00325 const std::vector<edm::ParameterSet> parameterInstancesVPSet =
00326 config.getParameter<std::vector<edm::ParameterSet> >("parameterInstances");
00327
00328 for (std::vector<edm::ParameterSet>::const_iterator iter = parameterInstancesVPSet.begin();
00329 iter != parameterInstancesVPSet.end();
00330 ++iter) {
00331
00332 const std::vector<std::string> tempMomentumRanges = (*iter).getParameter<std::vector<std::string> >("momentumRanges");
00333 if (tempMomentumRanges.size()==0) {
00334 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00335 << "MomentumRanges empty\n";
00336 }
00337
00338 MomentumRangeVector MomentumRanges;
00339 float lower;
00340 float upper;
00341 for (unsigned int iMomentum=0;iMomentum<tempMomentumRanges.size();++iMomentum) {
00342 std::vector<std::string> tokens = edm::tokenize(tempMomentumRanges[iMomentum], ":");
00343
00344 lower = strtod(tokens[0].c_str(), 0);
00345 upper = strtod(tokens[1].c_str(), 0);
00346
00347 MomentumRanges.push_back(std::pair<float,float>(lower, upper));
00348 }
00349
00350 const std::vector<std::string> selStrings = (*iter).getParameter<std::vector<std::string> >("selector");
00351 for (std::vector<std::string>::const_iterator iSel = selStrings.begin();
00352 iSel != selStrings.end();
00353 ++iSel) {
00354 std::vector<std::string> decompSel(this->decompose(*iSel, ','));
00355
00356 if (decompSel.size()!=2) {
00357 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00358 << *iSel <<" should have at least 2 ','-separated parts\n";
00359 }
00360
00361 std::vector<unsigned int> selParam = this->convertParamSel(decompSel[1]);
00362 selector.clear();
00363 selector.addSelection(decompSel[0], paramSelDumthe);
00364
00365 const std::vector<Alignable*> &alis = selector.selectedAlignables();
00366 for (std::vector<Alignable*>::const_iterator iAli = alis.begin();
00367 iAli != alis.end();
00368 ++iAli) {
00369 for (std::vector<unsigned int>::const_iterator iParam = selParam.begin();
00370 iParam != selParam.end();
00371 ++iParam) {
00372 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(*iAli);
00373 if (positionAli!=theAlignableToMomentumRangeMap.end()) {
00374
00375 AlignmentParameters *AliParams = (*positionAli).first->alignmentParameters();
00376 if (static_cast<int>(selParam[selParam.size()-1]) >= AliParams->size()) {
00377 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00378 << "mismatch in number of parameters\n";
00379 }
00380
00381 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(*iParam);
00382 if (positionParam!=(*positionAli).second.end()) {
00383 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00384 << "Momentum range for parameter specified twice\n";
00385 }
00386 }
00387
00388 theAlignableToMomentumRangeMap[*iAli][*iParam] = MomentumRanges;
00389 }
00390 }
00391 }
00392 }
00393
00394 return theAlignableToMomentumRangeMap.size();
00395 }
00396
00397
00398 unsigned int MomentumDependentPedeLabeler::buildMap(const std::vector<Alignable*> &alis)
00399 {
00400 theAlignableToIdMap.clear();
00401
00402 std::vector<Alignable*> allComps;
00403
00404 for (std::vector<Alignable*>::const_iterator iAli = alis.begin(); iAli != alis.end(); ++iAli) {
00405 if (*iAli) {
00406 allComps.push_back(*iAli);
00407 (*iAli)->recursiveComponents(allComps);
00408 }
00409 }
00410
00411 unsigned int id = theMinLabel;
00412 for (std::vector<Alignable*>::const_iterator iter = allComps.begin();
00413 iter != allComps.end(); ++iter) {
00414 theAlignableToIdMap.insert(AlignableToIdPair(*iter, id));
00415 id += theMaxNumParam;
00416 }
00417
00418
00419 theLasBeamToLabelMap.clear();
00420
00421
00422 unsigned int beamIds[] = { 0, 10, 20, 30, 40, 50, 60, 70,
00423 1, 11, 21, 31, 41, 51, 61, 71,
00424 100, 110, 120, 130, 140, 150, 160, 170,
00425 101, 111, 121, 131, 141, 151, 161, 171,
00426 200, 210, 220, 230, 240, 250, 260, 270};
00427
00428 const size_t nBeams = sizeof(beamIds)/sizeof(beamIds[0]);
00429 for (size_t iBeam = 0; iBeam < nBeams; ++iBeam) {
00430
00431 theLasBeamToLabelMap[beamIds[iBeam]] = id;
00432 id += theMaxNumParam;
00433 }
00434
00435
00436 return theAlignableToIdMap.size() + theLasBeamToLabelMap.size();
00437 }
00438
00439
00440 unsigned int MomentumDependentPedeLabeler::buildReverseMap()
00441 {
00442
00443 theIdToAlignableMap.clear();
00444
00445 for (AlignableToIdMap::iterator it = theAlignableToIdMap.begin();
00446 it != theAlignableToIdMap.end(); ++it) {
00447 const unsigned int key = (*it).second;
00448 Alignable *ali = (*it).first;
00449 const unsigned int nInstances = this->numberOfParameterInstances(ali, -1);
00450 for (unsigned int iInstance=0;iInstance<nInstances;++iInstance) {
00451 theIdToAlignableMap[key+iInstance*theParamInstanceOffset] = ali;
00452 }
00453 }
00454
00455
00456 theLabelToLasBeamMap.clear();
00457
00458 for (UintUintMap::const_iterator it = theLasBeamToLabelMap.begin();
00459 it != theLasBeamToLabelMap.end(); ++it) {
00460 theLabelToLasBeamMap[it->second] = it->first;
00461 }
00462
00463
00464 return theIdToAlignableMap.size() + theLabelToLasBeamMap.size();
00465 }
00466
00467 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerPluginFactory.h"
00468 DEFINE_EDM_PLUGIN(PedeLabelerPluginFactory, MomentumDependentPedeLabeler, "MomentumDependentPedeLabeler");