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 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->buildMomentumDependencyMap(alignables.aliTracker_,
00044 alignables.aliMuon_,
00045 alignables.aliExtras_,
00046 config);
00047 this->buildMap(alis);
00048 this->buildReverseMap();
00049 }
00050
00051
00052
00053 MomentumDependentPedeLabeler::~MomentumDependentPedeLabeler()
00054 {
00055 }
00056
00057
00059 unsigned int MomentumDependentPedeLabeler::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=MomentumDependentPedeLabeler::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 MomentumDependentPedeLabeler::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 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00088 if (positionAli != theAlignableToMomentumRangeMap.end()) {
00089 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(param);
00090 if (positionParam!=(*positionAli).second.end()) {
00091 if (instance>=(*positionParam).second.size()) {
00092 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::alignableLabelFromParamAndMomentum"
00093 << "iovIdx out of bounds";
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=MomentumDependentPedeLabeler::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 MomentumDependentPedeLabeler::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=MomentumDependentPedeLabeler::lasBeamLabel"
00122 << "No label for beam Id " << lasBeamId;
00123 return 0;
00124 }
00125 }
00126
00127
00128 unsigned int MomentumDependentPedeLabeler::parameterLabel(unsigned int aliLabel, unsigned int parNum) const
00129 {
00130 if (parNum >= theMaxNumParam) {
00131 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::parameterLabel"
00132 << "Parameter number " << parNum
00133 << " out of range 0 <= num < " << theMaxNumParam;
00134 }
00135 return aliLabel + parNum;
00136 }
00137
00138
00139 unsigned int MomentumDependentPedeLabeler::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=MomentumDependentPedeLabeler::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 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00155 if (positionAli != theAlignableToMomentumRangeMap.end()) {
00156
00157 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(parNum);
00158 if (positionParam!=(*positionAli).second.end()) {
00159
00160 int offset = 0;
00161 float mom = tsos.globalMomentum().mag();
00162 const MomentumRangeVector & momentumRanges = (*positionParam).second;
00163 for (MomentumRangeVector::const_iterator iMomentum = momentumRanges.begin();
00164 iMomentum != momentumRanges.end();
00165 ++iMomentum) {
00166
00167 if (iMomentum->first<=mom && mom<iMomentum->second) {
00168 return position->second + offset * theParamInstanceOffset + parNum;
00169 }
00170 offset++;
00171 }
00172 const DetId detId(alignable->id());
00173 edm::LogError("LogicError")
00174 << "@SUB=MomentumDependentPedeLabeler::alignableLabel" << "Alignable "
00175 << typeid(*alignable).name() << " not in map, det/subdet/alignableStructureType = "
00176 << detId.det() << "/" << detId.subdetId() << "/" << alignable->alignableObjectId();
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=MomentumDependentPedeLabeler::alignableLabel" << "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 MomentumDependentPedeLabeler::hasSplitParameters(Alignable *alignable) const
00198 {
00199 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00200 if (positionAli != theAlignableToMomentumRangeMap.end()) return true;
00201 return false;
00202 }
00203
00204
00205 unsigned int MomentumDependentPedeLabeler::numberOfParameterInstances(Alignable *alignable, int param) const
00206 {
00207 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(alignable);
00208 if (positionAli != theAlignableToMomentumRangeMap.end()) {
00209
00210 size_t nMomentums = 1;
00211 if (param==-1) {
00212 for (MomentumRangeParamMap::const_iterator iParam = (*positionAli).second.begin();
00213 iParam != (*positionAli).second.end();
00214 ++iParam) {
00215 nMomentums = std::max(nMomentums, iParam->second.size());
00216 }
00217 return nMomentums;
00218 } else {
00219 MomentumRangeParamMap::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 MomentumDependentPedeLabeler::paramNumFromLabel(unsigned int paramLabel) const
00233 {
00234 if (paramLabel < theMinLabel) {
00235 edm::LogError("LogicError") << "@SUB=MomentumDependentPedeLabeler::paramNumFromLabel"
00236 << "Label " << paramLabel << " should be >= " << theMinLabel;
00237 return 0;
00238 }
00239 return (paramLabel - theMinLabel) % theParamInstanceOffset;
00240 }
00241
00242
00243 unsigned int MomentumDependentPedeLabeler::alignableLabelFromLabel(unsigned int paramLabel) const
00244 {
00245 return paramLabel - this->paramNumFromLabel(paramLabel);
00246 }
00247
00248
00249 Alignable* MomentumDependentPedeLabeler::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<MomentumDependentPedeLabeler*>(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=MomentumDependentPedeLabeler::alignableFromLabel"
00263 << "Alignable label " << aliLabel << " not in map.";
00264 }
00265 return 0;
00266 }
00267 }
00268
00269
00270 unsigned int MomentumDependentPedeLabeler::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<MomentumDependentPedeLabeler*>(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=MomentumDependentPedeLabeler::lasBeamIdFromLabel"
00281 << "Alignable label " << aliLabel << " not in map.";
00282 return 0;
00283 }
00284 }
00285
00286
00287 std::vector<std::string> MomentumDependentPedeLabeler::decompose(const std::string &s,
00288 std::string::value_type delimiter) const
00289 {
00290 std::vector<std::string> result;
00291
00292 std::string::size_type previousPos = 0;
00293 while (true) {
00294 const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
00295 if (delimiterPos == std::string::npos) {
00296 result.push_back(s.substr(previousPos));
00297 break;
00298 }
00299 result.push_back(s.substr(previousPos, delimiterPos - previousPos));
00300 previousPos = delimiterPos + 1;
00301 }
00302
00303 return result;
00304 }
00305
00306
00307 std::vector<unsigned int> MomentumDependentPedeLabeler::convertParamSel(const std::string &selString) const
00308 {
00309 std::vector<unsigned int> result;
00310 for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
00311 if (selString[pos]=='1') result.push_back(pos);
00312 }
00313 return result;
00314 }
00315
00316 unsigned int MomentumDependentPedeLabeler::buildMomentumDependencyMap(AlignableTracker *aliTracker,
00317 AlignableMuon* aliMuon,
00318 AlignableExtras *aliExtras,
00319 const edm::ParameterSet &config)
00320 {
00321 theAlignableToMomentumRangeMap.clear();
00322
00323 AlignmentParameterSelector selector(aliTracker, aliMuon, aliExtras);
00324
00325 std::vector<char> paramSelDumthe(6, '1');
00326
00327 const std::vector<edm::ParameterSet> parameterInstancesVPSet =
00328 config.getParameter<std::vector<edm::ParameterSet> >("parameterInstances");
00329
00330 for (std::vector<edm::ParameterSet>::const_iterator iter = parameterInstancesVPSet.begin();
00331 iter != parameterInstancesVPSet.end();
00332 ++iter) {
00333
00334 const std::vector<std::string> tempMomentumRanges = (*iter).getParameter<std::vector<std::string> >("momentumRanges");
00335 if (tempMomentumRanges.size()==0) {
00336 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00337 << "MomentumRanges empty\n";
00338 }
00339
00340 MomentumRangeVector MomentumRanges;
00341 float lower;
00342 float upper;
00343 for (unsigned int iMomentum=0;iMomentum<tempMomentumRanges.size();++iMomentum) {
00344 std::vector<std::string> tokens = edm::tokenize(tempMomentumRanges[iMomentum], ":");
00345
00346 lower = strtod(tokens[0].c_str(), 0);
00347 upper = strtod(tokens[1].c_str(), 0);
00348
00349 MomentumRanges.push_back(std::pair<float,float>(lower, upper));
00350 }
00351
00352 const std::vector<std::string> selStrings = (*iter).getParameter<std::vector<std::string> >("selector");
00353 for (std::vector<std::string>::const_iterator iSel = selStrings.begin();
00354 iSel != selStrings.end();
00355 ++iSel) {
00356 std::vector<std::string> decompSel(this->decompose(*iSel, ','));
00357
00358 if (decompSel.size()!=2) {
00359 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00360 << *iSel <<" should have at least 2 ','-separated parts\n";
00361 }
00362
00363 std::vector<unsigned int> selParam = this->convertParamSel(decompSel[1]);
00364 selector.clear();
00365 selector.addSelection(decompSel[0], paramSelDumthe);
00366
00367 const std::vector<Alignable*> &alis = selector.selectedAlignables();
00368 for (std::vector<Alignable*>::const_iterator iAli = alis.begin();
00369 iAli != alis.end();
00370 ++iAli) {
00371 for (std::vector<unsigned int>::const_iterator iParam = selParam.begin();
00372 iParam != selParam.end();
00373 ++iParam) {
00374 AlignableToMomentumRangeMap::const_iterator positionAli = theAlignableToMomentumRangeMap.find(*iAli);
00375 if (positionAli!=theAlignableToMomentumRangeMap.end()) {
00376
00377 AlignmentParameters *AliParams = (*positionAli).first->alignmentParameters();
00378 if (static_cast<int>(selParam[selParam.size()-1]) >= AliParams->size()) {
00379 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00380 << "mismatch in number of parameters\n";
00381 }
00382
00383 MomentumRangeParamMap::const_iterator positionParam = (*positionAli).second.find(*iParam);
00384 if (positionParam!=(*positionAli).second.end()) {
00385 throw cms::Exception("BadConfig") << "@SUB=MomentumDependentPedeLabeler::buildMomentumDependencyMap\n"
00386 << "Momentum range for parameter specified twice\n";
00387 }
00388 }
00389
00390 theAlignableToMomentumRangeMap[*iAli][*iParam] = MomentumRanges;
00391 }
00392 }
00393 }
00394 }
00395
00396 return theAlignableToMomentumRangeMap.size();
00397 }
00398
00399
00400 unsigned int MomentumDependentPedeLabeler::buildMap(const std::vector<Alignable*> &alis)
00401 {
00402 theAlignableToIdMap.clear();
00403
00404 std::vector<Alignable*> allComps;
00405
00406 for (std::vector<Alignable*>::const_iterator iAli = alis.begin(); iAli != alis.end(); ++iAli) {
00407 if (*iAli) {
00408 allComps.push_back(*iAli);
00409 (*iAli)->recursiveComponents(allComps);
00410 }
00411 }
00412
00413 unsigned int id = theMinLabel;
00414 for (std::vector<Alignable*>::const_iterator iter = allComps.begin();
00415 iter != allComps.end(); ++iter) {
00416 theAlignableToIdMap.insert(AlignableToIdPair(*iter, id));
00417 id += theMaxNumParam;
00418 }
00419
00420
00421 theLasBeamToLabelMap.clear();
00422
00423
00424 unsigned int beamIds[] = { 0, 10, 20, 30, 40, 50, 60, 70,
00425 1, 11, 21, 31, 41, 51, 61, 71,
00426 100, 110, 120, 130, 140, 150, 160, 170,
00427 101, 111, 121, 131, 141, 151, 161, 171,
00428 200, 210, 220, 230, 240, 250, 260, 270};
00429
00430 const size_t nBeams = sizeof(beamIds)/sizeof(beamIds[0]);
00431 for (size_t iBeam = 0; iBeam < nBeams; ++iBeam) {
00432
00433 theLasBeamToLabelMap[beamIds[iBeam]] = id;
00434 id += theMaxNumParam;
00435 }
00436
00437 if (id > theParamInstanceOffset) {
00438 throw cms::Exception("Alignment") << "@SUB=MomentumDependentPedeLabeler::buildMap: "
00439 << "Too many labels per instance (" << id-1 << ") leading to double use, "
00440 << "increase PedeLabelerBase::theParamInstanceOffset!\n";
00441 }
00442
00443 return theAlignableToIdMap.size() + theLasBeamToLabelMap.size();
00444 }
00445
00446
00447 unsigned int MomentumDependentPedeLabeler::buildReverseMap()
00448 {
00449
00450 theIdToAlignableMap.clear();
00451
00452 for (AlignableToIdMap::iterator it = theAlignableToIdMap.begin();
00453 it != theAlignableToIdMap.end(); ++it) {
00454 const unsigned int key = (*it).second;
00455 Alignable *ali = (*it).first;
00456 const unsigned int nInstances = this->numberOfParameterInstances(ali, -1);
00457 theMaxNumberOfParameterInstances = std::max(nInstances, theMaxNumberOfParameterInstances);
00458 for (unsigned int iInstance=0;iInstance<nInstances;++iInstance) {
00459 theIdToAlignableMap[key+iInstance*theParamInstanceOffset] = ali;
00460 }
00461 }
00462
00463
00464 theLabelToLasBeamMap.clear();
00465
00466 for (UintUintMap::const_iterator it = theLasBeamToLabelMap.begin();
00467 it != theLasBeamToLabelMap.end(); ++it) {
00468 theLabelToLasBeamMap[it->second] = it->first;
00469 }
00470
00471
00472 return theIdToAlignableMap.size() + theLabelToLasBeamMap.size();
00473 }
00474
00475 #include "Alignment/MillePedeAlignmentAlgorithm/interface/PedeLabelerPluginFactory.h"
00476 DEFINE_EDM_PLUGIN(PedeLabelerPluginFactory, MomentumDependentPedeLabeler, "MomentumDependentPedeLabeler");