CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/CommonAlignmentAlgorithm/src/AlignmentParameterSelector.cc

Go to the documentation of this file.
00001 
00009 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
00010 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
00011 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
00012 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
00013 #include "Alignment/TrackerAlignment/interface/TrackerAlignableId.h"
00014 
00015 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00016 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"  // for enums TID/TIB/etc.
00017 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00018 
00019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021 #include "FWCore/Utilities/interface/Exception.h"
00022 
00023 //________________________________________________________________________________
00024 AlignmentParameterSelector::AlignmentParameterSelector(AlignableTracker *aliTracker, AlignableMuon* aliMuon,
00025                                                        AlignableExtras *aliExtras) :
00026   theTracker(aliTracker), theMuon(aliMuon), theExtras(aliExtras), theSelectedAlignables(), 
00027   theRangesEta(), theRangesPhi(), theRangesR(), theRangesX(), theRangesY(), theRangesZ()
00028 {
00029   this->setSpecials(""); // init theOnlyDS, theOnlySS, theSelLayers, theMinLayer, theMaxLayer, theRphiOrStereoDetUnit
00030 }
00031 
00032 //________________________________________________________________________________
00033 void AlignmentParameterSelector::clear()
00034 {
00035   theSelectedAlignables.clear();
00036   theSelectedParameters.clear();
00037   this->clearGeometryCuts();
00038 }
00039 
00040 //________________________________________________________________________________
00041 void AlignmentParameterSelector::clearGeometryCuts()
00042 {
00043   theRangesEta.clear();
00044   theRangesPhi.clear();
00045   theRangesR.clear();
00046   theRangesX.clear();
00047   theRangesY.clear();
00048   theRangesZ.clear();
00049 
00050   thePXBDetIdRanges.clear();
00051   thePXFDetIdRanges.clear();
00052   theTIBDetIdRanges.clear();
00053   theTIDDetIdRanges.clear();
00054   theTOBDetIdRanges.clear();
00055   theTECDetIdRanges.clear();
00056 }
00057 
00058 const AlignableTracker* AlignmentParameterSelector::alignableTracker() const
00059 {
00060   return theTracker;
00061 }
00062 
00063 //__________________________________________________________________________________________________
00064 unsigned int AlignmentParameterSelector::addSelections(const edm::ParameterSet &pSet)
00065 {
00066 
00067   const std::vector<std::string> selections
00068     = pSet.getParameter<std::vector<std::string> >("alignParams");
00069   
00070   unsigned int addedSets = 0;
00071 
00072   for (unsigned int iSel = 0; iSel < selections.size(); ++iSel) {
00073     std::vector<std::string> decompSel(this->decompose(selections[iSel], ','));
00074     if (decompSel.empty()) continue; // edm::LogError or even cms::Exception??
00075 
00076     if (decompSel.size() < 2) {
00077       throw cms::Exception("BadConfig") << "@SUB=AlignmentParameterSelector::addSelections"
00078                                         << selections[iSel]<<" from alignableParamSelector: "
00079                                         << " should have at least 2 ','-separated parts";
00080     } else if (decompSel.size() > 2) {
00081       const edm::ParameterSet geoSel(pSet.getParameter<edm::ParameterSet>(decompSel[2].c_str()));
00082       this->addSelection(decompSel[0], this->convertParamSel(decompSel[1]), geoSel);
00083     } else {
00084       this->clearGeometryCuts();
00085       this->addSelection(decompSel[0], this->convertParamSel(decompSel[1]));
00086     }
00087     
00088     ++addedSets;
00089   }
00090 
00091   return addedSets;
00092 }
00093 
00094 //________________________________________________________________________________
00095 void AlignmentParameterSelector::setGeometryCuts(const edm::ParameterSet &pSet)
00096 {
00097   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
00098   // but take care that nothing unknown is configured (to fetch typos!). 
00099 
00100   this->clearGeometryCuts();
00101   const std::vector<std::string> parameterNames(pSet.getParameterNames());
00102   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(),
00103          iEnd = parameterNames.end(); iParam != iEnd; ++iParam) {
00104 
00105     // Calling swap is more efficient than assignment:
00106     if (*iParam == "etaRanges") {
00107       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesEta);
00108     } else if (*iParam == "phiRanges") {
00109       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesPhi);
00110     } else if (*iParam == "rRanges") {
00111       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesR);
00112     } else if (*iParam == "xRanges") {
00113       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesX);
00114     } else if (*iParam == "yRanges") {
00115       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesY);
00116     } else if (*iParam == "zRanges") {
00117       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesZ);
00118     } else if (*iParam == "detIds") {
00119       pSet.getParameter<std::vector<int> >(*iParam).swap(theDetIds);
00120     } else if (*iParam == "detIdRanges") {
00121       pSet.getParameter<std::vector<int> >(*iParam).swap(theDetIdRanges);
00122     } else if (*iParam == "excludedDetIds") {
00123       pSet.getParameter<std::vector<int> >(*iParam).swap(theExcludedDetIds);
00124     } else if (*iParam == "excludedDetIdRanges") {
00125       pSet.getParameter<std::vector<int> >(*iParam).swap(theExcludedDetIdRanges);
00126     } else if (*iParam == "pxbDetId") {
00127       const edm::ParameterSet & pxbDetIdPSet = pSet.getParameterSet(*iParam);
00128       this->setPXBDetIdCuts(pxbDetIdPSet);
00129     } else if (*iParam == "pxfDetId") {
00130       const edm::ParameterSet & pxfDetIdPSet = pSet.getParameterSet(*iParam);
00131       this->setPXFDetIdCuts(pxfDetIdPSet);
00132     } else if (*iParam == "tibDetId") {
00133       const edm::ParameterSet & tibDetIdPSet = pSet.getParameterSet(*iParam);
00134       this->setTIBDetIdCuts(tibDetIdPSet);
00135     } else if (*iParam == "tidDetId") {
00136       const edm::ParameterSet & tidDetIdPSet = pSet.getParameterSet(*iParam);
00137       this->setTIDDetIdCuts(tidDetIdPSet);
00138     } else if (*iParam == "tobDetId") {
00139       const edm::ParameterSet & tobDetIdPSet = pSet.getParameterSet(*iParam);
00140       this->setTOBDetIdCuts(tobDetIdPSet);
00141     } else if (*iParam == "tecDetId") {
00142       const edm::ParameterSet & tecDetIdPSet = pSet.getParameterSet(*iParam);
00143       this->setTECDetIdCuts(tecDetIdPSet);
00144     } else {
00145       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setGeometryCuts] "
00146                                         << "Unknown parameter '" << *iParam << "'.\n";
00147     }
00148   }
00149 }
00150 
00151 //________________________________________________________________________________
00152 void AlignmentParameterSelector::setPXBDetIdCuts(const edm::ParameterSet &pSet)
00153 {
00154   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
00155   // but take care that nothing unknown is configured (to fetch typos!). 
00156 
00157   const std::vector<std::string> parameterNames(pSet.getParameterNames());
00158   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(),
00159          iEnd = parameterNames.end(); iParam != iEnd; ++iParam) {
00160 
00161     // Calling swap is more efficient than assignment:
00162     if (*iParam == "ladderRanges") {
00163       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXBDetIdRanges.theLadderRanges);
00164     } else if (*iParam == "layerRanges") {
00165       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXBDetIdRanges.theLayerRanges);
00166     } else if (*iParam == "moduleRanges") {
00167       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXBDetIdRanges.theModuleRanges);
00168     } else {
00169       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setPXBDetIdCuts] "
00170                                         << "Unknown parameter '" << *iParam << "'.\n";
00171     }
00172   }
00173 }
00174 
00175 //________________________________________________________________________________
00176 void AlignmentParameterSelector::setPXFDetIdCuts(const edm::ParameterSet &pSet)
00177 {
00178   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
00179   // but take care that nothing unknown is configured (to fetch typos!). 
00180 
00181   const std::vector<std::string> parameterNames(pSet.getParameterNames());
00182   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(),
00183          iEnd = parameterNames.end(); iParam != iEnd; ++iParam) {
00184 
00185     // Calling swap is more efficient than assignment:
00186     if (*iParam == "bladeRanges") {
00187       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.theBladeRanges);
00188     } else if (*iParam == "diskRanges") {
00189       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.theDiskRanges);
00190     } else if (*iParam == "moduleRanges") {
00191       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.theModuleRanges);
00192     } else if (*iParam == "panelRanges") {
00193       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.thePanelRanges);
00194     } else if (*iParam == "sideRanges") {
00195       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.theSideRanges);
00196     } else {
00197       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setPXFDetIdCuts] "
00198                                         << "Unknown parameter '" << *iParam << "'.\n";
00199     }
00200   }
00201 }
00202 
00203 //________________________________________________________________________________
00204 void AlignmentParameterSelector::setTIBDetIdCuts(const edm::ParameterSet &pSet)
00205 {
00206   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
00207   // but take care that nothing unknown is configured (to fetch typos!). 
00208 
00209   const std::vector<std::string> parameterNames(pSet.getParameterNames());
00210   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(),
00211          iEnd = parameterNames.end(); iParam != iEnd; ++iParam) {
00212 
00213     // Calling swap is more efficient than assignment:
00214     if (*iParam == "layerRanges") {
00215       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIBDetIdRanges.theLayerRanges);
00216     } else if (*iParam == "moduleRanges") {
00217       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIBDetIdRanges.theModuleRanges);
00218     } else if (*iParam == "stringRanges") {
00219       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIBDetIdRanges.theStringRanges);
00220     } else if (*iParam == "sideRanges") {
00221       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIBDetIdRanges.theSideRanges);
00222     } else {
00223       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setTIBDetIdCuts] "
00224                                         << "Unknown parameter '" << *iParam << "'.\n";
00225     }
00226   }
00227 }
00228 
00229 //________________________________________________________________________________
00230 void AlignmentParameterSelector::setTIDDetIdCuts(const edm::ParameterSet &pSet)
00231 {
00232   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
00233   // but take care that nothing unknown is configured (to fetch typos!). 
00234 
00235   const std::vector<std::string> parameterNames(pSet.getParameterNames());
00236   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(),
00237          iEnd = parameterNames.end(); iParam != iEnd; ++iParam) {
00238 
00239     // Calling swap is more efficient than assignment:
00240     if (*iParam == "diskRanges") {
00241       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIDDetIdRanges.theDiskRanges);
00242     } else if (*iParam == "moduleRanges") {
00243       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIDDetIdRanges.theModuleRanges);
00244     } else if (*iParam == "ringRanges") {
00245       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIDDetIdRanges.theRingRanges);
00246     } else if (*iParam == "sideRanges") {
00247       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIDDetIdRanges.theSideRanges);
00248     } else {
00249       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setTIDDetIdCuts] "
00250                                         << "Unknown parameter '" << *iParam << "'.\n";
00251     }
00252   }
00253 }
00254 
00255 //________________________________________________________________________________
00256 void AlignmentParameterSelector::setTOBDetIdCuts(const edm::ParameterSet &pSet)
00257 {
00258   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
00259   // but take care that nothing unknown is configured (to fetch typos!). 
00260 
00261   const std::vector<std::string> parameterNames(pSet.getParameterNames());
00262   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(),
00263          iEnd = parameterNames.end(); iParam != iEnd; ++iParam) {
00264 
00265     // Calling swap is more efficient than assignment:
00266     if (*iParam == "layerRanges") {
00267       pSet.getParameter<std::vector<int> >(*iParam).swap(theTOBDetIdRanges.theLayerRanges);
00268     } else if (*iParam == "moduleRanges") {
00269       pSet.getParameter<std::vector<int> >(*iParam).swap(theTOBDetIdRanges.theModuleRanges);
00270     } else if (*iParam == "sideRanges") {
00271       pSet.getParameter<std::vector<int> >(*iParam).swap(theTOBDetIdRanges.theSideRanges);
00272     } else if (*iParam == "rodRanges") {
00273       pSet.getParameter<std::vector<int> >(*iParam).swap(theTOBDetIdRanges.theRodRanges);
00274     } else {
00275       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setTOBDetIdCuts] "
00276                                         << "Unknown parameter '" << *iParam << "'.\n";
00277     }
00278   }
00279 }
00280 
00281 //________________________________________________________________________________
00282 void AlignmentParameterSelector::setTECDetIdCuts(const edm::ParameterSet &pSet)
00283 {
00284   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
00285   // but take care that nothing unknown is configured (to fetch typos!). 
00286 
00287   const std::vector<std::string> parameterNames(pSet.getParameterNames());
00288   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(),
00289          iEnd = parameterNames.end(); iParam != iEnd; ++iParam) {
00290 
00291     // Calling swap is more efficient than assignment:
00292     if (*iParam == "wheelRanges") {
00293       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.theWheelRanges);
00294     } else if (*iParam == "petalRanges") {
00295       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.thePetalRanges);
00296     } else if (*iParam == "moduleRanges") {
00297       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.theModuleRanges);
00298     } else if (*iParam == "ringRanges") {
00299       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.theRingRanges);
00300     } else if (*iParam == "sideRanges") {
00301       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.theSideRanges);
00302     } else {
00303       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setTECDetIdCuts] "
00304                                         << "Unknown parameter '" << *iParam << "'.\n";
00305     }
00306   }
00307 }
00308 
00309 //________________________________________________________________________________
00310 unsigned int AlignmentParameterSelector::addSelection(const std::string &name,
00311                                                       const std::vector<char> &paramSel,
00312                                                       const edm::ParameterSet &pSet)
00313 {
00314   this->setGeometryCuts(pSet);
00315   return this->addSelection(name, paramSel);
00316 }
00317 
00318 //________________________________________________________________________________
00319 unsigned int AlignmentParameterSelector::addSelection(const std::string &nameInput, 
00320                                                       const std::vector<char> &paramSel)
00321 {
00322   const std::string name(this->setSpecials(nameInput)); // possibly changing name
00323 
00324   unsigned int numAli = 0;
00325 
00327   // Generic Tracker Section
00329   if (name.find("Tracker") == 0) { // string starts with "Tracker"
00330     if (!theTracker) {
00331       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::addSelection] "
00332                                         << "Configuration requires access to AlignableTracker"
00333                                         << " (for " << name << ") that is not initialized";
00334     }
00335     const std::string substructName(name, 7); // erase "Tracker" at the beginning
00336     numAli += this->add(theTracker->subStructures(substructName), paramSel);
00337   }
00339   // Old hardcoded (i.e. deprecated) tracker section (NOTE: no check on theTracker != 0)
00341   else if (name == "AllDets")       numAli += this->addAllDets(paramSel);
00342   else if (name == "AllRods")       numAli += this->addAllRods(paramSel);
00343   else if (name == "AllLayers")     numAli += this->addAllLayers(paramSel);
00344   else if (name == "AllComponents") numAli += this->add(theTracker->components(), paramSel);
00345   else if (name == "AllAlignables") numAli += this->addAllAlignables(paramSel);
00346   //
00347   // TIB+TOB
00348   //
00349   else if (name == "BarrelRods")   numAli += this->add(theTracker->barrelRods(), paramSel);
00350   else if (name == "BarrelDets")   numAli += this->add(theTracker->barrelGeomDets(), paramSel);
00351   else if (name == "BarrelLayers") numAli += this->add(theTracker->barrelLayers(), paramSel);
00352   else if (name == "TOBDets")      numAli += this->add(theTracker->outerBarrelGeomDets(), paramSel);
00353   else if (name == "TOBRods")      numAli += this->add(theTracker->outerBarrelRods(), paramSel);
00354   else if (name == "TOBLayers")    numAli += this->add(theTracker->outerBarrelLayers(), paramSel);
00355   else if (name == "TOBHalfBarrels") numAli += this->add(theTracker->outerHalfBarrels(), paramSel);
00356   else if (name == "TIBDets")      numAli += this->add(theTracker->innerBarrelGeomDets(), paramSel);
00357   else if (name == "TIBRods")      numAli += this->add(theTracker->innerBarrelRods(), paramSel);
00358   else if (name == "TIBLayers")    numAli += this->add(theTracker->innerBarrelLayers(), paramSel);
00359   else if (name == "TIBHalfBarrels") numAli += this->add(theTracker->innerHalfBarrels(), paramSel);
00360   //
00361   // PXBarrel
00362   //
00363   else if (name == "PixelHalfBarrelDets") {
00364     numAli += this->add(theTracker->pixelHalfBarrelGeomDets(), paramSel);
00365   } else if (name == "PixelHalfBarrelLadders") {
00366     numAli += this->add(theTracker->pixelHalfBarrelLadders(), paramSel);
00367   } else if (name == "PixelHalfBarrelLayers") {
00368     numAli += this->add(theTracker->pixelHalfBarrelLayers(), paramSel);
00369   } else if (name == "PixelHalfBarrels") {
00370     numAli += this->add(theTracker->pixelHalfBarrels(), paramSel);
00371   }
00372   //
00373   // PXEndcap
00374   //
00375   else if (name == "PXECDets") numAli += this->add(theTracker->pixelEndcapGeomDets(), paramSel);
00376   else if (name == "PXECPetals") numAli += this->add(theTracker->pixelEndcapPetals(), paramSel);
00377   else if (name == "PXECLayers") numAli += this->add(theTracker->pixelEndcapLayers(), paramSel);
00378   else if (name == "PXEndCaps") numAli += this->add(theTracker->pixelEndCaps(), paramSel);
00379   //
00380   // Pixel Barrel+endcap
00381   //
00382   else if (name == "PixelDets") {
00383     numAli += this->add(theTracker->pixelHalfBarrelGeomDets(), paramSel);
00384     numAli += this->add(theTracker->pixelEndcapGeomDets(), paramSel);
00385   } else if (name == "PixelRods") {
00386     numAli += this->add(theTracker->pixelHalfBarrelLadders(), paramSel);
00387     numAli += this->add(theTracker->pixelEndcapPetals(), paramSel);
00388   } else if (name == "PixelLayers") {
00389     numAli += this->add(theTracker->pixelHalfBarrelLayers(), paramSel);
00390     numAli += this->add(theTracker->pixelEndcapLayers(), paramSel);
00391   }
00392   //
00393   // TID
00394   //
00395   else if (name == "TIDs")          numAli += this->add(theTracker->TIDs(), paramSel);
00396   else if (name == "TIDLayers")     numAli += this->add(theTracker->TIDLayers(), paramSel);
00397   else if (name == "TIDRings")      numAli += this->add(theTracker->TIDRings(), paramSel);
00398   else if (name == "TIDDets")       numAli += this->add(theTracker->TIDGeomDets(), paramSel);
00399   //
00400   // TEC
00401   //
00402   else if (name == "TECDets")       numAli += this->add(theTracker->endcapGeomDets(), paramSel);
00403   else if (name == "TECPetals")     numAli += this->add(theTracker->endcapPetals(), paramSel);
00404   else if (name == "TECLayers")     numAli += this->add(theTracker->endcapLayers(), paramSel);
00405   else if (name == "TECs")          numAli += this->add(theTracker->endCaps(), paramSel);
00406   //
00407   // StripEndcap (TID+TEC)
00408   //
00409   else if (name == "EndcapDets") {
00410     numAli += this->add(theTracker->TIDGeomDets(), paramSel);
00411     numAli += this->add(theTracker->endcapGeomDets(), paramSel); 
00412   } else if (name == "EndcapPetals") {
00413     numAli += this->add(theTracker->TIDRings(), paramSel);
00414     numAli += this->add(theTracker->endcapPetals(), paramSel);
00415   } else if (name == "EndcapLayers") {
00416     numAli += this->add(theTracker->TIDLayers(), paramSel);
00417     numAli += this->add(theTracker->endcapLayers(), paramSel);
00418   }
00419   //
00420   // Strip Barrel+endcap
00421   //
00422   else if (name == "StripDets") {
00423     numAli += this->add(theTracker->barrelGeomDets(), paramSel);
00424     numAli += this->add(theTracker->TIDGeomDets(), paramSel);
00425     numAli += this->add(theTracker->endcapGeomDets(), paramSel); 
00426   } else if (name == "StripRods") {
00427     numAli += this->add(theTracker->barrelRods(), paramSel);
00428     numAli += this->add(theTracker->TIDRings(), paramSel);
00429     numAli += this->add(theTracker->endcapPetals(), paramSel);
00430   } else if (name == "StripLayers") {
00431     numAli += this->add(theTracker->barrelLayers(), paramSel);
00432     numAli += this->add(theTracker->TIDLayers(), paramSel);
00433     numAli += this->add(theTracker->endcapLayers(), paramSel);
00434   }
00436   // Muon selection
00438   // Check if name contains muon and react if alignable muon not initialized
00439   else if (name.find("Muon") != std::string::npos) {
00440     if  (!theMuon) {
00441       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::addSelection] "
00442                                         << "Configuration requires access to AlignableMuon"
00443                                         << " which is not initialized";
00444     }
00445     else if (name == "MuonDTLayers")             add(theMuon->DTLayers(), paramSel);
00446     else if (name == "MuonDTSuperLayers")        add(theMuon->DTSuperLayers(), paramSel);
00447     else if (name == "MuonDTChambers")           add(theMuon->DTChambers(), paramSel);
00448     else if (name == "MuonDTStations")           add(theMuon->DTStations(), paramSel);
00449     else if (name == "MuonDTWheels")             add(theMuon->DTWheels(), paramSel);
00450     else if (name == "MuonBarrel")               add(theMuon->DTBarrel(), paramSel);
00451     else if (name == "MuonCSCLayers")            add(theMuon->CSCLayers(), paramSel);
00452     else if (name == "MuonCSCRings")             add(theMuon->CSCRings(), paramSel);
00453     else if (name == "MuonCSCChambers")          add(theMuon->CSCChambers(), paramSel);
00454     else if (name == "MuonCSCStations")          add(theMuon->CSCStations(), paramSel);
00455     else if (name == "MuonEndcaps")              add(theMuon->CSCEndcaps(), paramSel);
00456 
00458     // not found, but Muon
00460     else {
00461       throw cms::Exception("BadConfig") <<"[AlignmentParameterSelector::addSelection]"
00462                                         << ": Selection '" << name << "' invalid!";
00463     }
00464   }
00465 
00467   // Generic Extra Alignable Section
00469   else if (name.find("Extras") == 0) { // string starts with "Extras"
00470     if (!theExtras) {
00471       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::addSelection] "
00472                                         << "Configuration requires access to AlignableExtras"
00473                                         << " (for " << name << ") that is not initialized";
00474     }
00475     const std::string substructName(name, 6); // erase "Extras" at the beginning
00476     numAli += this->add(theExtras->subStructures(substructName), paramSel);
00477   }
00478   // end of "name.find("Extras") != std::string::npos"
00479 
00480   else {
00481     throw cms::Exception("BadConfig") <<"[AlignmentParameterSelector::addSelection]"
00482                                       << ": Selection '" << name << "' invalid!";
00483   }
00484   
00485   this->setSpecials(""); // reset
00486 
00487   return numAli;
00488 }
00489 
00490 //________________________________________________________________________________
00491 unsigned int AlignmentParameterSelector::add(const align::Alignables &alignables,
00492                                              const std::vector<char> &paramSel)
00493 {
00494   unsigned int numAli = 0;
00495 
00496   // loop on Alignable objects
00497   for (align::Alignables::const_iterator iAli = alignables.begin();
00498        iAli != alignables.end(); ++iAli) {
00499 
00500     if (!this->layerDeselected(*iAli)             // check layers
00501         && !this->detUnitDeselected(*iAli)        // check detunit selection
00502         && !this->outsideGeometricalRanges(*iAli) // check geometrical ranges
00503         && !this->outsideDetIdRanges(*iAli)) {    // check DetId ranges
00504       // all fine, so add to output arrays
00505       theSelectedAlignables.push_back(*iAli);
00506       theSelectedParameters.push_back(paramSel);
00507       ++numAli;
00508     }
00509   }
00510 
00511   return numAli;
00512 }
00513 
00514 //_________________________________________________________________________
00515 bool AlignmentParameterSelector::layerDeselected(const Alignable *ali) const
00516 {
00517   if (theOnlySS || theOnlyDS || theSelLayers) {
00518     TrackerAlignableId idProvider;
00519     std::pair<int,int> typeLayer = idProvider.typeAndLayerFromDetId(ali->id(), alignableTracker()->trackerTopology());
00520     int type  = typeLayer.first;
00521     int layer = typeLayer.second;
00522     
00523     // select on single/double sided barrel layers in TIB/TOB
00524     if (theOnlySS // only single sided
00525         && (std::abs(type) == SiStripDetId::TIB || std::abs(type) == SiStripDetId::TOB)
00526         && layer <= 2) {
00527       return true;
00528     }
00529     if (theOnlyDS // only double sided
00530         && (std::abs(type) == SiStripDetId::TIB || std::abs(type) == SiStripDetId::TOB)
00531         && layer > 2) {
00532       return true;
00533     }
00534     
00535     // reject layers
00536     if (theSelLayers && (layer < theMinLayer || layer > theMaxLayer)) {
00537       return true;
00538     }
00539   }
00540   
00541   return false; // do not deselect...
00542 }
00543 
00544 //_________________________________________________________________________
00545 bool AlignmentParameterSelector::detUnitDeselected(const Alignable *ali) const
00546 {
00547 
00548   if (theRphiOrStereoDetUnit != Both && ali->alignableObjectId() == align::AlignableDetUnit) {
00549     const SiStripDetId detId(ali->geomDetId()); // do not know yet whether right type...
00550     if (detId.det() == DetId::Tracker 
00551         && (detId.subdetId() == SiStripDetId::TIB || detId.subdetId() == SiStripDetId::TID ||
00552             detId.subdetId() == SiStripDetId::TOB || detId.subdetId() == SiStripDetId::TEC)) {
00553       // We have a DetUnit in strip, so check for a selection of stereo/rphi (DetUnits in 1D layers are rphi):
00554       if ((theRphiOrStereoDetUnit == Stereo && !detId.stereo())
00555           || (theRphiOrStereoDetUnit == Rphi   &&  detId.stereo())) {
00556         return true;
00557       }
00558     }
00559   }
00560 
00561   return false; // do not deselect...
00562 }
00563 
00564 //_________________________________________________________________________
00565 bool AlignmentParameterSelector::outsideGeometricalRanges(const Alignable *alignable) const
00566 {
00567   const align::PositionType& position(alignable->globalPosition());
00568 
00569   if (!theRangesEta.empty() && !this->insideRanges<double>((position.eta()),  theRangesEta)) return true;
00570   if (!theRangesPhi.empty() && !this->insideRanges<double>((position.phi()),  theRangesPhi, true))return true;
00571   if (!theRangesR.empty()   && !this->insideRanges<double>((position.perp()), theRangesR)) return true;
00572   if (!theRangesX.empty()   && !this->insideRanges<double>((position.x()),    theRangesX)) return true;
00573   if (!theRangesY.empty()   && !this->insideRanges<double>((position.y()),    theRangesY)) return true;
00574   if (!theRangesZ.empty()   && !this->insideRanges<double>((position.z()),    theRangesZ)) return true;
00575   
00576   return false;
00577 }
00578 
00579 //_________________________________________________________________________
00580 bool AlignmentParameterSelector::outsideDetIdRanges(const Alignable *alignable) const
00581 {
00582   //const DetId detId(alignable->geomDetId());
00583   const DetId detId(alignable->id());
00584   const int subdetId = detId.subdetId();
00585   
00586   const TrackerTopology* tTopo = alignableTracker()->trackerTopology();
00587 
00588   if (!theDetIds.empty() &&
00589       !this->isMemberOfVector((detId.rawId()), theDetIds)) return true;
00590   if (!theDetIdRanges.empty() &&
00591       !this->insideRanges<int>((detId.rawId()), theDetIdRanges)) return true;
00592   if (!theExcludedDetIds.empty() &&
00593       this->isMemberOfVector((detId.rawId()), theExcludedDetIds)) return true;
00594   if (!theExcludedDetIdRanges.empty() &&
00595       this->insideRanges<int>((detId.rawId()), theExcludedDetIdRanges)) return true;
00596 
00597   if (detId.det()==DetId::Tracker) {
00598     
00599     if (subdetId==static_cast<int>(PixelSubdetector::PixelBarrel)) {
00600       if (!thePXBDetIdRanges.theLadderRanges.empty() && 
00601           !this->insideRanges<int>(tTopo->pxbLadder(detId), thePXBDetIdRanges.theLadderRanges)) return true;
00602       if (!thePXBDetIdRanges.theLayerRanges.empty() && 
00603           !this->insideRanges<int>(tTopo->pxbLayer(detId), thePXBDetIdRanges.theLayerRanges)) return true;
00604       if (!thePXBDetIdRanges.theModuleRanges.empty() && 
00605           !this->insideRanges<int>(tTopo->pxbModule(detId), thePXBDetIdRanges.theModuleRanges)) return true;
00606     }
00607     
00608     if (subdetId==static_cast<int>(PixelSubdetector::PixelEndcap)) {
00609       if (!thePXFDetIdRanges.theBladeRanges.empty() && 
00610           !this->insideRanges<int>(tTopo->pxfBlade(detId), thePXFDetIdRanges.theBladeRanges)) return true;
00611       if (!thePXFDetIdRanges.theDiskRanges.empty() && 
00612           !this->insideRanges<int>(tTopo->pxfDisk(detId), thePXFDetIdRanges.theDiskRanges)) return true;
00613       if (!thePXFDetIdRanges.theModuleRanges.empty() && 
00614           !this->insideRanges<int>(tTopo->pxfModule(detId), thePXFDetIdRanges.theModuleRanges)) return true;
00615       if (!thePXFDetIdRanges.thePanelRanges.empty() && 
00616           !this->insideRanges<int>(tTopo->pxfPanel(detId), thePXFDetIdRanges.thePanelRanges)) return true;
00617       if (!thePXFDetIdRanges.theSideRanges.empty() && 
00618           !this->insideRanges<int>(tTopo->pxfSide(detId), thePXFDetIdRanges.theSideRanges)) return true;
00619     }
00620     
00621     if (subdetId==static_cast<int>(SiStripDetId::TIB)) {
00622       if (!theTIBDetIdRanges.theLayerRanges.empty() && 
00623           !this->insideRanges<int>(tTopo->tibLayer(detId), theTIBDetIdRanges.theLayerRanges)) return true;
00624       if (!theTIBDetIdRanges.theModuleRanges.empty() && 
00625           !this->insideRanges<int>(tTopo->tibModule(detId), theTIBDetIdRanges.theModuleRanges)) return true;
00626       if (!theTIBDetIdRanges.theSideRanges.empty() && 
00627           !this->insideRanges<int>(tTopo->tibSide(detId), theTIBDetIdRanges.theSideRanges)) return true;
00628       if (!theTIBDetIdRanges.theStringRanges.empty() && 
00629           !this->insideRanges<int>(tTopo->tibString(detId), theTIBDetIdRanges.theStringRanges)) return true;
00630     }
00631     
00632     if (subdetId==static_cast<int>(SiStripDetId::TID)) {
00633       if (!theTIDDetIdRanges.theDiskRanges.empty() && 
00634           !this->insideRanges<int>(tTopo->tidWheel(detId), theTIDDetIdRanges.theDiskRanges)) return true;
00635       if (!theTIDDetIdRanges.theModuleRanges.empty() && 
00636           !this->insideRanges<int>(tTopo->tidModule(detId), theTIDDetIdRanges.theModuleRanges)) return true;
00637       if (!theTIDDetIdRanges.theRingRanges.empty() && 
00638           !this->insideRanges<int>(tTopo->tidRing(detId), theTIDDetIdRanges.theRingRanges)) return true;
00639       if (!theTIDDetIdRanges.theSideRanges.empty() && 
00640           !this->insideRanges<int>(tTopo->tidSide(detId), theTIDDetIdRanges.theSideRanges)) return true;
00641     }
00642     
00643     if (subdetId==static_cast<int>(SiStripDetId::TOB)) {
00644       if (!theTOBDetIdRanges.theLayerRanges.empty() && 
00645           !this->insideRanges<int>(tTopo->tobLayer(detId), theTOBDetIdRanges.theLayerRanges)) return true;
00646       if (!theTOBDetIdRanges.theModuleRanges.empty() && 
00647           !this->insideRanges<int>(tTopo->tobModule(detId), theTOBDetIdRanges.theModuleRanges)) return true;
00648       if (!theTOBDetIdRanges.theRodRanges.empty() && 
00649           !this->insideRanges<int>(tTopo->tobRod(detId), theTOBDetIdRanges.theRodRanges)) return true;
00650       if (!theTOBDetIdRanges.theSideRanges.empty() && 
00651           !this->insideRanges<int>(tTopo->tobSide(detId), theTOBDetIdRanges.theSideRanges)) return true;
00652     }
00653 
00654     if (subdetId==static_cast<int>(SiStripDetId::TEC)) {
00655       if (!theTECDetIdRanges.theWheelRanges.empty() && 
00656           !this->insideRanges<int>(tTopo->tecWheel(detId), theTECDetIdRanges.theWheelRanges)) return true;
00657       if (!theTECDetIdRanges.thePetalRanges.empty() && 
00658           !this->insideRanges<int>(tTopo->tecPetalNumber(detId), theTECDetIdRanges.thePetalRanges)) return true;
00659       if (!theTECDetIdRanges.theModuleRanges.empty() && 
00660           !this->insideRanges<int>(tTopo->tecModule(detId), theTECDetIdRanges.theModuleRanges)) return true;
00661       if (!theTECDetIdRanges.theRingRanges.empty() && 
00662           !this->insideRanges<int>(tTopo->tecRing(detId), theTECDetIdRanges.theRingRanges)) return true;
00663       if (!theTECDetIdRanges.theSideRanges.empty() && 
00664           !this->insideRanges<int>(tTopo->tecSide(detId), theTECDetIdRanges.theSideRanges)) return true;
00665     }
00666     
00667   }
00668   
00669   return false;
00670 }
00671 
00672 //_________________________________________________________________________
00673 template<typename T> bool AlignmentParameterSelector::insideRanges(T value,
00674                                                                    const std::vector<T> &ranges,
00675                                                                    bool isPhi) const
00676 {
00677   // might become templated on <double> ?
00678 
00679   if (ranges.size()%2 != 0) {
00680     cms::Exception("BadConfig") << "@SUB=AlignmentParameterSelector::insideRanges" 
00681                                 << " need even number of entries in ranges instead of "
00682                                 << ranges.size();
00683     return false;
00684   }
00685 
00686   for (unsigned int i = 0; i < ranges.size(); i += 2) {
00687     if (isPhi) { // mapping into (-pi,+pi] and checking for range including sign flip area
00688       Geom::Phi<double> rangePhi1(ranges[i]);
00689       Geom::Phi<double> rangePhi2(ranges[i+1]);
00690       Geom::Phi<double> valuePhi(value);
00691       if (rangePhi1 <= valuePhi && valuePhi < rangePhi2) { // 'normal'
00692         return true;
00693       }
00694       if (rangePhi2  < rangePhi1 && (rangePhi1 <= valuePhi || valuePhi < rangePhi2)) {// 'sign flip'
00695         return true;
00696       }
00697     } else if (ranges[i] <= value && value < ranges[i+1]) {
00698       return true;
00699     }
00700   }
00701   
00702   return false;
00703 }
00704 
00705 //_________________________________________________________________________
00706 template<> bool AlignmentParameterSelector::insideRanges<int>(int value,
00707                                                               const std::vector<int> &ranges,
00708                                                               bool /*isPhi*/) const
00709 {
00710   if (ranges.size()%2 != 0) {
00711     cms::Exception("BadConfig") << "@SUB=AlignmentParameterSelector::insideRanges" 
00712                                 << " need even number of entries in ranges instead of "
00713                                 << ranges.size();
00714     return false;
00715   }
00716 
00717   for (unsigned int i = 0; i < ranges.size(); i += 2) {
00718     if (ranges[i] <= value && value <= ranges[i+1]) return true;
00719   }
00720   
00721   return false;
00722 }
00723 
00724 bool AlignmentParameterSelector::isMemberOfVector(int value, const std::vector<int> &values) const
00725 {
00726   if (std::find(values.begin(), values.end(), value)!=values.end()) return true;
00727   return false;
00728 }
00729 
00730 //__________________________________________________________________________________________________
00731 std::vector<std::string> 
00732 AlignmentParameterSelector::decompose(const std::string &s, std::string::value_type delimiter) const
00733 {
00734 
00735   std::vector<std::string> result;
00736 
00737   std::string::size_type previousPos = 0;
00738   while (true) {
00739     const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
00740     if (delimiterPos == std::string::npos) {
00741       result.push_back(s.substr(previousPos)); // until end
00742       break;
00743     }
00744     result.push_back(s.substr(previousPos, delimiterPos - previousPos));
00745     previousPos = delimiterPos + 1; // +1: skip delimiter
00746   }
00747 
00748   return result;
00749 }
00750 
00751 //__________________________________________________________________________________________________
00752 std::vector<char> AlignmentParameterSelector::convertParamSel(const std::string &selString) const
00753 {
00754 
00755   // Convert selString into vector<char> of same length.
00756   // Note: Old implementation in AlignmentParameterBuilder was rigid in length,
00757   // expecting RigidBodyAlignmentParameters::N_PARAM.
00758   // But I prefer to be more general and allow other Alignables. It will throw anyway if
00759   // RigidBodyAlignmentParameters are build with wrong selection length.
00760   std::vector<char> result(selString.size());
00761 
00762   for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
00763     result[pos] = selString[pos];
00764   }
00765 
00766   return result;
00767 }
00768 
00769 
00770 //________________________________________________________________________________
00771 std::string AlignmentParameterSelector::setSpecials(const std::string &name)
00772 {
00773   // Use new string only, although direct erasing of found indicator causes problems for 'DSS',
00774   // but 'DSS' makes absolutely no sense!
00775   std::string newName(name); 
00776 
00777   const std::string::size_type ss = newName.rfind("SS");
00778   if (ss != std::string::npos) {
00779     newName.erase(ss, 2); // 2: length of 'SS'
00780     theOnlySS = true;
00781   } else {
00782     theOnlySS = false;
00783   }
00784 
00785   const std::string::size_type ds = newName.rfind("DS");
00786   if (ds != std::string::npos) {
00787     newName.erase(ds, 2); // 2: length of 'DS'
00788     theOnlyDS = true;
00789   } else {
00790     theOnlyDS = false;
00791   }
00792   
00793   const std::string::size_type size = newName.size();
00794   const std::string::size_type layers = newName.rfind("Layers");
00795   if (layers != std::string::npos && size - layers - 2 == 6 // 2 digits, 6: length of 'Layers'
00796       && isdigit(newName[size-1]) && isdigit(newName[size-2])) {
00797     theSelLayers = true;
00798     theMinLayer = newName[size-2] - '0';
00799     theMaxLayer = newName[size-1] - '0';
00800     newName.erase(layers);
00801   } else {
00802     theSelLayers = false;
00803     theMinLayer = -1;
00804     theMaxLayer = 99999;
00805   }
00806 
00807   theRphiOrStereoDetUnit = Both;
00808   if (newName.rfind("Unit") != std::string::npos) {
00809     const std::string::size_type uRph = newName.rfind("UnitRphi");
00810     if (uRph != std::string::npos) {
00811       newName.erase(uRph + 4, 4); // keep 'Unit' (4) and erase 'Rphi' (4)
00812       theRphiOrStereoDetUnit = Rphi;
00813     }
00814     const std::string::size_type uSte = newName.rfind("UnitStereo");
00815     if (uSte != std::string::npos) {
00816       newName.erase(uSte + 4, 6); // keep 'Unit' (4) and erase 'Stereo' (6)
00817       theRphiOrStereoDetUnit = Stereo;
00818     }
00819   }
00820 
00821   if (newName != name) {
00822     LogDebug("Alignment") << "@SUB=AlignmentParameterSelector::setSpecials"
00823                           << name << " becomes " << newName << ", makes theOnlySS " << theOnlySS
00824                           << ", theOnlyDS " << theOnlyDS << ", theSelLayers " << theSelLayers
00825                           << ", theMinLayer " << theMinLayer << ", theMaxLayer " << theMaxLayer
00826                           << ", theRphiOrStereoDetUnit " << theRphiOrStereoDetUnit;
00827   }
00828 
00829   return newName;
00830 }
00831 
00832 //________________________________________________________________________________
00833 unsigned int AlignmentParameterSelector::addAllDets(const std::vector<char> &paramSel)
00834 {
00835   unsigned int numAli = 0;
00836 
00837   numAli += this->add(theTracker->barrelGeomDets(), paramSel);          // TIB+TOB
00838   numAli += this->add(theTracker->endcapGeomDets(), paramSel);          // TEC
00839   numAli += this->add(theTracker->TIDGeomDets(), paramSel);             // TID
00840   numAli += this->add(theTracker->pixelHalfBarrelGeomDets(), paramSel); // PixelBarrel
00841   numAli += this->add(theTracker->pixelEndcapGeomDets(), paramSel);     // PixelEndcap
00842 
00843   return numAli;
00844 }
00845 
00846 //________________________________________________________________________________
00847 unsigned int AlignmentParameterSelector::addAllRods(const std::vector<char> &paramSel)
00848 {
00849   unsigned int numAli = 0;
00850 
00851   numAli += this->add(theTracker->barrelRods(), paramSel);             // TIB+TOB    
00852   numAli += this->add(theTracker->pixelHalfBarrelLadders(), paramSel); // PixelBarrel
00853   numAli += this->add(theTracker->endcapPetals(), paramSel);           // TEC        
00854   numAli += this->add(theTracker->TIDRings(), paramSel);               // TID        
00855   numAli += this->add(theTracker->pixelEndcapPetals(), paramSel);      // PixelEndcap
00856 
00857   return numAli;
00858 }
00859 
00860 //________________________________________________________________________________
00861 unsigned int AlignmentParameterSelector::addAllLayers(const std::vector<char> &paramSel)
00862 {
00863   unsigned int numAli = 0;
00864 
00865   numAli += this->add(theTracker->barrelLayers(), paramSel);          // TIB+TOB    
00866   numAli += this->add(theTracker->pixelHalfBarrelLayers(), paramSel); // PixelBarrel
00867   numAli += this->add(theTracker->endcapLayers(), paramSel);          // TEC
00868   numAli += this->add(theTracker->TIDLayers(), paramSel);             // TID
00869   numAli += this->add(theTracker->pixelEndcapLayers(), paramSel);     // PixelEndcap
00870 
00871   return numAli;
00872 }
00873 
00874 //________________________________________________________________________________
00875 unsigned int AlignmentParameterSelector::addAllAlignables(const std::vector<char> &paramSel)
00876 {
00877   unsigned int numAli = 0;
00878 
00879   numAli += this->addAllDets(paramSel);
00880   numAli += this->addAllRods(paramSel);
00881   numAli += this->addAllLayers(paramSel);
00882   numAli += this->add(theTracker->components(), paramSel);
00883 
00884   return numAli;
00885 }