Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:23

0001 // -*- C++ -*-
0002 //
0003 // Package:    SiPixelCondObjOfflineBuilder
0004 // Class:      SiPixelCondObjOfflineBuilder
0005 //
0006 /**\class SiPixelCondObjOfflineBuilder SiPixelCondObjOfflineBuilder.h SiPixel/test/SiPixelCondObjOfflineBuilder.h
0007 
0008  Description: Test analyzer for writing pixel calibration in the DB
0009 
0010  Implementation:
0011      <Notes on implementation>
0012 */
0013 //
0014 // Original Author:  Vincenzo CHIOCHIA
0015 //         Created:  Tue Oct 17 17:40:56 CEST 2006
0016 // $Id: SiPixelCondObjOfflineBuilder.h,v 1.7 2009/11/20 19:21:29 rougny Exp $
0017 //
0018 //
0019 
0020 // system includes
0021 #include <string>
0022 #include <memory>
0023 #include <iostream>
0024 
0025 // user includes
0026 #include "CalibTracker/SiPixelESProducers/interface/SiPixelGainCalibrationOfflineService.h"
0027 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
0028 #include "CondFormats/SiPixelObjects/interface/PixelIndices.h"
0029 #include "DataFormats/DetId/interface/DetId.h"
0030 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0031 #include "FWCore/Framework/interface/Event.h"
0032 #include "FWCore/Framework/interface/EventSetup.h"
0033 #include "FWCore/Framework/interface/Frameworkfwd.h"
0034 #include "FWCore/Framework/interface/MakerMacros.h"
0035 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0036 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0037 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0038 #include "FWCore/ServiceRegistry/interface/Service.h"
0039 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0040 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
0041 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
0042 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0043 
0044 #include "CLHEP/Random/RandGauss.h"
0045 #include "CLHEP/Random/RandFlat.h"
0046 
0047 namespace cms {
0048   class SiPixelCondObjOfflineBuilder : public edm::one::EDAnalyzer<> {
0049   public:
0050     explicit SiPixelCondObjOfflineBuilder(const edm::ParameterSet& iConfig);
0051 
0052     void beginJob() override;
0053     void analyze(const edm::Event&, const edm::EventSetup&) override;
0054     bool loadFromFile();
0055 
0056   private:
0057     const bool appendMode_;
0058     const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> pddToken_;
0059     std::unique_ptr<SiPixelGainCalibrationOffline> SiPixelGainCalibration_;
0060     SiPixelGainCalibrationOfflineService SiPixelGainCalibrationService_;
0061     const std::string recordName_;
0062 
0063     const double meanPed_;
0064     const double rmsPed_;
0065     const double meanGain_;
0066     const double rmsGain_;
0067     const double meanPedFPix_;
0068     const double rmsPedFPix_;
0069     const double meanGainFPix_;
0070     const double rmsGainFPix_;
0071     const double deadFraction_;
0072     const double noisyFraction_;
0073     const double secondRocRowGainOffset_;
0074     const double secondRocRowPedOffset_;
0075     const int numberOfModules_;
0076     const bool fromFile_;
0077     const std::string fileName_;
0078     const bool generateColumns_;
0079 
0080     // Internal class
0081     class CalParameters {
0082     public:
0083       float p0;
0084       float p1;
0085     };
0086     // Map for storing calibration constants
0087     std::map<int, CalParameters, std::less<int> > calmap_;
0088     PixelIndices* pIndexConverter_;  // Pointer to the index converter
0089   };
0090 }  // namespace cms
0091 
0092 namespace cms {
0093   SiPixelCondObjOfflineBuilder::SiPixelCondObjOfflineBuilder(const edm::ParameterSet& iConfig)
0094       : appendMode_(iConfig.getUntrackedParameter<bool>("appendMode", true)),
0095         pddToken_(esConsumes()),
0096         SiPixelGainCalibration_(nullptr),
0097         SiPixelGainCalibrationService_(iConfig, consumesCollector()),
0098         recordName_(iConfig.getParameter<std::string>("record")),
0099         meanPed_(iConfig.getParameter<double>("meanPed")),
0100         rmsPed_(iConfig.getParameter<double>("rmsPed")),
0101         meanGain_(iConfig.getParameter<double>("meanGain")),
0102         rmsGain_(iConfig.getParameter<double>("rmsGain")),
0103         meanPedFPix_(iConfig.getUntrackedParameter<double>("meanPedFPix", meanPed_)),
0104         rmsPedFPix_(iConfig.getUntrackedParameter<double>("rmsPedFPix", rmsPed_)),
0105         meanGainFPix_(iConfig.getUntrackedParameter<double>("meanGainFPix", meanGain_)),
0106         rmsGainFPix_(iConfig.getUntrackedParameter<double>("rmsGainFPix", rmsGain_)),
0107         deadFraction_(iConfig.getParameter<double>("deadFraction")),
0108         noisyFraction_(iConfig.getParameter<double>("noisyFraction")),
0109         secondRocRowGainOffset_(iConfig.getParameter<double>("secondRocRowGainOffset")),
0110         secondRocRowPedOffset_(iConfig.getParameter<double>("secondRocRowPedOffset")),
0111         numberOfModules_(iConfig.getParameter<int>("numberOfModules")),
0112         fromFile_(iConfig.getParameter<bool>("fromFile")),
0113         fileName_(iConfig.getParameter<std::string>("fileName")),
0114         generateColumns_(iConfig.getUntrackedParameter<bool>("generateColumns", true)) {
0115     ::putenv((char*)"CORAL_AUTH_USER=me");
0116     ::putenv((char*)"CORAL_AUTH_PASSWORD=test");
0117   }
0118 
0119   void SiPixelCondObjOfflineBuilder::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0120     using namespace edm;
0121     unsigned int run = iEvent.id().run();
0122     int nmodules = 0;
0123     uint32_t nchannels = 0;
0124     //    int mycol = 415;
0125     //    int myrow = 159;
0126 
0127     edm::LogInfo("SiPixelCondObjOfflineBuilder")
0128         << "... creating dummy SiPixelGainCalibration Data for Run " << run << "\n " << std::endl;
0129     //
0130     // Instantiate Gain calibration offset and define pedestal/gain range
0131     //
0132     // note: the hard-coded range values are also used in random generation. That is why they're defined here
0133 
0134     float minped = 0.;
0135     float maxped = 100.;
0136     float mingain = 0.;
0137     float maxgain = 10.;
0138     SiPixelGainCalibration_ = std::make_unique<SiPixelGainCalibrationOffline>(minped, maxped, mingain, maxgain);
0139 
0140     const TrackerGeometry* pDD = &iSetup.getData(pddToken_);
0141     edm::LogInfo("SiPixelCondObjOfflineBuilder") << " There are " << pDD->dets().size() << " detectors" << std::endl;
0142 
0143     for (TrackerGeometry::DetContainer::const_iterator it = pDD->dets().begin(); it != pDD->dets().end(); it++) {
0144       if (dynamic_cast<PixelGeomDetUnit const*>((*it)) != nullptr) {
0145         uint32_t detid = ((*it)->geographicalId()).rawId();
0146 
0147         // Stop if module limit reached
0148         nmodules++;
0149         if (nmodules > numberOfModules_)
0150           break;
0151 
0152         const PixelGeomDetUnit* pixDet = dynamic_cast<const PixelGeomDetUnit*>((*it));
0153         const PixelTopology& topol = pixDet->specificTopology();
0154         // Get the module sizes.
0155         int nrows = topol.nrows();     // rows in x
0156         int ncols = topol.ncolumns();  // cols in y
0157         //edm::LogPrint("SiPixelCondObjOfflineBuilder") << " ---> PIXEL DETID " << detid << " Cols " << ncols << " Rows " << nrows << std::endl;
0158 
0159         double meanPedWork = meanPed_;
0160         double rmsPedWork = rmsPed_;
0161         double meanGainWork = meanGain_;
0162         double rmsGainWork = rmsGain_;
0163         DetId detId(detid);
0164         if (detId.subdetId() == 2) {  // FPIX
0165           meanPedWork = meanPedFPix_;
0166           rmsPedWork = rmsPedFPix_;
0167           meanGainWork = meanGainFPix_;
0168           rmsGainWork = rmsGainFPix_;
0169         }
0170 
0171         PixelIndices pIndexConverter(ncols, nrows);
0172 
0173         std::vector<char> theSiPixelGainCalibration;
0174 
0175         // Loop over columns and rows of this DetID
0176         for (int i = 0; i < ncols; i++) {
0177           float totalGain = 0.0;
0178           for (int j = 0; j < nrows; j++) {
0179             nchannels++;
0180             bool isDead = false;
0181             bool isNoisy = false;
0182             float ped = 0.0, gain = 0.0;
0183 
0184             if (fromFile_) {
0185               // Use calibration from a file
0186               int chipIndex = 0, colROC = 0, rowROC = 0;
0187 
0188               pIndexConverter.transformToROC(i, j, chipIndex, colROC, rowROC);
0189               int chanROC = PixelIndices::pixelToChannelROC(rowROC, colROC);  // use ROC coordinates
0190               //         float pp0=0, pp1=0;
0191               std::map<int, CalParameters, std::less<int> >::const_iterator it = calmap_.find(chanROC);
0192               CalParameters theCalParameters = (*it).second;
0193               ped = theCalParameters.p0;
0194               gain = theCalParameters.p1;
0195 
0196             } else {
0197               if (deadFraction_ > 0) {
0198                 double val = CLHEP::RandFlat::shoot();
0199                 if (val < deadFraction_) {
0200                   isDead = true;
0201                   //         edm::LogPrint("SiPixelCondObjOfflineBuilder") << "dead pixel " << detid << " " << i << "," << j << " " << val << std::endl;
0202                 }
0203               }
0204               if (deadFraction_ > 0 && !isDead) {
0205                 double val = CLHEP::RandFlat::shoot();
0206                 if (val < noisyFraction_) {
0207                   isNoisy = true;
0208                   //         edm::LogPrint("SiPixelCondObjOfflineBuilder") << "noisy pixel " << detid << " " << i << "," << j << " " << val << std::endl;
0209                 }
0210               }
0211 
0212               if (rmsPedWork > 0) {
0213                 ped = CLHEP::RandGauss::shoot(meanPedWork, rmsPedWork);
0214                 while (ped < minped || ped > maxped)
0215                   ped = CLHEP::RandGauss::shoot(meanPedWork, rmsPedWork);
0216               } else
0217                 ped = meanPedWork;
0218               if (rmsGainWork > 0) {
0219                 gain = CLHEP::RandGauss::shoot(meanGainWork, rmsGainWork);
0220                 while (gain < mingain || gain > maxgain)
0221                   gain = CLHEP::RandGauss::shoot(meanGainWork, rmsGainWork);
0222 
0223               } else
0224                 gain = meanGainWork;
0225             }
0226 
0227             //     if(i==mycol && j==myrow) {
0228             //       edm::LogPrint("SiPixelCondObjOfflineBuilder") << "       Col "<<i<<" Row "<<j<<" Ped "<<ped<<" Gain "<<gain<<std::endl;
0229             //     }
0230 
0231             //         gain =  2.8;
0232             //         ped  = 28.2;
0233 
0234             //if in the second row of rocs (i.e. a 2xN plaquette) add an offset (if desired) for testing
0235             if (j >= 80) {
0236               ped += secondRocRowPedOffset_;
0237               gain += secondRocRowGainOffset_;
0238 
0239               if (gain > maxgain)
0240                 gain = maxgain;
0241               else if (gain < mingain)
0242                 gain = mingain;
0243 
0244               if (ped > maxped)
0245                 ped = maxped;
0246               else if (ped < minped)
0247                 ped = minped;
0248             }
0249 
0250             totalGain += gain;
0251 
0252             if (!isDead && !isNoisy) {
0253               SiPixelGainCalibration_->setDataPedestal(ped, theSiPixelGainCalibration);
0254             } else if (isDead)  // dead pixel
0255               //         edm::LogPrint("SiPixelCondObjOfflineBuilder") << "filling pixel as dead for detid " << detid <<", col " << i << ", row" << j <<  std::endl;
0256               SiPixelGainCalibration_->setDeadPixel(theSiPixelGainCalibration);
0257             else if (isNoisy)  // dead pixel
0258               //         edm::LogPrint("SiPixelCondObjOfflineBuilder") << "filling pixel as dead for detid " << detid <<", col " << i << ", row" << j <<  std::endl;
0259               SiPixelGainCalibration_->setNoisyPixel(theSiPixelGainCalibration);
0260             if ((j + 1) % 80 == 0)  // fill the column average after ever ROC!
0261             {
0262               float averageGain = totalGain / static_cast<float>(80);
0263 
0264               if (generateColumns_) {
0265                 averageGain = gain;
0266               }
0267 
0268               //edm::LogPrint("SiPixelCondObjOfflineBuilder") << "Filling gain " << averageGain << " for col: " << i << " row: " << j << std::endl;
0269               SiPixelGainCalibration_->setDataGain(averageGain, 80, theSiPixelGainCalibration);
0270               totalGain = 0;
0271             }
0272           }
0273         }
0274 
0275         SiPixelGainCalibrationOffline::Range range(theSiPixelGainCalibration.begin(), theSiPixelGainCalibration.end());
0276         if (!SiPixelGainCalibration_->put(detid, range, ncols))
0277           edm::LogError("SiPixelCondObjOfflineBuilder")
0278               << "[SiPixelCondObjOfflineBuilder::analyze] detid already exists" << std::endl;
0279       }
0280     }
0281     edm::LogPrint("SiPixelCondObjOfflineBuilder") << " ---> PIXEL Modules  " << nmodules << std::endl;
0282     edm::LogPrint("SiPixelCondObjOfflineBuilder") << " ---> PIXEL Channels " << nchannels << std::endl;
0283 
0284     //   // Try to read object
0285     //    int mynmodules =0;
0286     //    for(TrackerGeometry::DetContainer::const_iterator it = pDD->dets().begin(); it != pDD->dets().end(); it++){
0287     //      if( dynamic_cast<PixelGeomDetUnit const*>((*it))!=0){
0288     //        uint32_t mydetid=((*it)->geographicalId()).rawId();
0289     //        mynmodules++;
0290     //        if( mynmodules > numberOfModules_) break;
0291     //        SiPixelGainCalibration::Range myrange = SiPixelGainCalibration_->getRange(mydetid);
0292     //        float mypedestal = SiPixelGainCalibration_->getPed (mycol,myrow,myrange,416);
0293     //        float mygain     = SiPixelGainCalibration_->getGain(mycol,myrow,myrange,416);
0294     //        //edm::LogPrint("SiPixelCondObjOfflineBuilder")<<" PEDESTAL "<< mypedestal<<" GAIN "<<mygain<<std::endl;
0295     //      }
0296     //    }
0297     // Write into DB
0298     edm::LogInfo("SiPixelCondOfflineBuilder") << "writing to DB, record = \"" << recordName_ << "\"";
0299     edm::Service<cond::service::PoolDBOutputService> mydbservice;
0300     if (!mydbservice.isAvailable()) {
0301       edm::LogError("SiPixelCondOfflineBuilder") << " db service unavailable";
0302       return;
0303     } else {
0304       edm::LogInfo("SiPixelCondOfflineBuilder") << " DB service OK";
0305     }
0306 
0307     try {
0308       if (mydbservice->isNewTagRequest(recordName_)) {
0309         mydbservice->createOneIOV<SiPixelGainCalibrationOffline>(
0310             *SiPixelGainCalibration_, mydbservice->beginOfTime(), recordName_);
0311       } else {
0312         mydbservice->appendOneIOV<SiPixelGainCalibrationOffline>(
0313             *SiPixelGainCalibration_, mydbservice->currentTime(), recordName_);
0314       }
0315       edm::LogInfo(" --- all OK");
0316     } catch (const cond::Exception& er) {
0317       edm::LogError("SiPixelCondObjOfflineBuilder") << er.what() << std::endl;
0318     } catch (const std::exception& er) {
0319       edm::LogError("SiPixelCondObjOfflineBuilder") << "caught std::exception " << er.what() << std::endl;
0320     } catch (...) {
0321       edm::LogError("SiPixelCondObjOfflineBuilder") << "Funny error" << std::endl;
0322     }
0323   }
0324 
0325   // ------------ method called once each job just before starting event loop  ------------
0326   void SiPixelCondObjOfflineBuilder::beginJob() {
0327     if (fromFile_) {
0328       if (loadFromFile()) {
0329         edm::LogInfo("SiPixelCondObjOfflineBuilder") << " Calibration loaded: Map size " << calmap_.size() << " max "
0330                                                      << calmap_.max_size() << " " << calmap_.empty() << std::endl;
0331       }
0332     }
0333   }
0334 
0335   bool SiPixelCondObjOfflineBuilder::loadFromFile() {
0336     float par0, par1;  //,par2,par3;
0337     int colid, rowid;  //rocid
0338     std::string name;
0339 
0340     std::ifstream in_file;                          // data file pointer
0341     in_file.open(fileName_.c_str(), std::ios::in);  // in C++
0342     if (in_file.bad()) {
0343       edm::LogError("SiPixelCondObjOfflineBuilder") << "Input file not found" << std::endl;
0344     }
0345     if (in_file.eof() != 0) {
0346       edm::LogError("SiPixelCondObjOfflineBuilder") << in_file.eof() << " " << in_file.gcount() << " " << in_file.fail()
0347                                                     << " " << in_file.good() << " end of file " << std::endl;
0348       return false;
0349     }
0350     //Load file header
0351     char line[500];
0352     for (int i = 0; i < 3; i++) {
0353       in_file.getline(line, 500, '\n');
0354       edm::LogInfo("SiPixelCondObjOfflineBuilder") << line << std::endl;
0355     }
0356     //Loading calibration constants from file, loop on pixels
0357     for (int i = 0; i < (52 * 80); i++) {
0358       in_file >> par0 >> par1 >> name >> colid >> rowid;
0359 
0360       edm::LogPrint("SiPixelCondObjOfflineBuilder")
0361           << " Col " << colid << " Row " << rowid << " P0 " << par0 << " P1 " << par1 << std::endl;
0362 
0363       CalParameters onePix;
0364       onePix.p0 = par0;
0365       onePix.p1 = par1;
0366 
0367       // Convert ROC pixel index to channel
0368       int chan = PixelIndices::pixelToChannelROC(rowid, colid);
0369       calmap_.insert(std::pair<int, CalParameters>(chan, onePix));
0370     }
0371 
0372     bool flag;
0373     if (calmap_.size() == 4160) {
0374       flag = true;
0375     } else {
0376       flag = false;
0377     }
0378     return flag;
0379   }
0380 
0381 }  // namespace cms
0382 
0383 using namespace cms;
0384 DEFINE_FWK_MODULE(SiPixelCondObjOfflineBuilder);