Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:35:14

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     for (siPixelStatusVtr_iterator it = firstStatus; it != lastStatus; it++) {
0157       if (isNewIOV) {  // if it is new IOV, init with the current data
0158         tmpLumi = edm::LuminosityBlockNumber_t(it->getLSRange().first);
0159         tmpSiPixelStatus = (*it);
0160       } else {  // if it is not new IOV, append current data
0161         tmpSiPixelStatus.updateDetectorStatus((*it));
0162         tmpSiPixelStatus.setLSRange(int(tmpLumi), (*it).getLSRange().second);
0163       }
0164 
0165       // if reaching the end of data, write the last IOV to the map whatsoevec
0166       siPixelStatusVtr_iterator currentIt = it;
0167       siPixelStatusVtr_iterator nextIt = std::next(currentIt);
0168       if (tmpSiPixelStatus.perRocDigiOcc() < aveDigiOcc && nextIt != lastStatus) {
0169         isNewIOV = false;  // if digi occ is not enough, next data will not belong to new IOV
0170       } else {             // if (accunumated) digi occ is enough, write the data to the map
0171         isNewIOV = true;
0172         siPixelStatusMap_[tmpLumi] = tmpSiPixelStatus;
0173         // so next loop is the begining of a new IOV
0174       }
0175 
0176     }  // end of siPixelStatusMap
0177 
0178     // check whether last IOV has enough statistics
0179     // (ONLY when there are more than oneIOV(otherwise there is NO previous IOV before the last IOV) )
0180     // if not, combine with previous IOV
0181     if (siPixelStatusMap_.size() > 1) {
0182       // start from the end iterator of the std::map
0183       siPixelStatusMap_iterator iterEnd = siPixelStatusMap_.end();
0184       // the last IOV
0185       siPixelStatusMap_iterator iterLastIOV = std::prev(iterEnd);
0186       // if the statistics of the last IOV is not enough
0187       if ((iterLastIOV->second).perRocDigiOcc() < aveDigiOcc) {
0188         // the IOV before the last IOV of the map
0189         siPixelStatusMap_iterator iterBeforeLastIOV = std::prev(iterLastIOV);
0190         // combine the last IOV data to the IOV before the last IOV
0191         (iterBeforeLastIOV->second).updateDetectorStatus(iterLastIOV->second);
0192         (iterBeforeLastIOV->second)
0193             .setLSRange((iterBeforeLastIOV->second).getLSRange().first, (iterLastIOV->second).getLSRange().second);
0194         // erase the last IOV, so the IOV before the last IOV becomes the new last IOV
0195         siPixelStatusMap_.erase(iterLastIOV);
0196       }
0197     }
0198 
0199   } else if (outputBase_ == "runbased" || ((int(siPixelStatusVtr_.size()) <= nLumi_ && outputBase_ == "nLumibased"))) {
0200     edm::LuminosityBlockNumber_t tmpLumi = edm::LuminosityBlockNumber_t(firstStatus->getLSRange().first);
0201     SiPixelDetectorStatus tmpSiPixelStatus = (*firstStatus);
0202 
0203     siPixelStatusVtr_iterator nextStatus = ++siPixelStatusVtr_.begin();
0204     for (siPixelStatusVtr_iterator it = nextStatus; it != lastStatus; it++) {
0205       tmpSiPixelStatus.updateDetectorStatus((*it));
0206       tmpSiPixelStatus.setLSRange(int(tmpLumi), (*it).getLSRange().second);
0207     }
0208 
0209     siPixelStatusMap_[tmpLumi] = tmpSiPixelStatus;
0210 
0211   } else {
0212     LogInfo("SiPixelStatusManager") << "Unrecognized payload outputBase parameter: " << outputBase_ << endl;
0213   }
0214 }
0215 
0216 void SiPixelStatusManager::createFEDerror25() {
0217   // initialize the first IOV and SiPixelDetector status (in the first IOV)
0218   siPixelStatusVtr_iterator firstStatus = siPixelStatusVtr_.begin();
0219   edm::LuminosityBlockNumber_t firstLumi = edm::LuminosityBlockNumber_t(firstStatus->getLSRange().first);
0220   SiPixelDetectorStatus firstFEDerror25 = (*firstStatus);
0221   FEDerror25Map_[firstLumi] = firstFEDerror25.getFEDerror25Rocs();
0222 
0223   siPixelStatusVtr_iterator lastStatus = siPixelStatusVtr_.end();
0224 
0225   ///////////
0226   bool sameAsLastIOV = true;
0227   edm::LuminosityBlockNumber_t previousLumi = firstLumi;
0228 
0229   siPixelStatusVtr_iterator secondStatus = std::next(siPixelStatusVtr_.begin());
0230   for (siPixelStatusVtr_iterator it = secondStatus; it != lastStatus; it++) {
0231     // init for each lumi section (iterator)
0232     edm::LuminosityBlockNumber_t tmpLumi = edm::LuminosityBlockNumber_t(it->getLSRange().first);
0233     SiPixelDetectorStatus tmpFEDerror25 = (*it);
0234 
0235     std::map<int, std::vector<int> > tmpBadRocLists = tmpFEDerror25.getFEDerror25Rocs();
0236 
0237     std::map<int, SiPixelModuleStatus>::iterator itModEnd = tmpFEDerror25.end();
0238     for (std::map<int, SiPixelModuleStatus>::iterator itMod = tmpFEDerror25.begin(); itMod != itModEnd; ++itMod) {
0239       int detid = itMod->first;
0240       // if the badroc list differs for any detid, update the payload
0241       if (tmpBadRocLists[detid] != (FEDerror25Map_[previousLumi])[detid]) {
0242         sameAsLastIOV = false;
0243         break;  // jump out of the loop once a new payload is found
0244       }
0245     }
0246 
0247     if (sameAsLastIOV == false) {
0248       //only write new IOV when this Lumi's FEDerror25 ROC list is not equal to the previous one
0249       FEDerror25Map_[tmpLumi] = tmpBadRocLists;
0250       // and reset
0251       previousLumi = tmpLumi;
0252       sameAsLastIOV = true;
0253     }
0254   }
0255 }