Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:44:39

0001 /** \file AlignmentParameterSelector.cc
0002  *  \author Gero Flucke, Nov. 2006
0003  *
0004  *  $Date: 2010/11/22 08:40:09 $
0005  *  $Revision: 1.20 $
0006  *  (last update by $Author: mussgill $)
0007  */
0008 
0009 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
0010 #include "Alignment/CommonAlignment/interface/AlignableExtras.h"
0011 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
0012 #include "Alignment/MuonAlignment/interface/AlignableMuon.h"
0013 #include "Alignment/TrackerAlignment/interface/TrackerAlignableId.h"
0014 
0015 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0016 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"  // for enums TID/TIB/etc.
0017 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0018 
0019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0021 #include "FWCore/Utilities/interface/Exception.h"
0022 
0023 //________________________________________________________________________________
0024 AlignmentParameterSelector::AlignmentParameterSelector(AlignableTracker *aliTracker,
0025                                                        AlignableMuon *aliMuon,
0026                                                        AlignableExtras *aliExtras)
0027     : theTracker(aliTracker),
0028       theMuon(aliMuon),
0029       theExtras(aliExtras),
0030       theSelectedAlignables(),
0031       theRangesEta(),
0032       theRangesPhi(),
0033       theRangesR(),
0034       theRangesX(),
0035       theRangesY(),
0036       theRangesZ() {
0037   this->setSpecials("");  // init theOnlyDS, theOnlySS, theSelLayers, theMinLayer, theMaxLayer, theRphiOrStereoDetUnit
0038 }
0039 
0040 //________________________________________________________________________________
0041 void AlignmentParameterSelector::clear() {
0042   theSelectedAlignables.clear();
0043   theSelectedParameters.clear();
0044   this->clearGeometryCuts();
0045 }
0046 
0047 //________________________________________________________________________________
0048 void AlignmentParameterSelector::clearGeometryCuts() {
0049   theRangesEta.clear();
0050   theRangesPhi.clear();
0051   theRangesR.clear();
0052   theRangesX.clear();
0053   theRangesY.clear();
0054   theRangesZ.clear();
0055 
0056   thePXBDetIdRanges.clear();
0057   thePXFDetIdRanges.clear();
0058   theTIBDetIdRanges.clear();
0059   theTIDDetIdRanges.clear();
0060   theTOBDetIdRanges.clear();
0061   theTECDetIdRanges.clear();
0062 }
0063 
0064 const AlignableTracker *AlignmentParameterSelector::alignableTracker() const { return theTracker; }
0065 
0066 //__________________________________________________________________________________________________
0067 unsigned int AlignmentParameterSelector::addSelections(const edm::ParameterSet &pSet) {
0068   const std::vector<std::string> selections = pSet.getParameter<std::vector<std::string> >("alignParams");
0069 
0070   unsigned int addedSets = 0;
0071 
0072   for (unsigned int iSel = 0; iSel < selections.size(); ++iSel) {
0073     std::vector<std::string> decompSel(this->decompose(selections[iSel], ','));
0074     if (decompSel.empty())
0075       continue;  // edm::LogError or even cms::Exception??
0076 
0077     if (decompSel.size() < 2) {
0078       throw cms::Exception("BadConfig") << "@SUB=AlignmentParameterSelector::addSelections" << selections[iSel]
0079                                         << " from alignableParamSelector: "
0080                                         << " should have at least 2 ','-separated parts";
0081     } else if (decompSel.size() > 2) {
0082       const edm::ParameterSet geoSel(pSet.getParameter<edm::ParameterSet>(decompSel[2].c_str()));
0083       this->addSelection(decompSel[0], this->convertParamSel(decompSel[1]), geoSel);
0084     } else {
0085       this->clearGeometryCuts();
0086       this->addSelection(decompSel[0], this->convertParamSel(decompSel[1]));
0087     }
0088 
0089     ++addedSets;
0090   }
0091 
0092   return addedSets;
0093 }
0094 
0095 //________________________________________________________________________________
0096 void AlignmentParameterSelector::setGeometryCuts(const edm::ParameterSet &pSet) {
0097   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
0098   // but take care that nothing unknown is configured (to fetch typos!).
0099 
0100   this->clearGeometryCuts();
0101   const std::vector<std::string> parameterNames(pSet.getParameterNames());
0102   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(), iEnd = parameterNames.end();
0103        iParam != iEnd;
0104        ++iParam) {
0105     // Calling swap is more efficient than assignment:
0106     if (*iParam == "etaRanges") {
0107       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesEta);
0108     } else if (*iParam == "phiRanges") {
0109       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesPhi);
0110     } else if (*iParam == "rRanges") {
0111       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesR);
0112     } else if (*iParam == "xRanges") {
0113       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesX);
0114     } else if (*iParam == "yRanges") {
0115       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesY);
0116     } else if (*iParam == "zRanges") {
0117       pSet.getParameter<std::vector<double> >(*iParam).swap(theRangesZ);
0118     } else if (*iParam == "detIds") {
0119       pSet.getParameter<std::vector<int> >(*iParam).swap(theDetIds);
0120     } else if (*iParam == "detIdRanges") {
0121       pSet.getParameter<std::vector<int> >(*iParam).swap(theDetIdRanges);
0122     } else if (*iParam == "excludedDetIds") {
0123       pSet.getParameter<std::vector<int> >(*iParam).swap(theExcludedDetIds);
0124     } else if (*iParam == "excludedDetIdRanges") {
0125       pSet.getParameter<std::vector<int> >(*iParam).swap(theExcludedDetIdRanges);
0126     } else if (*iParam == "pxbDetId") {
0127       const edm::ParameterSet &pxbDetIdPSet = pSet.getParameterSet(*iParam);
0128       this->setPXBDetIdCuts(pxbDetIdPSet);
0129     } else if (*iParam == "pxfDetId") {
0130       const edm::ParameterSet &pxfDetIdPSet = pSet.getParameterSet(*iParam);
0131       this->setPXFDetIdCuts(pxfDetIdPSet);
0132     } else if (*iParam == "tibDetId") {
0133       const edm::ParameterSet &tibDetIdPSet = pSet.getParameterSet(*iParam);
0134       this->setTIBDetIdCuts(tibDetIdPSet);
0135     } else if (*iParam == "tidDetId") {
0136       const edm::ParameterSet &tidDetIdPSet = pSet.getParameterSet(*iParam);
0137       this->setTIDDetIdCuts(tidDetIdPSet);
0138     } else if (*iParam == "tobDetId") {
0139       const edm::ParameterSet &tobDetIdPSet = pSet.getParameterSet(*iParam);
0140       this->setTOBDetIdCuts(tobDetIdPSet);
0141     } else if (*iParam == "tecDetId") {
0142       const edm::ParameterSet &tecDetIdPSet = pSet.getParameterSet(*iParam);
0143       this->setTECDetIdCuts(tecDetIdPSet);
0144     } else {
0145       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setGeometryCuts] "
0146                                         << "Unknown parameter '" << *iParam << "'.\n";
0147     }
0148   }
0149 }
0150 
0151 //________________________________________________________________________________
0152 void AlignmentParameterSelector::setPXBDetIdCuts(const edm::ParameterSet &pSet) {
0153   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
0154   // but take care that nothing unknown is configured (to fetch typos!).
0155 
0156   const std::vector<std::string> parameterNames(pSet.getParameterNames());
0157   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(), iEnd = parameterNames.end();
0158        iParam != iEnd;
0159        ++iParam) {
0160     // Calling swap is more efficient than assignment:
0161     if (*iParam == "ladderRanges") {
0162       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXBDetIdRanges.theLadderRanges);
0163     } else if (*iParam == "layerRanges") {
0164       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXBDetIdRanges.theLayerRanges);
0165     } else if (*iParam == "moduleRanges") {
0166       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXBDetIdRanges.theModuleRanges);
0167     } else {
0168       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setPXBDetIdCuts] "
0169                                         << "Unknown parameter '" << *iParam << "'.\n";
0170     }
0171   }
0172 }
0173 
0174 //________________________________________________________________________________
0175 void AlignmentParameterSelector::setPXFDetIdCuts(const edm::ParameterSet &pSet) {
0176   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
0177   // but take care that nothing unknown is configured (to fetch typos!).
0178 
0179   const std::vector<std::string> parameterNames(pSet.getParameterNames());
0180   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(), iEnd = parameterNames.end();
0181        iParam != iEnd;
0182        ++iParam) {
0183     // Calling swap is more efficient than assignment:
0184     if (*iParam == "bladeRanges") {
0185       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.theBladeRanges);
0186     } else if (*iParam == "diskRanges") {
0187       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.theDiskRanges);
0188     } else if (*iParam == "moduleRanges") {
0189       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.theModuleRanges);
0190     } else if (*iParam == "panelRanges") {
0191       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.thePanelRanges);
0192     } else if (*iParam == "sideRanges") {
0193       pSet.getParameter<std::vector<int> >(*iParam).swap(thePXFDetIdRanges.theSideRanges);
0194     } else {
0195       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setPXFDetIdCuts] "
0196                                         << "Unknown parameter '" << *iParam << "'.\n";
0197     }
0198   }
0199 }
0200 
0201 //________________________________________________________________________________
0202 void AlignmentParameterSelector::setTIBDetIdCuts(const edm::ParameterSet &pSet) {
0203   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
0204   // but take care that nothing unknown is configured (to fetch typos!).
0205 
0206   const std::vector<std::string> parameterNames(pSet.getParameterNames());
0207   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(), iEnd = parameterNames.end();
0208        iParam != iEnd;
0209        ++iParam) {
0210     // Calling swap is more efficient than assignment:
0211     if (*iParam == "layerRanges") {
0212       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIBDetIdRanges.theLayerRanges);
0213     } else if (*iParam == "moduleRanges") {
0214       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIBDetIdRanges.theModuleRanges);
0215     } else if (*iParam == "stringRanges") {
0216       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIBDetIdRanges.theStringRanges);
0217     } else if (*iParam == "sideRanges") {
0218       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIBDetIdRanges.theSideRanges);
0219     } else {
0220       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setTIBDetIdCuts] "
0221                                         << "Unknown parameter '" << *iParam << "'.\n";
0222     }
0223   }
0224 }
0225 
0226 //________________________________________________________________________________
0227 void AlignmentParameterSelector::setTIDDetIdCuts(const edm::ParameterSet &pSet) {
0228   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
0229   // but take care that nothing unknown is configured (to fetch typos!).
0230 
0231   const std::vector<std::string> parameterNames(pSet.getParameterNames());
0232   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(), iEnd = parameterNames.end();
0233        iParam != iEnd;
0234        ++iParam) {
0235     // Calling swap is more efficient than assignment:
0236     if (*iParam == "diskRanges") {
0237       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIDDetIdRanges.theDiskRanges);
0238     } else if (*iParam == "moduleRanges") {
0239       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIDDetIdRanges.theModuleRanges);
0240     } else if (*iParam == "ringRanges") {
0241       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIDDetIdRanges.theRingRanges);
0242     } else if (*iParam == "sideRanges") {
0243       pSet.getParameter<std::vector<int> >(*iParam).swap(theTIDDetIdRanges.theSideRanges);
0244     } else {
0245       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setTIDDetIdCuts] "
0246                                         << "Unknown parameter '" << *iParam << "'.\n";
0247     }
0248   }
0249 }
0250 
0251 //________________________________________________________________________________
0252 void AlignmentParameterSelector::setTOBDetIdCuts(const edm::ParameterSet &pSet) {
0253   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
0254   // but take care that nothing unknown is configured (to fetch typos!).
0255 
0256   const std::vector<std::string> parameterNames(pSet.getParameterNames());
0257   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(), iEnd = parameterNames.end();
0258        iParam != iEnd;
0259        ++iParam) {
0260     // Calling swap is more efficient than assignment:
0261     if (*iParam == "layerRanges") {
0262       pSet.getParameter<std::vector<int> >(*iParam).swap(theTOBDetIdRanges.theLayerRanges);
0263     } else if (*iParam == "moduleRanges") {
0264       pSet.getParameter<std::vector<int> >(*iParam).swap(theTOBDetIdRanges.theModuleRanges);
0265     } else if (*iParam == "sideRanges") {
0266       pSet.getParameter<std::vector<int> >(*iParam).swap(theTOBDetIdRanges.theSideRanges);
0267     } else if (*iParam == "rodRanges") {
0268       pSet.getParameter<std::vector<int> >(*iParam).swap(theTOBDetIdRanges.theRodRanges);
0269     } else {
0270       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setTOBDetIdCuts] "
0271                                         << "Unknown parameter '" << *iParam << "'.\n";
0272     }
0273   }
0274 }
0275 
0276 //________________________________________________________________________________
0277 void AlignmentParameterSelector::setTECDetIdCuts(const edm::ParameterSet &pSet) {
0278   // Allow non-specified arrays to be interpreted as empty (i.e. no selection),
0279   // but take care that nothing unknown is configured (to fetch typos!).
0280 
0281   const std::vector<std::string> parameterNames(pSet.getParameterNames());
0282   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(), iEnd = parameterNames.end();
0283        iParam != iEnd;
0284        ++iParam) {
0285     // Calling swap is more efficient than assignment:
0286     if (*iParam == "wheelRanges") {
0287       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.theWheelRanges);
0288     } else if (*iParam == "petalRanges") {
0289       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.thePetalRanges);
0290     } else if (*iParam == "moduleRanges") {
0291       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.theModuleRanges);
0292     } else if (*iParam == "ringRanges") {
0293       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.theRingRanges);
0294     } else if (*iParam == "sideRanges") {
0295       pSet.getParameter<std::vector<int> >(*iParam).swap(theTECDetIdRanges.theSideRanges);
0296     } else {
0297       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::setTECDetIdCuts] "
0298                                         << "Unknown parameter '" << *iParam << "'.\n";
0299     }
0300   }
0301 }
0302 
0303 //________________________________________________________________________________
0304 unsigned int AlignmentParameterSelector::addSelection(const std::string &name,
0305                                                       const std::vector<char> &paramSel,
0306                                                       const edm::ParameterSet &pSet) {
0307   this->setGeometryCuts(pSet);
0308   return this->addSelection(name, paramSel);
0309 }
0310 
0311 //________________________________________________________________________________
0312 unsigned int AlignmentParameterSelector::addSelection(const std::string &nameInput, const std::vector<char> &paramSel) {
0313   const std::string name(this->setSpecials(nameInput));  // possibly changing name
0314 
0315   unsigned int numAli = 0;
0316 
0317   ////////////////////////////////////
0318   // Generic Tracker Section
0319   ////////////////////////////////////
0320   if (name.find("Tracker") == 0) {  // string starts with "Tracker"
0321     if (!theTracker) {
0322       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::addSelection] "
0323                                         << "Configuration requires access to AlignableTracker"
0324                                         << " (for " << name << ") that is not initialized";
0325     }
0326     const std::string substructName(name, 7);  // erase "Tracker" at the beginning
0327     numAli += this->add(theTracker->subStructures(substructName), paramSel);
0328   }
0329   ////////////////////////////////////
0330   // Old hardcoded, but geometry-independent tracker section (NOTE: no check on theTracker != 0)
0331   ////////////////////////////////////
0332   else if (name == "AllDets")
0333     numAli += this->addAllDets(paramSel);
0334   else if (name == "AllRods")
0335     numAli += this->addAllRods(paramSel);
0336   else if (name == "AllLayers")
0337     numAli += this->addAllLayers(paramSel);
0338   else if (name == "AllComponents")
0339     numAli += this->add(theTracker->components(), paramSel);
0340   else if (name == "AllAlignables")
0341     numAli += this->addAllAlignables(paramSel);
0342   //
0343   // TIB+TOB
0344   //
0345   else if (name == "BarrelRods")
0346     numAli += this->add(theTracker->barrelRods(), paramSel);
0347   else if (name == "BarrelDets")
0348     numAli += this->add(theTracker->barrelGeomDets(), paramSel);
0349   else if (name == "BarrelLayers")
0350     numAli += this->add(theTracker->barrelLayers(), paramSel);
0351   else if (name == "TOBDets")
0352     numAli += this->add(theTracker->outerBarrelGeomDets(), paramSel);
0353   else if (name == "TOBRods")
0354     numAli += this->add(theTracker->outerBarrelRods(), paramSel);
0355   else if (name == "TOBLayers")
0356     numAli += this->add(theTracker->outerBarrelLayers(), paramSel);
0357   else if (name == "TOBHalfBarrels")
0358     numAli += this->add(theTracker->outerHalfBarrels(), paramSel);
0359   else if (name == "TIBDets")
0360     numAli += this->add(theTracker->innerBarrelGeomDets(), paramSel);
0361   else if (name == "TIBRods")
0362     numAli += this->add(theTracker->innerBarrelRods(), paramSel);
0363   else if (name == "TIBLayers")
0364     numAli += this->add(theTracker->innerBarrelLayers(), paramSel);
0365   else if (name == "TIBHalfBarrels")
0366     numAli += this->add(theTracker->innerHalfBarrels(), paramSel);
0367   //
0368   // PXBarrel
0369   //
0370   else if (name == "PixelHalfBarrelDets") {
0371     numAli += this->add(theTracker->pixelHalfBarrelGeomDets(), paramSel);
0372   } else if (name == "PixelHalfBarrelLadders") {
0373     numAli += this->add(theTracker->pixelHalfBarrelLadders(), paramSel);
0374   } else if (name == "PixelHalfBarrelLayers") {
0375     numAli += this->add(theTracker->pixelHalfBarrelLayers(), paramSel);
0376   } else if (name == "PixelHalfBarrels") {
0377     numAli += this->add(theTracker->pixelHalfBarrels(), paramSel);
0378   }
0379   //
0380   // PXEndcap
0381   //
0382   else if (name == "PXECDets")
0383     numAli += this->add(theTracker->pixelEndcapGeomDets(), paramSel);
0384   else if (name == "PXECPetals")
0385     numAli += this->add(theTracker->pixelEndcapPetals(), paramSel);
0386   else if (name == "PXECLayers")
0387     numAli += this->add(theTracker->pixelEndcapLayers(), paramSel);
0388   else if (name == "PXECHalfCylinders")
0389     numAli += this->add(theTracker->pixelEndcapHalfCylinders(), paramSel);
0390   else if (name == "PXEndCaps")
0391     numAli += this->add(theTracker->pixelEndCaps(), paramSel);
0392   //
0393   // Pixel Barrel+endcap
0394   //
0395   else if (name == "PixelDets") {
0396     numAli += this->add(theTracker->pixelHalfBarrelGeomDets(), paramSel);
0397     numAli += this->add(theTracker->pixelEndcapGeomDets(), paramSel);
0398   } else if (name == "PixelRods") {
0399     numAli += this->add(theTracker->pixelHalfBarrelLadders(), paramSel);
0400     numAli += this->add(theTracker->pixelEndcapPetals(), paramSel);
0401   } else if (name == "PixelLayers") {
0402     numAli += this->add(theTracker->pixelHalfBarrelLayers(), paramSel);
0403     numAli += this->add(theTracker->pixelEndcapLayers(), paramSel);
0404   }
0405   //
0406   // TID
0407   //
0408   else if (name == "TIDs")
0409     numAli += this->add(theTracker->TIDs(), paramSel);
0410   else if (name == "TIDLayers")
0411     numAli += this->add(theTracker->TIDLayers(), paramSel);
0412   else if (name == "TIDRings")
0413     numAli += this->add(theTracker->TIDRings(), paramSel);
0414   else if (name == "TIDDets")
0415     numAli += this->add(theTracker->TIDGeomDets(), paramSel);
0416   //
0417   // TEC
0418   //
0419   else if (name == "TECDets")
0420     numAli += this->add(theTracker->endcapGeomDets(), paramSel);
0421   else if (name == "TECPetals")
0422     numAli += this->add(theTracker->endcapPetals(), paramSel);
0423   else if (name == "TECLayers")
0424     numAli += this->add(theTracker->endcapLayers(), paramSel);
0425   else if (name == "TECs")
0426     numAli += this->add(theTracker->endCaps(), paramSel);
0427   //
0428   // StripEndcap (TID+TEC)
0429   //
0430   else if (name == "EndcapDets") {
0431     numAli += this->add(theTracker->TIDGeomDets(), paramSel);
0432     numAli += this->add(theTracker->endcapGeomDets(), paramSel);
0433   } else if (name == "EndcapPetals") {
0434     numAli += this->add(theTracker->TIDRings(), paramSel);
0435     numAli += this->add(theTracker->endcapPetals(), paramSel);
0436   } else if (name == "EndcapLayers") {
0437     numAli += this->add(theTracker->TIDLayers(), paramSel);
0438     numAli += this->add(theTracker->endcapLayers(), paramSel);
0439   }
0440   //
0441   // Strip Barrel+endcap
0442   //
0443   else if (name == "StripDets") {
0444     numAli += this->add(theTracker->barrelGeomDets(), paramSel);
0445     numAli += this->add(theTracker->TIDGeomDets(), paramSel);
0446     numAli += this->add(theTracker->endcapGeomDets(), paramSel);
0447   } else if (name == "StripRods") {
0448     numAli += this->add(theTracker->barrelRods(), paramSel);
0449     numAli += this->add(theTracker->TIDRings(), paramSel);
0450     numAli += this->add(theTracker->endcapPetals(), paramSel);
0451   } else if (name == "StripLayers") {
0452     numAli += this->add(theTracker->barrelLayers(), paramSel);
0453     numAli += this->add(theTracker->TIDLayers(), paramSel);
0454     numAli += this->add(theTracker->endcapLayers(), paramSel);
0455   }
0456   ////////////////////////////////////
0457   // Muon selection
0458   ////////////////////////////////////
0459   // Check if name contains muon and react if alignable muon not initialized
0460   else if (name.find("Muon") != std::string::npos) {
0461     if (!theMuon) {
0462       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::addSelection] "
0463                                         << "Configuration requires access to AlignableMuon"
0464                                         << " which is not initialized";
0465     } else if (name == "MuonDTLayers")
0466       add(theMuon->DTLayers(), paramSel);
0467     else if (name == "MuonDTSuperLayers")
0468       add(theMuon->DTSuperLayers(), paramSel);
0469     else if (name == "MuonDTChambers")
0470       add(theMuon->DTChambers(), paramSel);
0471     else if (name == "MuonDTStations")
0472       add(theMuon->DTStations(), paramSel);
0473     else if (name == "MuonDTWheels")
0474       add(theMuon->DTWheels(), paramSel);
0475     else if (name == "MuonBarrel")
0476       add(theMuon->DTBarrel(), paramSel);
0477     else if (name == "MuonCSCLayers")
0478       add(theMuon->CSCLayers(), paramSel);
0479     else if (name == "MuonCSCRings")
0480       add(theMuon->CSCRings(), paramSel);
0481     else if (name == "MuonCSCChambers")
0482       add(theMuon->CSCChambers(), paramSel);
0483     else if (name == "MuonCSCStations")
0484       add(theMuon->CSCStations(), paramSel);
0485     else if (name == "MuonEndcaps")
0486       add(theMuon->CSCEndcaps(), paramSel);
0487 
0488     ////////////////////////////////////
0489     // not found, but Muon
0490     ////////////////////////////////////
0491     else {
0492       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::addSelection]"
0493                                         << ": Selection '" << name << "' invalid!";
0494     }
0495   }
0496 
0497   ////////////////////////////////////
0498   // Generic Extra Alignable Section
0499   ////////////////////////////////////
0500   else if (name.find("Extras") == 0) {  // string starts with "Extras"
0501     if (!theExtras) {
0502       throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::addSelection] "
0503                                         << "Configuration requires access to AlignableExtras"
0504                                         << " (for " << name << ") that is not initialized";
0505     }
0506     const std::string substructName(name, 6);  // erase "Extras" at the beginning
0507     numAli += this->add(theExtras->subStructures(substructName), paramSel);
0508   }
0509   // end of "name.find("Extras") != std::string::npos"
0510 
0511   else {
0512     throw cms::Exception("BadConfig") << "[AlignmentParameterSelector::addSelection]"
0513                                       << ": Selection '" << name << "' invalid!";
0514   }
0515 
0516   this->setSpecials("");  // reset
0517 
0518   return numAli;
0519 }
0520 
0521 //________________________________________________________________________________
0522 unsigned int AlignmentParameterSelector::add(const align::Alignables &alignables, const std::vector<char> &paramSel) {
0523   unsigned int numAli = 0;
0524 
0525   // loop on Alignable objects
0526   for (align::Alignables::const_iterator iAli = alignables.begin(); iAli != alignables.end(); ++iAli) {
0527     if (!this->layerDeselected(*iAli)              // check layers
0528         && !this->detUnitDeselected(*iAli)         // check detunit selection
0529         && !this->outsideGeometricalRanges(*iAli)  // check geometrical ranges
0530         && !this->outsideDetIdRanges(*iAli)) {     // check DetId ranges
0531       // all fine, so add to output arrays
0532       theSelectedAlignables.push_back(*iAli);
0533       theSelectedParameters.push_back(paramSel);
0534       ++numAli;
0535     }
0536   }
0537 
0538   return numAli;
0539 }
0540 
0541 //_________________________________________________________________________
0542 bool AlignmentParameterSelector::layerDeselected(const Alignable *ali) const {
0543   if (theOnlySS || theOnlyDS || theSelLayers) {
0544     TrackerAlignableId idProvider;
0545     std::pair<int, int> typeLayer = idProvider.typeAndLayerFromDetId(ali->id(), alignableTracker()->trackerTopology());
0546     int type = typeLayer.first;
0547     int layer = typeLayer.second;
0548 
0549     // select on single/double sided barrel layers in TIB/TOB
0550     if (theOnlySS  // only single sided
0551         && (std::abs(type) == SiStripDetId::TIB || std::abs(type) == SiStripDetId::TOB) && layer <= 2) {
0552       return true;
0553     }
0554     if (theOnlyDS  // only double sided
0555         && (std::abs(type) == SiStripDetId::TIB || std::abs(type) == SiStripDetId::TOB) && layer > 2) {
0556       return true;
0557     }
0558 
0559     // reject layers
0560     if (theSelLayers && (layer < theMinLayer || layer > theMaxLayer)) {
0561       return true;
0562     }
0563   }
0564 
0565   return false;  // do not deselect...
0566 }
0567 
0568 //_________________________________________________________________________
0569 bool AlignmentParameterSelector::detUnitDeselected(const Alignable *ali) const {
0570   if (theRphiOrStereoDetUnit != Both && ali->alignableObjectId() == align::AlignableDetUnit) {
0571     const SiStripDetId detId(ali->geomDetId());  // do not know yet whether right type...
0572     if (detId.det() == DetId::Tracker &&
0573         (detId.subdetId() == SiStripDetId::TIB || detId.subdetId() == SiStripDetId::TID ||
0574          detId.subdetId() == SiStripDetId::TOB || detId.subdetId() == SiStripDetId::TEC)) {
0575       // We have a DetUnit in strip, so check for a selection of stereo/rphi (DetUnits in 1D layers are rphi):
0576       if ((theRphiOrStereoDetUnit == Stereo && !detId.stereo()) || (theRphiOrStereoDetUnit == Rphi && detId.stereo())) {
0577         return true;
0578       }
0579     }
0580   }
0581 
0582   return false;  // do not deselect...
0583 }
0584 
0585 //_________________________________________________________________________
0586 bool AlignmentParameterSelector::outsideGeometricalRanges(const Alignable *alignable) const {
0587   const align::PositionType &position(alignable->globalPosition());
0588 
0589   if (!theRangesEta.empty() && !this->insideRanges<double>((position.eta()), theRangesEta))
0590     return true;
0591   if (!theRangesPhi.empty() && !this->insideRanges<double>((position.phi()), theRangesPhi, true))
0592     return true;
0593   if (!theRangesR.empty() && !this->insideRanges<double>((position.perp()), theRangesR))
0594     return true;
0595   if (!theRangesX.empty() && !this->insideRanges<double>((position.x()), theRangesX))
0596     return true;
0597   if (!theRangesY.empty() && !this->insideRanges<double>((position.y()), theRangesY))
0598     return true;
0599   if (!theRangesZ.empty() && !this->insideRanges<double>((position.z()), theRangesZ))
0600     return true;
0601 
0602   return false;
0603 }
0604 
0605 //_________________________________________________________________________
0606 bool AlignmentParameterSelector::outsideDetIdRanges(const Alignable *alignable) const {
0607   //const DetId detId(alignable->geomDetId());
0608   const DetId detId(alignable->id());
0609   const int subdetId = detId.subdetId();
0610 
0611   if (alignableTracker()) {
0612     const TrackerTopology *tTopo = alignableTracker()->trackerTopology();
0613 
0614     if (!theDetIds.empty() && !this->isMemberOfVector((detId.rawId()), theDetIds))
0615       return true;
0616     if (!theDetIdRanges.empty() && !this->insideRanges<int>((detId.rawId()), theDetIdRanges))
0617       return true;
0618     if (!theExcludedDetIds.empty() && this->isMemberOfVector((detId.rawId()), theExcludedDetIds))
0619       return true;
0620     if (!theExcludedDetIdRanges.empty() && this->insideRanges<int>((detId.rawId()), theExcludedDetIdRanges))
0621       return true;
0622 
0623     if (detId.det() == DetId::Tracker) {
0624       if (subdetId == static_cast<int>(PixelSubdetector::PixelBarrel)) {
0625         if (!thePXBDetIdRanges.theLadderRanges.empty() &&
0626             !this->insideRanges<int>(tTopo->pxbLadder(detId), thePXBDetIdRanges.theLadderRanges))
0627           return true;
0628         if (!thePXBDetIdRanges.theLayerRanges.empty() &&
0629             !this->insideRanges<int>(tTopo->pxbLayer(detId), thePXBDetIdRanges.theLayerRanges))
0630           return true;
0631         if (!thePXBDetIdRanges.theModuleRanges.empty() &&
0632             !this->insideRanges<int>(tTopo->pxbModule(detId), thePXBDetIdRanges.theModuleRanges))
0633           return true;
0634       }
0635 
0636       if (subdetId == static_cast<int>(PixelSubdetector::PixelEndcap)) {
0637         if (!thePXFDetIdRanges.theBladeRanges.empty() &&
0638             !this->insideRanges<int>(tTopo->pxfBlade(detId), thePXFDetIdRanges.theBladeRanges))
0639           return true;
0640         if (!thePXFDetIdRanges.theDiskRanges.empty() &&
0641             !this->insideRanges<int>(tTopo->pxfDisk(detId), thePXFDetIdRanges.theDiskRanges))
0642           return true;
0643         if (!thePXFDetIdRanges.theModuleRanges.empty() &&
0644             !this->insideRanges<int>(tTopo->pxfModule(detId), thePXFDetIdRanges.theModuleRanges))
0645           return true;
0646         if (!thePXFDetIdRanges.thePanelRanges.empty() &&
0647             !this->insideRanges<int>(tTopo->pxfPanel(detId), thePXFDetIdRanges.thePanelRanges))
0648           return true;
0649         if (!thePXFDetIdRanges.theSideRanges.empty() &&
0650             !this->insideRanges<int>(tTopo->pxfSide(detId), thePXFDetIdRanges.theSideRanges))
0651           return true;
0652       }
0653 
0654       if (subdetId == static_cast<int>(SiStripDetId::TIB)) {
0655         if (!theTIBDetIdRanges.theLayerRanges.empty() &&
0656             !this->insideRanges<int>(tTopo->tibLayer(detId), theTIBDetIdRanges.theLayerRanges))
0657           return true;
0658         if (!theTIBDetIdRanges.theModuleRanges.empty() &&
0659             !this->insideRanges<int>(tTopo->tibModule(detId), theTIBDetIdRanges.theModuleRanges))
0660           return true;
0661         if (!theTIBDetIdRanges.theSideRanges.empty() &&
0662             !this->insideRanges<int>(tTopo->tibSide(detId), theTIBDetIdRanges.theSideRanges))
0663           return true;
0664         if (!theTIBDetIdRanges.theStringRanges.empty() &&
0665             !this->insideRanges<int>(tTopo->tibString(detId), theTIBDetIdRanges.theStringRanges))
0666           return true;
0667       }
0668 
0669       if (subdetId == static_cast<int>(SiStripDetId::TID)) {
0670         if (!theTIDDetIdRanges.theDiskRanges.empty() &&
0671             !this->insideRanges<int>(tTopo->tidWheel(detId), theTIDDetIdRanges.theDiskRanges))
0672           return true;
0673         if (!theTIDDetIdRanges.theModuleRanges.empty() &&
0674             !this->insideRanges<int>(tTopo->tidModule(detId), theTIDDetIdRanges.theModuleRanges))
0675           return true;
0676         if (!theTIDDetIdRanges.theRingRanges.empty() &&
0677             !this->insideRanges<int>(tTopo->tidRing(detId), theTIDDetIdRanges.theRingRanges))
0678           return true;
0679         if (!theTIDDetIdRanges.theSideRanges.empty() &&
0680             !this->insideRanges<int>(tTopo->tidSide(detId), theTIDDetIdRanges.theSideRanges))
0681           return true;
0682       }
0683 
0684       if (subdetId == static_cast<int>(SiStripDetId::TOB)) {
0685         if (!theTOBDetIdRanges.theLayerRanges.empty() &&
0686             !this->insideRanges<int>(tTopo->tobLayer(detId), theTOBDetIdRanges.theLayerRanges))
0687           return true;
0688         if (!theTOBDetIdRanges.theModuleRanges.empty() &&
0689             !this->insideRanges<int>(tTopo->tobModule(detId), theTOBDetIdRanges.theModuleRanges))
0690           return true;
0691         if (!theTOBDetIdRanges.theRodRanges.empty() &&
0692             !this->insideRanges<int>(tTopo->tobRod(detId), theTOBDetIdRanges.theRodRanges))
0693           return true;
0694         if (!theTOBDetIdRanges.theSideRanges.empty() &&
0695             !this->insideRanges<int>(tTopo->tobSide(detId), theTOBDetIdRanges.theSideRanges))
0696           return true;
0697       }
0698 
0699       if (subdetId == static_cast<int>(SiStripDetId::TEC)) {
0700         if (!theTECDetIdRanges.theWheelRanges.empty() &&
0701             !this->insideRanges<int>(tTopo->tecWheel(detId), theTECDetIdRanges.theWheelRanges))
0702           return true;
0703         if (!theTECDetIdRanges.thePetalRanges.empty() &&
0704             !this->insideRanges<int>(tTopo->tecPetalNumber(detId), theTECDetIdRanges.thePetalRanges))
0705           return true;
0706         if (!theTECDetIdRanges.theModuleRanges.empty() &&
0707             !this->insideRanges<int>(tTopo->tecModule(detId), theTECDetIdRanges.theModuleRanges))
0708           return true;
0709         if (!theTECDetIdRanges.theRingRanges.empty() &&
0710             !this->insideRanges<int>(tTopo->tecRing(detId), theTECDetIdRanges.theRingRanges))
0711           return true;
0712         if (!theTECDetIdRanges.theSideRanges.empty() &&
0713             !this->insideRanges<int>(tTopo->tecSide(detId), theTECDetIdRanges.theSideRanges))
0714           return true;
0715       }
0716     }
0717   }
0718 
0719   return false;
0720 }
0721 
0722 //_________________________________________________________________________
0723 template <typename T>
0724 bool AlignmentParameterSelector::insideRanges(T value, const std::vector<T> &ranges, bool isPhi) const {
0725   // might become templated on <double> ?
0726 
0727   if (ranges.size() % 2 != 0) {
0728     cms::Exception("BadConfig") << "@SUB=AlignmentParameterSelector::insideRanges"
0729                                 << " need even number of entries in ranges instead of " << ranges.size();
0730     return false;
0731   }
0732 
0733   for (unsigned int i = 0; i < ranges.size(); i += 2) {
0734     if (isPhi) {  // mapping into (-pi,+pi] and checking for range including sign flip area
0735       Geom::Phi<double> rangePhi1(ranges[i]);
0736       Geom::Phi<double> rangePhi2(ranges[i + 1]);
0737       Geom::Phi<double> valuePhi(value);
0738       if (rangePhi1 <= valuePhi && valuePhi < rangePhi2) {  // 'normal'
0739         return true;
0740       }
0741       if (rangePhi2 < rangePhi1 && (rangePhi1 <= valuePhi || valuePhi < rangePhi2)) {  // 'sign flip'
0742         return true;
0743       }
0744     } else if (ranges[i] <= value && value < ranges[i + 1]) {
0745       return true;
0746     }
0747   }
0748 
0749   return false;
0750 }
0751 
0752 //_________________________________________________________________________
0753 template <>
0754 bool AlignmentParameterSelector::insideRanges<int>(int value, const std::vector<int> &ranges, bool /*isPhi*/) const {
0755   if (ranges.size() % 2 != 0) {
0756     cms::Exception("BadConfig") << "@SUB=AlignmentParameterSelector::insideRanges"
0757                                 << " need even number of entries in ranges instead of " << ranges.size();
0758     return false;
0759   }
0760 
0761   for (unsigned int i = 0; i < ranges.size(); i += 2) {
0762     if (ranges[i] <= value && value <= ranges[i + 1])
0763       return true;
0764   }
0765 
0766   return false;
0767 }
0768 
0769 bool AlignmentParameterSelector::isMemberOfVector(int value, const std::vector<int> &values) const {
0770   if (std::find(values.begin(), values.end(), value) != values.end())
0771     return true;
0772   return false;
0773 }
0774 
0775 //__________________________________________________________________________________________________
0776 std::vector<std::string> AlignmentParameterSelector::decompose(const std::string &s,
0777                                                                std::string::value_type delimiter) const {
0778   std::vector<std::string> result;
0779 
0780   std::string::size_type previousPos = 0;
0781   while (true) {
0782     const std::string::size_type delimiterPos = s.find(delimiter, previousPos);
0783     if (delimiterPos == std::string::npos) {
0784       result.push_back(s.substr(previousPos));  // until end
0785       break;
0786     }
0787     result.push_back(s.substr(previousPos, delimiterPos - previousPos));
0788     previousPos = delimiterPos + 1;  // +1: skip delimiter
0789   }
0790 
0791   return result;
0792 }
0793 
0794 //__________________________________________________________________________________________________
0795 std::vector<char> AlignmentParameterSelector::convertParamSel(const std::string &selString) const {
0796   // Convert selString into vector<char> of same length.
0797   // Note: Old implementation in AlignmentParameterBuilder was rigid in length,
0798   // expecting RigidBodyAlignmentParameters::N_PARAM.
0799   // But I prefer to be more general and allow other Alignables. It will throw anyway if
0800   // RigidBodyAlignmentParameters are build with wrong selection length.
0801   std::vector<char> result(selString.size());
0802 
0803   for (std::string::size_type pos = 0; pos < selString.size(); ++pos) {
0804     result[pos] = selString[pos];
0805   }
0806 
0807   return result;
0808 }
0809 
0810 //________________________________________________________________________________
0811 std::string AlignmentParameterSelector::setSpecials(const std::string &name) {
0812   // Use new string only, although direct erasing of found indicator causes problems for 'DSS',
0813   // but 'DSS' makes absolutely no sense!
0814   std::string newName(name);
0815 
0816   const std::string::size_type ss = newName.rfind("SS");
0817   if (ss != std::string::npos) {
0818     newName.erase(ss, 2);  // 2: length of 'SS'
0819     theOnlySS = true;
0820   } else {
0821     theOnlySS = false;
0822   }
0823 
0824   const std::string::size_type ds = newName.rfind("DS");
0825   if (ds != std::string::npos) {
0826     newName.erase(ds, 2);  // 2: length of 'DS'
0827     theOnlyDS = true;
0828   } else {
0829     theOnlyDS = false;
0830   }
0831 
0832   const std::string::size_type size = newName.size();
0833   const std::string::size_type layers = newName.rfind("Layers");
0834   if (layers != std::string::npos && size - layers - 2 == 6  // 2 digits, 6: length of 'Layers'
0835       && isdigit(newName[size - 1]) && isdigit(newName[size - 2])) {
0836     theSelLayers = true;
0837     theMinLayer = newName[size - 2] - '0';
0838     theMaxLayer = newName[size - 1] - '0';
0839     newName.erase(layers);
0840   } else {
0841     theSelLayers = false;
0842     theMinLayer = -1;
0843     theMaxLayer = 99999;
0844   }
0845 
0846   theRphiOrStereoDetUnit = Both;
0847   if (newName.rfind("Unit") != std::string::npos) {
0848     const std::string::size_type uRph = newName.rfind("UnitRphi");
0849     if (uRph != std::string::npos) {
0850       newName.erase(uRph + 4, 4);  // keep 'Unit' (4) and erase 'Rphi' (4)
0851       theRphiOrStereoDetUnit = Rphi;
0852     }
0853     const std::string::size_type uSte = newName.rfind("UnitStereo");
0854     if (uSte != std::string::npos) {
0855       newName.erase(uSte + 4, 6);  // keep 'Unit' (4) and erase 'Stereo' (6)
0856       theRphiOrStereoDetUnit = Stereo;
0857     }
0858   }
0859 
0860   if (newName != name) {
0861     LogDebug("Alignment") << "@SUB=AlignmentParameterSelector::setSpecials" << name << " becomes " << newName
0862                           << ", makes theOnlySS " << theOnlySS << ", theOnlyDS " << theOnlyDS << ", theSelLayers "
0863                           << theSelLayers << ", theMinLayer " << theMinLayer << ", theMaxLayer " << theMaxLayer
0864                           << ", theRphiOrStereoDetUnit " << theRphiOrStereoDetUnit;
0865   }
0866 
0867   return newName;
0868 }
0869 
0870 //________________________________________________________________________________
0871 unsigned int AlignmentParameterSelector::addAllDets(const std::vector<char> &paramSel) {
0872   unsigned int numAli = 0;
0873 
0874   numAli += this->add(theTracker->barrelGeomDets(), paramSel);           // TIB+TOB
0875   numAli += this->add(theTracker->endcapGeomDets(), paramSel);           // TEC
0876   numAli += this->add(theTracker->TIDGeomDets(), paramSel);              // TID
0877   numAli += this->add(theTracker->pixelHalfBarrelGeomDets(), paramSel);  // PixelBarrel
0878   numAli += this->add(theTracker->pixelEndcapGeomDets(), paramSel);      // PixelEndcap
0879 
0880   return numAli;
0881 }
0882 
0883 //________________________________________________________________________________
0884 unsigned int AlignmentParameterSelector::addAllRods(const std::vector<char> &paramSel) {
0885   unsigned int numAli = 0;
0886 
0887   numAli += this->add(theTracker->barrelRods(), paramSel);              // TIB+TOB
0888   numAli += this->add(theTracker->pixelHalfBarrelLadders(), paramSel);  // PixelBarrel
0889   numAli += this->add(theTracker->endcapPetals(), paramSel);            // TEC
0890   numAli += this->add(theTracker->TIDRings(), paramSel);                // TID
0891   numAli += this->add(theTracker->pixelEndcapPetals(), paramSel);       // PixelEndcap
0892 
0893   return numAli;
0894 }
0895 
0896 //________________________________________________________________________________
0897 unsigned int AlignmentParameterSelector::addAllLayers(const std::vector<char> &paramSel) {
0898   unsigned int numAli = 0;
0899 
0900   numAli += this->add(theTracker->barrelLayers(), paramSel);           // TIB+TOB
0901   numAli += this->add(theTracker->pixelHalfBarrelLayers(), paramSel);  // PixelBarrel
0902   numAli += this->add(theTracker->endcapLayers(), paramSel);           // TEC
0903   numAli += this->add(theTracker->TIDLayers(), paramSel);              // TID
0904   numAli += this->add(theTracker->pixelEndcapLayers(), paramSel);      // PixelEndcap
0905 
0906   return numAli;
0907 }
0908 
0909 //________________________________________________________________________________
0910 unsigned int AlignmentParameterSelector::addAllAlignables(const std::vector<char> &paramSel) {
0911   unsigned int numAli = 0;
0912 
0913   numAli += this->addAllDets(paramSel);
0914   numAli += this->addAllRods(paramSel);
0915   numAli += this->addAllLayers(paramSel);
0916   numAli += this->add(theTracker->components(), paramSel);
0917 
0918   return numAli;
0919 }