Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:14:33

0001 /** \class SiPixelStatusManager
0002  *  helper class that set up IOV strcutre of SiPixelDetectorStatus
0003  *
0004  *  \author 
0005  */
0006 
0007 #include "CalibTracker/SiPixelQuality/interface/SiPixelStatusManager.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "DataFormats/Common/interface/Handle.h"
0010 #include "FWCore/Framework/interface/ESHandle.h"
0011 #include <vector>
0012 #include <cmath>
0013 #include <climits>
0014 
0015 #include <iostream>
0016 
0017 using namespace edm;
0018 using namespace std;
0019 
0020 //--------------------------------------------------------------------------------------------------
0021 SiPixelStatusManager::SiPixelStatusManager() {}
0022 
0023 //--------------------------------------------------------------------------------------------------
0024 SiPixelStatusManager::SiPixelStatusManager(const ParameterSet& iConfig, edm::ConsumesCollector&& iC)
0025     : outputBase_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0026                       .getUntrackedParameter<std::string>("outputBase")),
0027       aveDigiOcc_(iConfig.getParameter<edm::ParameterSet>("SiPixelStatusManagerParameters")
0028                       .getUntrackedParameter<int>("aveDigiOcc")),
0029       nLumi_(iConfig.getParameter<edm::ParameterSet>("SiPixelStatusManagerParameters")
0030                  .getUntrackedParameter<int>("resetEveryNLumi")),
0031       moduleName_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0032                       .getUntrackedParameter<std::string>("moduleName")),
0033       label_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0034                  .getUntrackedParameter<std::string>("label")) {
0035   edm::InputTag siPixelStatusTag_(moduleName_, label_);
0036   siPixelStatusToken_ = iC.consumes<SiPixelDetectorStatus, edm::InLumi>(siPixelStatusTag_);
0037 
0038   LogInfo("SiPixelStatusManager") << "Output base: " << outputBase_ << std::endl;
0039   reset();
0040 }
0041 
0042 //--------------------------------------------------------------------------------------------------
0043 SiPixelStatusManager::~SiPixelStatusManager() {}
0044 
0045 //--------------------------------------------------------------------------------------------------
0046 void SiPixelStatusManager::reset() {
0047   siPixelStatusMap_.clear();
0048   siPixelStatusVtr_.clear();
0049 }
0050 
0051 //--------------------------------------------------------------------------------------------------
0052 bool SiPixelStatusManager::rankByLumi(SiPixelDetectorStatus status1, SiPixelDetectorStatus status2) {
0053   return (status1.getLSRange().first < status2.getLSRange().first);
0054 }
0055 
0056 void SiPixelStatusManager::createPayloads() {
0057   //only create std::map payloads when the number of non-zero DIGI lumi sections is greater than ZERO otherwise segmentation fault
0058   if (!siPixelStatusVtr_.empty()) {
0059     // sort the vector according to lumi
0060     std::sort(siPixelStatusVtr_.begin(), siPixelStatusVtr_.end(), SiPixelStatusManager::rankByLumi);
0061 
0062     // create FEDerror25 ROCs and bad ROCs from PCL
0063     SiPixelStatusManager::createFEDerror25();
0064     SiPixelStatusManager::createBadComponents();
0065 
0066     // realse the cost of siPixelStatusVtr_ since it is not needed anymore
0067     siPixelStatusVtr_.clear();
0068   }
0069 }
0070 
0071 //--------------------------------------------------------------------------------------------------
0072 void SiPixelStatusManager::readLumi(const LuminosityBlock& iLumi) {
0073   edm::Handle<SiPixelDetectorStatus> siPixelStatusHandle;
0074   iLumi.getByToken(siPixelStatusToken_, siPixelStatusHandle);
0075 
0076   if (siPixelStatusHandle.isValid()) {  // check the product
0077     SiPixelDetectorStatus tmpStatus = (*siPixelStatusHandle);
0078     if (tmpStatus.digiOccDET() > 0) {  // only put in SiPixelDetectorStatus with non zero digi (pixel hit)
0079       siPixelStatusVtr_.push_back(tmpStatus);
0080     }
0081   } else {
0082     edm::LogWarning("SiPixelStatusManager") << " SiPixelDetectorStatus is not valid for run " << iLumi.run() << " lumi "
0083                                             << iLumi.luminosityBlock() << std::endl;
0084   }
0085 }
0086 
0087 //--------------------------------------------------------------------------------------------------
0088 void SiPixelStatusManager::createBadComponents() {
0089   siPixelStatusVtr_iterator firstStatus = siPixelStatusVtr_.begin();
0090   siPixelStatusVtr_iterator lastStatus = siPixelStatusVtr_.end();
0091 
0092   siPixelStatusMap_.clear();
0093 
0094   // doesn't work for nLumi_=1 cos any integer can be completely divided by 1
0095   if (outputBase_ == "nLumibased" && nLumi_ > 1) {
0096     // if the total number of Lumi Blocks can't be completely divided by nLumi_,
0097     // the residual Lumi Blocks will be as the last IOV
0098     int iterationLumi = 0;
0099 
0100     LuminosityBlockNumber_t tmpLumi;
0101     SiPixelDetectorStatus tmpSiPixelStatus;
0102     for (siPixelStatusVtr_iterator it = firstStatus; it != lastStatus; it++) {
0103       // this is the begining of an IOV
0104       if (iterationLumi % nLumi_ == 0) {
0105         tmpLumi = edm::LuminosityBlockNumber_t(it->getLSRange().first);
0106         tmpSiPixelStatus = (*it);
0107       }
0108 
0109       // keep update detector status up to nLumi_ lumi sections
0110       if (iterationLumi % nLumi_ > 0) {
0111         tmpSiPixelStatus.updateDetectorStatus((*it));
0112         tmpSiPixelStatus.setLSRange(int(tmpLumi), (*it).getLSRange().second);
0113       }
0114 
0115       siPixelStatusVtr_iterator currentIt = it;
0116       siPixelStatusVtr_iterator nextIt = std::next(currentIt);
0117       // wirte out if current lumi is the last lumi-section in the IOV
0118       if (iterationLumi % nLumi_ == nLumi_ - 1 || nextIt == lastStatus) {
0119         // fill it into a new map (with IOV structured)
0120         siPixelStatusMap_[tmpLumi] = tmpSiPixelStatus;
0121       }
0122 
0123       iterationLumi = iterationLumi + 1;
0124     }
0125 
0126     // check whether there is not enough number of Lumi in the last IOV
0127     // (only when siPixelStatusVtr_.size() > nLumi_ or equivalently current siPixelStatusMap_.size()>1
0128     //            (otherwise there will be only one IOV, and not previous IOV before the last IOV)
0129     //            and the number of lumi can not be completely divided by the nLumi_.
0130     //                (then the number of lumis in the last IOV is equal to the residual, which is less than nLumi_)
0131     // if it is, combine last IOV with the IOV before it
0132     if (siPixelStatusVtr_.size() % nLumi_ != 0 && siPixelStatusMap_.size() > 1) {
0133       // start from the iterator of the end of std::map
0134       siPixelStatusMap_iterator iterEnd = siPixelStatusMap_.end();
0135       // the last IOV
0136       siPixelStatusMap_iterator iterLastIOV = std::prev(iterEnd);
0137       // the IOV before the last IOV
0138       siPixelStatusMap_iterator iterBeforeLastIOV = std::prev(iterLastIOV);
0139 
0140       // combine the last IOV data to the IOV before the last IOV
0141       (iterBeforeLastIOV->second).updateDetectorStatus(iterLastIOV->second);
0142       (iterBeforeLastIOV->second)
0143           .setLSRange((iterBeforeLastIOV->second).getLSRange().first, (iterLastIOV->second).getLSRange().second);
0144 
0145       // delete the last IOV, so the IOV before the last IOV becomes the new last IOV
0146       siPixelStatusMap_.erase(iterLastIOV);
0147     }
0148 
0149   } else if (outputBase_ == "dynamicLumibased") {
0150     double aveDigiOcc = 1.0 * aveDigiOcc_;
0151 
0152     edm::LuminosityBlockNumber_t tmpLumi;
0153     SiPixelDetectorStatus tmpSiPixelStatus;
0154     bool isNewIOV = true;
0155 
0156     int counter = 0;
0157     for (siPixelStatusVtr_iterator it = firstStatus; it != lastStatus; it++) {
0158       if (isNewIOV) {  // if it is new IOV, init with the current data
0159         tmpLumi = edm::LuminosityBlockNumber_t(it->getLSRange().first);
0160         tmpSiPixelStatus = (*it);
0161       } else {  // if it is not new IOV, append current data
0162         tmpSiPixelStatus.updateDetectorStatus((*it));
0163         tmpSiPixelStatus.setLSRange(int(tmpLumi), (*it).getLSRange().second);
0164       }
0165 
0166       // if reaching the end of data, write the last IOV to the map whatsoevec
0167       siPixelStatusVtr_iterator currentIt = it;
0168       siPixelStatusVtr_iterator nextIt = std::next(currentIt);
0169       if (tmpSiPixelStatus.perRocDigiOcc() < aveDigiOcc && nextIt != lastStatus) {
0170         isNewIOV = false;  // if digi occ is not enough, next data will not belong to new IOV
0171       } else {             // if (accunumated) digi occ is enough, write the data to the map
0172         isNewIOV = true;
0173         siPixelStatusMap_[tmpLumi] = tmpSiPixelStatus;
0174         // so next loop is the begining of a new IOV
0175       }
0176       counter++;
0177 
0178     }  // end of siPixelStatusMap
0179 
0180     // check whether last IOV has enough statistics
0181     // (ONLY when there are more than oneIOV(otherwise there is NO previous IOV before the last IOV) )
0182     // if not, combine with previous IOV
0183     if (siPixelStatusMap_.size() > 1) {
0184       // start from the end iterator of the std::map
0185       siPixelStatusMap_iterator iterEnd = siPixelStatusMap_.end();
0186       // the last IOV
0187       siPixelStatusMap_iterator iterLastIOV = std::prev(iterEnd);
0188       // if the statistics of the last IOV is not enough
0189       if ((iterLastIOV->second).perRocDigiOcc() < aveDigiOcc) {
0190         // the IOV before the last IOV of the map
0191         siPixelStatusMap_iterator iterBeforeLastIOV = std::prev(iterLastIOV);
0192         // combine the last IOV data to the IOV before the last IOV
0193         (iterBeforeLastIOV->second).updateDetectorStatus(iterLastIOV->second);
0194         (iterBeforeLastIOV->second)
0195             .setLSRange((iterBeforeLastIOV->second).getLSRange().first, (iterLastIOV->second).getLSRange().second);
0196         // erase the last IOV, so the IOV before the last IOV becomes the new last IOV
0197         siPixelStatusMap_.erase(iterLastIOV);
0198       }
0199     }
0200 
0201   } else if (outputBase_ == "runbased" || ((int(siPixelStatusVtr_.size()) <= nLumi_ && outputBase_ == "nLumibased"))) {
0202     edm::LuminosityBlockNumber_t tmpLumi = edm::LuminosityBlockNumber_t(firstStatus->getLSRange().first);
0203     SiPixelDetectorStatus tmpSiPixelStatus = (*firstStatus);
0204 
0205     siPixelStatusVtr_iterator nextStatus = ++siPixelStatusVtr_.begin();
0206     for (siPixelStatusVtr_iterator it = nextStatus; it != lastStatus; it++) {
0207       tmpSiPixelStatus.updateDetectorStatus((*it));
0208       tmpSiPixelStatus.setLSRange(int(tmpLumi), (*it).getLSRange().second);
0209     }
0210 
0211     siPixelStatusMap_[tmpLumi] = tmpSiPixelStatus;
0212 
0213   } else {
0214     LogInfo("SiPixelStatusManager") << "Unrecognized payload outputBase parameter: " << outputBase_ << endl;
0215   }
0216 }
0217 
0218 void SiPixelStatusManager::createFEDerror25() {
0219   // initialize the first IOV and SiPixelDetector status (in the first IOV)
0220   siPixelStatusVtr_iterator firstStatus = siPixelStatusVtr_.begin();
0221   edm::LuminosityBlockNumber_t firstLumi = edm::LuminosityBlockNumber_t(firstStatus->getLSRange().first);
0222   SiPixelDetectorStatus firstFEDerror25 = (*firstStatus);
0223   FEDerror25Map_[firstLumi] = firstFEDerror25.getFEDerror25Rocs();
0224 
0225   siPixelStatusVtr_iterator lastStatus = siPixelStatusVtr_.end();
0226 
0227   ///////////
0228   bool sameAsLastIOV = true;
0229   edm::LuminosityBlockNumber_t previousLumi = firstLumi;
0230 
0231   siPixelStatusVtr_iterator secondStatus = std::next(siPixelStatusVtr_.begin());
0232   for (siPixelStatusVtr_iterator it = secondStatus; it != lastStatus; it++) {
0233     // init for each lumi section (iterator)
0234     edm::LuminosityBlockNumber_t tmpLumi = edm::LuminosityBlockNumber_t(it->getLSRange().first);
0235     SiPixelDetectorStatus tmpFEDerror25 = (*it);
0236 
0237     std::map<int, std::vector<int> > tmpBadRocLists = tmpFEDerror25.getFEDerror25Rocs();
0238 
0239     std::map<int, SiPixelModuleStatus>::iterator itModEnd = tmpFEDerror25.end();
0240     for (std::map<int, SiPixelModuleStatus>::iterator itMod = tmpFEDerror25.begin(); itMod != itModEnd; ++itMod) {
0241       int detid = itMod->first;
0242       // if the badroc list differs for any detid, update the payload
0243       if (tmpBadRocLists[detid] != (FEDerror25Map_[previousLumi])[detid]) {
0244         sameAsLastIOV = false;
0245         break;  // jump out of the loop once a new payload is found
0246       }
0247     }
0248 
0249     if (sameAsLastIOV == false) {
0250       //only write new IOV when this Lumi's FEDerror25 ROC list is not equal to the previous one
0251       FEDerror25Map_[tmpLumi] = tmpBadRocLists;
0252       // and reset
0253       previousLumi = tmpLumi;
0254       sameAsLastIOV = true;
0255     }
0256   }
0257 }