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