Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:10

0001 /**
0002  * \file TkModuleGroupSelector.cc
0003  *
0004  *  \author Joerg Behr
0005  *  \date May 2013
0006  *  $Revision: 1.5 $
0007  *  $Date: 2013/06/19 08:33:03 $
0008  *  (last update by $Author: jbehr $)
0009  */
0010 
0011 #include "Alignment/CommonAlignmentAlgorithm/interface/TkModuleGroupSelector.h"
0012 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterSelector.h"
0013 #include "Alignment/CommonAlignment/interface/Alignable.h"
0014 #include "DataFormats/DetId/interface/DetId.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 
0017 #include <vector>
0018 #include <map>
0019 #include <set>
0020 
0021 //============================================================================
0022 TkModuleGroupSelector::TkModuleGroupSelector(AlignableTracker *aliTracker,
0023                                              const edm::ParameterSet &cfg,
0024                                              const std::vector<int> &sdets)
0025     : nparameters_(0), subdetids_(sdets) {
0026   //verify that all provided options are known
0027   std::vector<std::string> parameterNames = cfg.getParameterNames();
0028   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(); iParam != parameterNames.end();
0029        ++iParam) {
0030     const std::string &name = (*iParam);
0031     if (name != "RunRange" && name != "ReferenceRun" && name != "Granularity") {
0032       throw cms::Exception("BadConfig") << "@SUB=TkModuleGroupSelector::TkModuleGroupSelector:"
0033                                         << " Unknown parameter name '" << name << "' in PSet. Maybe a typo?";
0034     }
0035   }
0036 
0037   //extract the reference run range if defined
0038   const edm::RunNumber_t defaultReferenceRun =
0039       (cfg.exists("ReferenceRun") ? cfg.getParameter<edm::RunNumber_t>("ReferenceRun") : 0);
0040 
0041   //extract run range to be used for all module groups (if not locally overwritten)
0042   const std::vector<edm::RunNumber_t> defaultRunRange =
0043       (cfg.exists("RunRange") ? cfg.getParameter<std::vector<edm::RunNumber_t> >("RunRange")
0044                               : std::vector<edm::RunNumber_t>());
0045 
0046   // finally create everything from configuration
0047   this->createModuleGroups(
0048       aliTracker, cfg.getParameter<edm::VParameterSet>("Granularity"), defaultRunRange, defaultReferenceRun);
0049 }
0050 
0051 //============================================================================
0052 void TkModuleGroupSelector::fillDetIdMap(const unsigned int detid, const unsigned int groupid) {
0053   //only add new entries
0054   if (mapDetIdGroupId_.find(detid) == mapDetIdGroupId_.end()) {
0055     mapDetIdGroupId_.insert(std::pair<unsigned int, unsigned int>(detid, groupid));
0056   } else {
0057     throw cms::Exception("BadConfig") << "@SUB=TkModuleGroupSelector:fillDetIdMap:"
0058                                       << " Module with det ID " << detid << " configured in group " << groupid
0059                                       << " but it was already selected"
0060                                       << " in group " << mapDetIdGroupId_[detid] << ".";
0061   }
0062 }
0063 
0064 //============================================================================
0065 const bool TkModuleGroupSelector::testSplitOption(const edm::ParameterSet &pset) const {
0066   bool split = false;
0067   if (pset.exists("split")) {
0068     split = pset.getParameter<bool>("split");
0069   }
0070   return split;
0071 }
0072 
0073 //============================================================================
0074 bool TkModuleGroupSelector::createGroup(unsigned int &Id,
0075                                         const std::vector<edm::RunNumber_t> &range,
0076                                         const std::list<Alignable *> &selected_alis,
0077                                         const edm::RunNumber_t refrun) {
0078   bool modules_selected = false;
0079 
0080   referenceRun_.push_back(refrun);
0081   firstId_.push_back(Id);
0082   runRange_.push_back(range);
0083   for (std::list<Alignable *>::const_iterator it = selected_alis.begin(); it != selected_alis.end(); ++it) {
0084     this->fillDetIdMap((*it)->id(), firstId_.size() - 1);
0085     modules_selected = true;
0086   }
0087   if (refrun > 0 && !range.empty()) {  //FIXME: last condition not really needed?
0088     Id += range.size() - 1;
0089     nparameters_ += range.size() - 1;
0090   } else {
0091     Id += range.size();
0092     nparameters_ += range.size();
0093   }
0094 
0095   if (refrun > 0 && range.front() > refrun) {  //range.size() > 0 checked before
0096     throw cms::Exception("BadConfig") << "@SUB=TkModuleGroupSelector::createGroup:\n"
0097                                       << "Invalid combination of reference run number and specified run dependence"
0098                                       << "\n in module group " << firstId_.size() << "."
0099                                       << "\n Reference run number (" << refrun << ") is smaller than starting run "
0100                                       << "\n number (" << range.front() << ") of first IOV.";
0101   }
0102   return modules_selected;
0103 }
0104 
0105 //============================================================================
0106 void TkModuleGroupSelector::verifyParameterNames(const edm::ParameterSet &pset, unsigned int psetnr) const {
0107   std::vector<std::string> parameterNames = pset.getParameterNames();
0108   for (std::vector<std::string>::const_iterator iParam = parameterNames.begin(); iParam != parameterNames.end();
0109        ++iParam) {
0110     const std::string &name = (*iParam);
0111     if (name != "levels" && name != "RunRange" && name != "split" && name != "ReferenceRun") {
0112       throw cms::Exception("BadConfig") << "@SUB=TkModuleGroupSelector::verifyParameterNames:"
0113                                         << " Unknown parameter name '" << name << "' in PSet number " << psetnr
0114                                         << ". Maybe a typo?";
0115     }
0116   }
0117 }
0118 
0119 //============================================================================
0120 void TkModuleGroupSelector::createModuleGroups(AlignableTracker *aliTracker,
0121                                                const edm::VParameterSet &granularityConfig,
0122                                                const std::vector<edm::RunNumber_t> &defaultRunRange,
0123                                                edm::RunNumber_t defaultReferenceRun) {
0124   std::set<edm::RunNumber_t> localRunRange;
0125   nparameters_ = 0;
0126   unsigned int Id = 0;
0127   unsigned int psetnr = 0;
0128   //loop over all LA groups
0129   for (edm::VParameterSet::const_iterator pset = granularityConfig.begin(); pset != granularityConfig.end(); ++pset) {
0130     //test for unknown parameters
0131     this->verifyParameterNames((*pset), psetnr);
0132     psetnr++;
0133 
0134     bool modules_selected = false;  //track whether at all a module has been selected in this group
0135     const std::vector<edm::RunNumber_t> range =
0136         ((*pset).exists("RunRange") ? pset->getParameter<std::vector<edm::RunNumber_t> >("RunRange") : defaultRunRange);
0137     if (range.empty()) {
0138       throw cms::Exception("BadConfig") << "@SUB=TkModuleGroupSelector::createModuleGroups:\n"
0139                                         << "Run range array empty!";
0140     }
0141     const bool split = this->testSplitOption((*pset));
0142 
0143     edm::RunNumber_t refrun = 0;
0144     if ((*pset).exists("ReferenceRun")) {
0145       refrun = (*pset).getParameter<edm::RunNumber_t>("ReferenceRun");
0146     } else {
0147       refrun = defaultReferenceRun;
0148     }
0149 
0150     AlignmentParameterSelector selector(aliTracker);
0151     selector.clear();
0152     selector.addSelections((*pset).getParameter<edm::ParameterSet>("levels"));
0153 
0154     const auto &alis = selector.selectedAlignables();
0155     std::list<Alignable *> selected_alis;
0156     for (const auto &it : alis) {
0157       const auto &aliDaughts = it->deepComponents();
0158       for (const auto &iD : aliDaughts) {
0159         if (iD->alignableObjectId() == align::AlignableDetUnit || iD->alignableObjectId() == align::AlignableDet) {
0160           if (split) {
0161             modules_selected = this->createGroup(Id, range, std::list<Alignable *>(1, iD), refrun);
0162           } else {
0163             selected_alis.push_back(iD);
0164           }
0165         }
0166       }
0167     }
0168 
0169     if (!split) {
0170       modules_selected = this->createGroup(Id, range, selected_alis, refrun);
0171     }
0172 
0173     edm::RunNumber_t firstRun = 0;
0174     for (std::vector<edm::RunNumber_t>::const_iterator iRun = range.begin(); iRun != range.end(); ++iRun) {
0175       localRunRange.insert((*iRun));
0176       if ((*iRun) > firstRun) {
0177         firstRun = (*iRun);
0178       } else {
0179         throw cms::Exception("BadConfig") << "@SUB=TkModuleGroupSelector::createModuleGroups:"
0180                                           << " Run range not sorted.";
0181       }
0182     }
0183 
0184     if (!modules_selected) {
0185       throw cms::Exception("BadConfig") << "@SUB=TkModuleGroupSelector:createModuleGroups:"
0186                                         << " No module was selected in the module group selector in group "
0187                                         << (firstId_.size() - 1) << ".";
0188     }
0189   }
0190 
0191   //copy local set into the global vector of run boundaries
0192   for (std::set<edm::RunNumber_t>::const_iterator itRun = localRunRange.begin(); itRun != localRunRange.end();
0193        ++itRun) {
0194     globalRunRange_.push_back((*itRun));
0195   }
0196 }
0197 
0198 //============================================================================
0199 unsigned int TkModuleGroupSelector::getNumberOfParameters() const { return nparameters_; }
0200 
0201 //============================================================================
0202 unsigned int TkModuleGroupSelector::numIovs() const { return globalRunRange_.size(); }
0203 
0204 //============================================================================
0205 edm::RunNumber_t TkModuleGroupSelector::firstRunOfIOV(unsigned int iovNum) const {
0206   return iovNum < this->numIovs() ? globalRunRange_.at(iovNum) : 0;
0207 }
0208 
0209 //======================================================================
0210 int TkModuleGroupSelector::getParameterIndexFromDetId(unsigned int detId, edm::RunNumber_t run) const {
0211   // Return the index of the parameter that is used for this DetId.
0212   // If this DetId is not treated, return values < 0.
0213 
0214   const DetId temp_id(detId);
0215 
0216   int index = -1;
0217 
0218   bool sel = false;
0219   for (std::vector<int>::const_iterator itSubDets = subdetids_.begin(); itSubDets != subdetids_.end(); ++itSubDets) {
0220     if (temp_id.det() == DetId::Tracker && temp_id.subdetId() == (*itSubDets)) {
0221       sel = true;
0222       break;
0223     }
0224   }
0225 
0226   if (temp_id.det() != DetId::Tracker || !sel)
0227     return -1;
0228 
0229   std::map<unsigned int, unsigned int>::const_iterator it = mapDetIdGroupId_.find(detId);
0230   if (it != mapDetIdGroupId_.end()) {
0231     const unsigned int iAlignableGroup = (*it).second;
0232     const std::vector<edm::RunNumber_t> &runs = runRange_.at(iAlignableGroup);
0233     const unsigned int id0 = firstId_.at(iAlignableGroup);
0234     const edm::RunNumber_t refrun = referenceRun_.at(iAlignableGroup);
0235 
0236     unsigned int iovNum = 0;
0237     for (; iovNum < runs.size(); ++iovNum) {
0238       if (runs[iovNum] > run)
0239         break;
0240     }
0241     if (iovNum == 0) {
0242       throw cms::Exception("BadConfig") << "@SUB=TkModuleGroupSelector::getParameterIndexFromDetId:\n"
0243                                         << "Run " << run << " not foreseen for detid '" << detId << "'"
0244                                         << " in module group " << iAlignableGroup << ".";
0245     } else {
0246       --iovNum;
0247     }
0248 
0249     //test whether the iov contains the reference run
0250     if (refrun > 0) {  //if > 0 a reference run number has been provided
0251       if (iovNum + 1 == runs.size()) {
0252         if (refrun >= runs[iovNum])
0253           return -1;
0254       } else if ((iovNum + 1) < runs.size()) {
0255         if (refrun >= runs[iovNum] && refrun < runs[iovNum + 1]) {
0256           return -1;
0257         }
0258       }
0259       if (run > refrun) {
0260         //iovNum > 0 due to checks in createGroup(...) and createModuleGroups(...)
0261         //remove IOV in which the reference run can be found
0262         iovNum -= 1;
0263       }
0264     }
0265 
0266     index = id0 + iovNum;
0267   }
0268   return index;
0269 }