CMS 3D CMS Logo

CMSSW_4_4_3_patch1/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/SiPixelDetId/interface/PXBDetId.h"
00017 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00018 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"  // for enums TID/TIB/etc.
00019 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00020 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00021 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00022 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00023 
00024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00026 #include "FWCore/Utilities/interface/Exception.h"
00027 
00028 //________________________________________________________________________________
00029 AlignmentParameterSelector::AlignmentParameterSelector(AlignableTracker *aliTracker, AlignableMuon* aliMuon,
00030                                                        AlignableExtras *aliExtras) :
00031   theTracker(aliTracker), theMuon(aliMuon), theExtras(aliExtras), theSelectedAlignables(), 
00032   theRangesEta(), theRangesPhi(), theRangesR(), theRangesX(), theRangesY(), theRangesZ()
00033 {
00034   this->setSpecials(""); // init theOnlyDS, theOnlySS, theSelLayers, theMinLayer, theMaxLayer, theRphiOrStereoDetUnit
00035 }
00036 
00037 //________________________________________________________________________________
00038 void AlignmentParameterSelector::clear()
00039 {
00040   theSelectedAlignables.clear();
00041   theSelectedParameters.clear();
00042   this->clearGeometryCuts();
00043 }
00044 
00045 //________________________________________________________________________________
00046 void AlignmentParameterSelector::clearGeometryCuts()
00047 {
00048   theRangesEta.clear();
00049   theRangesPhi.clear();
00050   theRangesR.clear();
00051   theRangesX.clear();
00052   theRangesY.clear();
00053   theRangesZ.clear();
00054 
00055   thePXBDetIdRanges.clear();
00056   thePXFDetIdRanges.clear();
00057   theTIBDetIdRanges.clear();
00058   theTIDDetIdRanges.clear();
00059   theTOBDetIdRanges.clear();
00060   theTECDetIdRanges.clear();
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());
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   if (!theDetIds.empty() &&
00587       !this->isMemberOfVector((detId.rawId()), theDetIds)) return true;
00588   if (!theDetIdRanges.empty() &&
00589       !this->insideRanges<int>((detId.rawId()), theDetIdRanges)) return true;
00590   if (!theExcludedDetIds.empty() &&
00591       this->isMemberOfVector((detId.rawId()), theExcludedDetIds)) return true;
00592   if (!theExcludedDetIdRanges.empty() &&
00593       this->insideRanges<int>((detId.rawId()), theExcludedDetIdRanges)) return true;
00594 
00595   if (detId.det()==DetId::Tracker) {
00596     
00597     if (subdetId==static_cast<int>(PixelSubdetector::PixelBarrel)) {
00598       const PXBDetId pxbDetId(detId);
00599       if (!thePXBDetIdRanges.theLadderRanges.empty() && 
00600           !this->insideRanges<int>(pxbDetId.ladder(), thePXBDetIdRanges.theLadderRanges)) return true;
00601       if (!thePXBDetIdRanges.theLayerRanges.empty() && 
00602           !this->insideRanges<int>(pxbDetId.layer(), thePXBDetIdRanges.theLayerRanges)) return true;
00603       if (!thePXBDetIdRanges.theModuleRanges.empty() && 
00604           !this->insideRanges<int>(pxbDetId.module(), thePXBDetIdRanges.theModuleRanges)) return true;
00605     }
00606     
00607     if (subdetId==static_cast<int>(PixelSubdetector::PixelEndcap)) {
00608       const PXFDetId pxfDetId(detId);
00609       if (!thePXFDetIdRanges.theBladeRanges.empty() && 
00610           !this->insideRanges<int>(pxfDetId.blade(), thePXFDetIdRanges.theBladeRanges)) return true;
00611       if (!thePXFDetIdRanges.theDiskRanges.empty() && 
00612           !this->insideRanges<int>(pxfDetId.disk(), thePXFDetIdRanges.theDiskRanges)) return true;
00613       if (!thePXFDetIdRanges.theModuleRanges.empty() && 
00614           !this->insideRanges<int>(pxfDetId.module(), thePXFDetIdRanges.theModuleRanges)) return true;
00615       if (!thePXFDetIdRanges.thePanelRanges.empty() && 
00616           !this->insideRanges<int>(pxfDetId.panel(), thePXFDetIdRanges.thePanelRanges)) return true;
00617       if (!thePXFDetIdRanges.theSideRanges.empty() && 
00618           !this->insideRanges<int>(pxfDetId.side(), thePXFDetIdRanges.theSideRanges)) return true;
00619     }
00620     
00621     if (subdetId==static_cast<int>(SiStripDetId::TIB)) {
00622       const TIBDetId tibDetId(detId);
00623       if (!theTIBDetIdRanges.theLayerRanges.empty() && 
00624           !this->insideRanges<int>(tibDetId.layer(), theTIBDetIdRanges.theLayerRanges)) return true;
00625       if (!theTIBDetIdRanges.theModuleRanges.empty() && 
00626           !this->insideRanges<int>(tibDetId.module(), theTIBDetIdRanges.theModuleRanges)) return true;
00627       if (!theTIBDetIdRanges.theSideRanges.empty() && 
00628           !this->insideRanges<int>(tibDetId.side(), theTIBDetIdRanges.theSideRanges)) return true;
00629       if (!theTIBDetIdRanges.theStringRanges.empty() && 
00630           !this->insideRanges<int>(tibDetId.stringNumber(), theTIBDetIdRanges.theStringRanges)) return true;
00631     }
00632     
00633     if (subdetId==static_cast<int>(SiStripDetId::TID)) {
00634       const TIDDetId tidDetId(detId);
00635       if (!theTIDDetIdRanges.theDiskRanges.empty() && 
00636           !this->insideRanges<int>(tidDetId.diskNumber(), theTIDDetIdRanges.theDiskRanges)) return true;
00637       if (!theTIDDetIdRanges.theModuleRanges.empty() && 
00638           !this->insideRanges<int>(tidDetId.moduleNumber(), theTIDDetIdRanges.theModuleRanges)) return true;
00639       if (!theTIDDetIdRanges.theRingRanges.empty() && 
00640           !this->insideRanges<int>(tidDetId.ring(), theTIDDetIdRanges.theRingRanges)) return true;
00641       if (!theTIDDetIdRanges.theSideRanges.empty() && 
00642           !this->insideRanges<int>(tidDetId.side(), theTIDDetIdRanges.theSideRanges)) return true;
00643     }
00644     
00645     if (subdetId==static_cast<int>(SiStripDetId::TOB)) {
00646       const TOBDetId tobDetId(detId);
00647       if (!theTOBDetIdRanges.theLayerRanges.empty() && 
00648           !this->insideRanges<int>(tobDetId.layer(), theTOBDetIdRanges.theLayerRanges)) return true;
00649       if (!theTOBDetIdRanges.theModuleRanges.empty() && 
00650           !this->insideRanges<int>(tobDetId.module(), theTOBDetIdRanges.theModuleRanges)) return true;
00651       if (!theTOBDetIdRanges.theRodRanges.empty() && 
00652           !this->insideRanges<int>(tobDetId.rodNumber(), theTOBDetIdRanges.theRodRanges)) return true;
00653       if (!theTOBDetIdRanges.theSideRanges.empty() && 
00654           !this->insideRanges<int>(tobDetId.side(), theTOBDetIdRanges.theSideRanges)) return true;
00655     }
00656 
00657     if (subdetId==static_cast<int>(SiStripDetId::TEC)) {
00658       const TECDetId tecDetId(detId);
00659       if (!theTECDetIdRanges.theWheelRanges.empty() && 
00660           !this->insideRanges<int>(tecDetId.wheel(), theTECDetIdRanges.theWheelRanges)) return true;
00661       if (!theTECDetIdRanges.thePetalRanges.empty() && 
00662           !this->insideRanges<int>(tecDetId.petalNumber(), theTECDetIdRanges.thePetalRanges)) return true;
00663       if (!theTECDetIdRanges.theModuleRanges.empty() && 
00664           !this->insideRanges<int>(tecDetId.module(), theTECDetIdRanges.theModuleRanges)) return true;
00665       if (!theTECDetIdRanges.theRingRanges.empty() && 
00666           !this->insideRanges<int>(tecDetId.ring(), theTECDetIdRanges.theRingRanges)) return true;
00667       if (!theTECDetIdRanges.theSideRanges.empty() && 
00668           !this->insideRanges<int>(tecDetId.side(), theTECDetIdRanges.theSideRanges)) return true;
00669     }
00670     
00671   }
00672   
00673   return false;
00674 }
00675 
00676 //_________________________________________________________________________
00677 template<typename T> bool AlignmentParameterSelector::insideRanges(T value,
00678                                                                    const std::vector<T> &ranges,
00679                                                                    bool isPhi) const
00680 {
00681   // might become templated on <double> ?
00682 
00683   if (ranges.size()%2 != 0) {
00684     cms::Exception("BadConfig") << "@SUB=AlignmentParameterSelector::insideRanges" 
00685                                 << " need even number of entries in ranges instead of "
00686                                 << ranges.size();
00687     return false;
00688   }
00689 
00690   for (unsigned int i = 0; i < ranges.size(); i += 2) {
00691     if (isPhi) { // mapping into (-pi,+pi] and checking for range including sign flip area
00692       Geom::Phi<double> rangePhi1(ranges[i]);
00693       Geom::Phi<double> rangePhi2(ranges[i+1]);
00694       Geom::Phi<double> valuePhi(value);
00695       if (rangePhi1 <= valuePhi && valuePhi < rangePhi2) { // 'normal'
00696         return true;
00697       }
00698       if (rangePhi2  < rangePhi1 && (rangePhi1 <= valuePhi || valuePhi < rangePhi2)) {// 'sign flip'
00699         return true;
00700       }
00701     } else if (ranges[i] <= value && value < ranges[i+1]) {
00702       return true;
00703     }
00704   }
00705   
00706   return false;
00707 }
00708 
00709 //_________________________________________________________________________
00710 template<> bool AlignmentParameterSelector::insideRanges<int>(int value,
00711                                                               const std::vector<int> &ranges,
00712                                                               bool /*isPhi*/) const
00713 {
00714   if (ranges.size()%2 != 0) {
00715     cms::Exception("BadConfig") << "@SUB=AlignmentParameterSelector::insideRanges" 
00716                                 << " need even number of entries in ranges instead of "
00717                                 << ranges.size();
00718     return false;
00719   }
00720 
00721   for (unsigned int i = 0; i < ranges.size(); i += 2) {
00722     if (ranges[i] <= value && value <= ranges[i+1]) return true;
00723   }
00724   
00725   return false;
00726 }
00727 
00728 bool AlignmentParameterSelector::isMemberOfVector(int value, const std::vector<int> &values) const
00729 {
00730   if (std::find(values.begin(), values.end(), value)!=values.end()) return true;
00731   return false;
00732 }
00733 
00734 //__________________________________________________________________________________________________
00735 std::vector<std::string> 
00736 AlignmentParameterSelector::decompose(const std::string &s, std::string::value_type delimiter) const
00737 {
00738 
00739   std::vector<std::string> result;
00740 
00741   std::string::size_type previousPos = 0;
00742   while (true) {
00743     const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
00744     if (delimiterPos == std::string::npos) {
00745       result.push_back(s.substr(previousPos)); // until end
00746       break;
00747     }
00748     result.push_back(s.substr(previousPos, delimiterPos - previousPos));
00749     previousPos = delimiterPos + 1; // +1: skip delimiter
00750   }
00751 
00752   return result;
00753 }
00754 
00755 //__________________________________________________________________________________________________
00756 std::vector<char> AlignmentParameterSelector::convertParamSel(const std::string &selString) const
00757 {
00758 
00759   // Convert selString into vector<char> of same length.
00760   // Note: Old implementation in AlignmentParameterBuilder was rigid in length,
00761   // expecting RigidBodyAlignmentParameters::N_PARAM.
00762   // But I prefer to be more general and allow other Alignables. It will throw anyway if
00763   // RigidBodyAlignmentParameters are build with wrong selection length.
00764   std::vector<char> result(selString.size());
00765 
00766   for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
00767     result[pos] = selString[pos];
00768   }
00769 
00770   return result;
00771 }
00772 
00773 
00774 //________________________________________________________________________________
00775 std::string AlignmentParameterSelector::setSpecials(const std::string &name)
00776 {
00777   // Use new string only, although direct erasing of found indicator causes problems for 'DSS',
00778   // but 'DSS' makes absolutely no sense!
00779   std::string newName(name); 
00780 
00781   const std::string::size_type ss = newName.rfind("SS");
00782   if (ss != std::string::npos) {
00783     newName.erase(ss, 2); // 2: length of 'SS'
00784     theOnlySS = true;
00785   } else {
00786     theOnlySS = false;
00787   }
00788 
00789   const std::string::size_type ds = newName.rfind("DS");
00790   if (ds != std::string::npos) {
00791     newName.erase(ds, 2); // 2: length of 'DS'
00792     theOnlyDS = true;
00793   } else {
00794     theOnlyDS = false;
00795   }
00796   
00797   const std::string::size_type size = newName.size();
00798   const std::string::size_type layers = newName.rfind("Layers");
00799   if (layers != std::string::npos && size - layers - 2 == 6 // 2 digits, 6: length of 'Layers'
00800       && isdigit(newName[size-1]) && isdigit(newName[size-2])) {
00801     theSelLayers = true;
00802     theMinLayer = newName[size-2] - '0';
00803     theMaxLayer = newName[size-1] - '0';
00804     newName.erase(layers);
00805   } else {
00806     theSelLayers = false;
00807     theMinLayer = -1;
00808     theMaxLayer = 99999;
00809   }
00810 
00811   theRphiOrStereoDetUnit = Both;
00812   if (newName.rfind("Unit") != std::string::npos) {
00813     const std::string::size_type uRph = newName.rfind("UnitRphi");
00814     if (uRph != std::string::npos) {
00815       newName.erase(uRph + 4, 4); // keep 'Unit' (4) and erase 'Rphi' (4)
00816       theRphiOrStereoDetUnit = Rphi;
00817     }
00818     const std::string::size_type uSte = newName.rfind("UnitStereo");
00819     if (uSte != std::string::npos) {
00820       newName.erase(uSte + 4, 6); // keep 'Unit' (4) and erase 'Stereo' (6)
00821       theRphiOrStereoDetUnit = Stereo;
00822     }
00823   }
00824 
00825   if (newName != name) {
00826     LogDebug("Alignment") << "@SUB=AlignmentParameterSelector::setSpecials"
00827                           << name << " becomes " << newName << ", makes theOnlySS " << theOnlySS
00828                           << ", theOnlyDS " << theOnlyDS << ", theSelLayers " << theSelLayers
00829                           << ", theMinLayer " << theMinLayer << ", theMaxLayer " << theMaxLayer
00830                           << ", theRphiOrStereoDetUnit " << theRphiOrStereoDetUnit;
00831   }
00832 
00833   return newName;
00834 }
00835 
00836 //________________________________________________________________________________
00837 unsigned int AlignmentParameterSelector::addAllDets(const std::vector<char> &paramSel)
00838 {
00839   unsigned int numAli = 0;
00840 
00841   numAli += this->add(theTracker->barrelGeomDets(), paramSel);          // TIB+TOB
00842   numAli += this->add(theTracker->endcapGeomDets(), paramSel);          // TEC
00843   numAli += this->add(theTracker->TIDGeomDets(), paramSel);             // TID
00844   numAli += this->add(theTracker->pixelHalfBarrelGeomDets(), paramSel); // PixelBarrel
00845   numAli += this->add(theTracker->pixelEndcapGeomDets(), paramSel);     // PixelEndcap
00846 
00847   return numAli;
00848 }
00849 
00850 //________________________________________________________________________________
00851 unsigned int AlignmentParameterSelector::addAllRods(const std::vector<char> &paramSel)
00852 {
00853   unsigned int numAli = 0;
00854 
00855   numAli += this->add(theTracker->barrelRods(), paramSel);             // TIB+TOB    
00856   numAli += this->add(theTracker->pixelHalfBarrelLadders(), paramSel); // PixelBarrel
00857   numAli += this->add(theTracker->endcapPetals(), paramSel);           // TEC        
00858   numAli += this->add(theTracker->TIDRings(), paramSel);               // TID        
00859   numAli += this->add(theTracker->pixelEndcapPetals(), paramSel);      // PixelEndcap
00860 
00861   return numAli;
00862 }
00863 
00864 //________________________________________________________________________________
00865 unsigned int AlignmentParameterSelector::addAllLayers(const std::vector<char> &paramSel)
00866 {
00867   unsigned int numAli = 0;
00868 
00869   numAli += this->add(theTracker->barrelLayers(), paramSel);          // TIB+TOB    
00870   numAli += this->add(theTracker->pixelHalfBarrelLayers(), paramSel); // PixelBarrel
00871   numAli += this->add(theTracker->endcapLayers(), paramSel);          // TEC
00872   numAli += this->add(theTracker->TIDLayers(), paramSel);             // TID
00873   numAli += this->add(theTracker->pixelEndcapLayers(), paramSel);     // PixelEndcap
00874 
00875   return numAli;
00876 }
00877 
00878 //________________________________________________________________________________
00879 unsigned int AlignmentParameterSelector::addAllAlignables(const std::vector<char> &paramSel)
00880 {
00881   unsigned int numAli = 0;
00882 
00883   numAli += this->addAllDets(paramSel);
00884   numAli += this->addAllRods(paramSel);
00885   numAli += this->addAllLayers(paramSel);
00886   numAli += this->add(theTracker->components(), paramSel);
00887 
00888   return numAli;
00889 }