Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-02 04:16:20

0001 // -*- C++ -*-
0002 //
0003 // Package:    CondTools/SiStrip
0004 // Class:      SiStripApvGainFromFileBuilder
0005 //
0006 /**\class SiStripApvGainFromFileBuilder SiStripApvGainFromFileBuilder.cc
0007    Description: Created SiStripApvGain paylaods from tickmark height input ASCII files coming from
0008                 SiStrip opto-gain scans.
0009 */
0010 //
0011 //  Original Author: A. Di Mattia
0012 //  Contributors:    M. Musich    (modernization)
0013 //
0014 //  Created:  Wed, 1 Mar 2022 14:26:18 GMT
0015 //
0016 
0017 // STL includes
0018 #include <algorithm>
0019 #include <cstdint>
0020 #include <fstream>
0021 #include <iomanip>
0022 #include <iostream>
0023 #include <map>
0024 #include <sstream>
0025 #include <stdexcept>
0026 #include <utility>
0027 #include <vector>
0028 
0029 // user includes
0030 #include "CalibFormats/SiStripObjects/interface/SiStripDetCabling.h"
0031 #include "CalibTracker/Records/interface/SiStripDetCablingRcd.h"
0032 #include "CalibTracker/SiStripCommon/interface/SiStripDetInfoFileReader.h"
0033 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
0034 #include "CondFormats/SiStripObjects/interface/SiStripApvGain.h"
0035 #include "FWCore/Framework/interface/ESHandle.h"
0036 #include "FWCore/Framework/interface/EventSetup.h"
0037 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0038 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0039 #include "FWCore/ParameterSet/interface/FileInPath.h"
0040 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0041 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0042 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0043 #include "FWCore/ServiceRegistry/interface/Service.h"
0044 #include "FWCore/Utilities/interface/Exception.h"
0045 
0046 class SiStripApvGainFromFileBuilder : public edm::one::EDAnalyzer<> {
0047 public:
0048   //enum ExceptionType = { NotConnected, ZeroGainFromScan, NegativeGainFromScan };
0049 
0050   typedef std::map<uint32_t, float> Gain;
0051 
0052   typedef struct {
0053     uint32_t det_id;
0054     uint16_t offlineAPV_id;
0055     int onlineAPV_id;
0056     int FED_id;
0057     int FED_ch;
0058     int i2cAdd;
0059     bool is_connected;
0060     bool is_scanned;
0061     float gain_from_scan;
0062     float gain_in_db;
0063   } Summary;
0064 
0065   /** Brief Constructor.
0066    */
0067   explicit SiStripApvGainFromFileBuilder(const edm::ParameterSet& iConfig);
0068 
0069   /** Brief Destructor performing the memory cleanup.
0070    */
0071   ~SiStripApvGainFromFileBuilder() override;
0072 
0073   /** Brief One dummy-event analysis to create the database record.
0074    */
0075   void analyze(const edm::Event&, const edm::EventSetup&) override;
0076 
0077   /** Brief framework fillDescription
0078    */
0079   static void fillDescriptions(edm::ConfigurationDescriptions&);
0080 
0081 private:
0082   const edm::ESGetToken<SiStripDetCabling, SiStripDetCablingRcd> cablingToken_; /*!< ES token for the cabling */
0083   edm::FileInPath tfp_;        /*!< File Path for the tickmark scan with the APV gains. */
0084   double gainThreshold_;       /*!< Threshold for accepting the APV gain in the tickmark scan file. */
0085   double dummyAPVGain_;        /*!< Dummy value for the APV gain. */
0086   bool doGainNormalization_;   /*!< Normalize the tickmark for the APV gain. */
0087   bool putDummyIntoUncabled_;  /*!< Flag for putting the dummy gain in the channels not actuall cabled. */
0088   bool putDummyIntoUnscanned_; /*!< Flag for putting the dummy gain in the chennals not scanned. */
0089   bool putDummyIntoOffChannels_; /*!< Flag for putting the dummy gain in the channels that were off during the tickmark scan. */
0090   bool putDummyIntoBadChannels_; /*!< Flag for putting the dummy gain in the channels with negative gains. */
0091   bool outputMaps_;              /*!< Flag for dumping the internal maps on ASCII files. */
0092   bool outputSummary_;           /*!< Flag for dumping the summary of the exceptions during the DB filling. */
0093 
0094   const SiStripDetCabling* detCabling_; /*!< Description of detector cabling. */
0095 
0096   /** Brief Maps [det_id <--> gains] arranged per APV indexes.
0097    */
0098   std::vector<Gain*> gains_;          /*!< Mapping channels with positive heights. */
0099   std::vector<Gain*> negative_gains_; /*!< Mapping channels sending bad data. */
0100   std::vector<Gain*> null_gains_;     /*!< Mapping channels switched off during the scan. */
0101 
0102   /** Brief Collection of the channels entered in the DB without exceptions.
0103    * The channels whose APV gain has been input in the DB straight from the 
0104    * tickmark scan are collected in the summary vector. The summary list is
0105    * dumped in the SiStripApvGainSummary.txt at the end of the job. 
0106    */
0107   std::vector<Summary> summary_; /*!< Collection of channel with no DB filling exceptions. */
0108 
0109   /** Brief Collection of the exceptions encountered when filling the DB. 
0110    * An exception occur for all the non-cabled channels ( no gain associated
0111    * in the tikmark file) and for all the channels that were off ( with zero
0112    * gain associated) or sending corrupted data (with negative values in the
0113    * tickmark file). At the end of the job the exception summary is dumped in
0114    * SiStripApvGainExceptionSummary.txt.
0115    */
0116   std::vector<Summary> ex_summary_; /*!< Collection of DB filling exceptions. */
0117 
0118   /** Brief Read the ASCII file containing the tickmark gains.
0119    * This method reads the ASCII files that contains the tickmark heights for 
0120    * every APV. The heights are first translated into gains, dividing by 640,
0121    * then are stored into maps to be associated to the detector ids. Maps are
0122    * created for every APV index. 
0123    * Negative and Zero heights, yielding to a non physical gain, are stored 
0124    * into separate maps.
0125    *   Negative gain: channels sending bad data at the tickmark scan. 
0126    *   Zero gain    : channels switched off during the tickmark scan. 
0127    */
0128   void read_tickmark(void);
0129 
0130   /** Brief Returns the mapping among channels and gain heights for the APVs.
0131    * This method searchs the mapping of detector Ids <-> gains provided. If the
0132    * mapping exists for the requested APV it is returned; if not a new empty
0133    * mapping is created, inserted and retruned. The methods accepts onlineIDs
0134    * running from 0 to 5. 
0135    */
0136   Gain* get_map(std::vector<Gain*>* maps, int onlineAPV_id);
0137 
0138   /** Brief Dumps the internal mapping on a ASCII files.
0139    * This method dumps the detector id <-> gain maps into acii files separated
0140    * for each APV. The basenmae of for the acii file has to be provided as a
0141    * input parameter.
0142    */
0143   void output_maps(std::vector<Gain*>* maps, const char* basename) const;
0144 
0145   /** Brief Dump the exceptions summary on a ASCII file.
0146    * This method dumps the online coordinate of the channels for which  there
0147    * was an exception for filling the database record. Exceptions are the non
0148    * cabled modules, the channels that were off during the tickmark scan, the
0149    * channels sending corrupted data duirng the tickmark scan. These exceptions
0150    * have been solved putting a dummy gain into the DB record or putting a zero
0151    * gain.
0152    */
0153   void output_summary() const;
0154 
0155   /** Brief Format the output line for the channel summary.
0156    */
0157   void format_summary(std::stringstream& line, Summary summary) const;
0158 
0159   /** Brief Find the gain value for a pair det_id, APV_id in the internal maps.
0160    */
0161   bool gain_from_maps(uint32_t det_id, int onlineAPV_id, float& gain);
0162   void gain_from_maps(uint32_t det_id, uint16_t totalAPVs, std::vector<std::pair<int, float>>& gain) const;
0163 
0164   /** Brief Convert online APV id into offline APV id.
0165    */
0166   int online2offline(uint16_t onlineAPV_id, uint16_t totalAPVs) const;
0167 
0168   static constexpr float k_GainNormalizationFactor = 640.f;
0169   static constexpr float k_InvalidGain = 999999.f;
0170 };
0171 
0172 static const struct clean_up {
0173   void operator()(SiStripApvGainFromFileBuilder::Gain* el) {
0174     if (el != nullptr) {
0175       el->clear();
0176       delete el;
0177       el = nullptr;
0178     }
0179   }
0180 } CleanUp;
0181 
0182 SiStripApvGainFromFileBuilder::~SiStripApvGainFromFileBuilder() {
0183   for_each(gains_.begin(), gains_.end(), CleanUp);
0184   for_each(negative_gains_.begin(), negative_gains_.end(), CleanUp);
0185   for_each(null_gains_.begin(), null_gains_.end(), CleanUp);
0186 }
0187 
0188 SiStripApvGainFromFileBuilder::SiStripApvGainFromFileBuilder(const edm::ParameterSet& iConfig)
0189     : cablingToken_(esConsumes()),
0190       tfp_(iConfig.getParameter<edm::FileInPath>("tickFile")),
0191       gainThreshold_(iConfig.getParameter<double>("gainThreshold")),
0192       dummyAPVGain_(iConfig.getParameter<double>("dummyAPVGain")),
0193       doGainNormalization_(iConfig.getParameter<bool>("doGainNormalization")),
0194       putDummyIntoUncabled_(iConfig.getParameter<bool>("putDummyIntoUncabled")),
0195       putDummyIntoUnscanned_(iConfig.getParameter<bool>("putDummyIntoUnscanned")),
0196       putDummyIntoOffChannels_(iConfig.getParameter<bool>("putDummyIntoOffChannels")),
0197       putDummyIntoBadChannels_(iConfig.getParameter<bool>("putDummyIntoBadChannels")),
0198       outputMaps_(iConfig.getParameter<bool>("outputMaps")),
0199       outputSummary_(iConfig.getParameter<bool>("outputSummary")) {}
0200 
0201 void SiStripApvGainFromFileBuilder::analyze(const edm::Event& evt, const edm::EventSetup& iSetup) {
0202   //unsigned int run=evt.id().run();
0203 
0204   edm::LogInfo("SiStripApvGainFromFileBuilder") << "@SUB=analyze"
0205                                                 << "Insert SiStripApvGain Data.";
0206   this->read_tickmark();
0207 
0208   if (outputMaps_) {
0209     try {
0210       this->output_maps(&gains_, "tickmark_heights");
0211       this->output_maps(&negative_gains_, "negative_tickmark");
0212       this->output_maps(&null_gains_, "zero_tickmark");
0213     } catch (std::exception& e) {
0214       std::cerr << e.what() << std::endl;
0215     }
0216   }
0217 
0218   // Retrieve the SiStripDetCabling description
0219   detCabling_ = &iSetup.getData(cablingToken_);
0220 
0221   // APV gain record to be filled with gains and delivered into the database.
0222   auto obj = std::make_unique<SiStripApvGain>();
0223 
0224   const auto& reader =
0225       SiStripDetInfoFileReader::read(edm::FileInPath{SiStripDetInfoFileReader::kDefaultFile}.fullPath());
0226   const auto& DetInfos = reader.getAllData();
0227 
0228   LogTrace("SiStripApvGainFromFileBuilder") << "  det id  |APVOF| CON |APVON| FED |FEDCH|i2cAd|tickGain|" << std::endl;
0229 
0230   for (const auto& it : DetInfos) {
0231     // check if det id is correct and if it is actually cabled in the detector
0232     if (it.first == 0 || it.first == 0xFFFFFFFF) {
0233       edm::LogError("DetIdNotGood") << "@SUB=analyze"
0234                                     << "Wrong det id: " << it.first << "  ... neglecting!";
0235       continue;
0236     }
0237 
0238     // For the cabled det_id retrieve the number of APV connected
0239     // to the module with the FED cabling
0240     uint16_t nAPVs = 0;
0241     const std::vector<const FedChannelConnection*> connection = detCabling_->getConnections(it.first);
0242     for (unsigned int ca = 0; ca < connection.size(); ca++) {
0243       if (connection[ca] != nullptr) {
0244         nAPVs += (connection[ca])->nApvs();
0245         break;
0246       }
0247     }
0248 
0249     // check consistency among FED cabling and ideal cabling, exit on error
0250     if (!connection.empty() && nAPVs != (uint16_t)it.second.nApvs) {
0251       edm::LogError("SiStripCablingError")
0252           << "@SUB=analyze"
0253           << "det id " << it.first << ": APV number from FedCabling (" << nAPVs
0254           << ") is different from the APV number retrieved from the ideal cabling (" << it.second.nApvs << ").";
0255       throw("Inconsistency on the number of APVs.");
0256     }
0257 
0258     // eventually separate the processing for the module that are fully
0259     // uncabled. This is worth only if we decide not tu put the record
0260     // in the DB for the uncabled det_id.
0261     //if( !detCabling_->IsConnected(it.first) ) {
0262     //
0263     //  continue;
0264     //}
0265 
0266     //Gather the APV online id
0267     std::vector<std::pair<int, float>> tickmark_for_detId(it.second.nApvs, std::pair<int, float>(-1, k_InvalidGain));
0268     for (unsigned int ca = 0; ca < connection.size(); ca++) {
0269       if (connection[ca] != nullptr) {
0270         uint16_t id1 = (connection[ca])->i2cAddr(0) % 32;
0271         uint16_t id2 = (connection[ca])->i2cAddr(1) % 32;
0272         tickmark_for_detId[online2offline(id1, it.second.nApvs)].first = id1;
0273         tickmark_for_detId[online2offline(id2, it.second.nApvs)].first = id2;
0274       }
0275     }
0276     gain_from_maps(it.first, it.second.nApvs, tickmark_for_detId);
0277     std::vector<float> theSiStripVector;
0278 
0279     // Fill the gain in the DB object, apply the logic for the dummy values
0280     for (unsigned short j = 0; j < it.second.nApvs; j++) {
0281       Summary summary;
0282       summary.det_id = it.first;
0283       summary.offlineAPV_id = j;
0284       summary.onlineAPV_id = tickmark_for_detId.at(j).first;
0285       summary.is_connected = false;
0286       summary.FED_id = -1;
0287       summary.FED_ch = -1;
0288       summary.i2cAdd = -1;
0289 
0290       for (unsigned int ca = 0; ca < connection.size(); ca++) {
0291         if (connection[ca] != nullptr && (connection[ca])->i2cAddr(j % 2) % 32 == summary.onlineAPV_id) {
0292           summary.is_connected = (connection[ca])->isConnected();
0293           summary.FED_id = (connection[ca])->fedId();
0294           summary.FED_ch = (connection[ca])->fedCh();
0295           summary.i2cAdd = (connection[ca])->i2cAddr(j % 2);
0296         }
0297       }
0298 
0299       try {
0300         float gain = tickmark_for_detId[j].second;
0301         summary.gain_from_scan = gain;
0302         LogTrace("SiStripApvGainFromFileBuilder")
0303             << it.first << "  " << std::setw(3) << j << "   " << std::setw(3) << connection.size() << "   "
0304             << std::setw(3) << summary.onlineAPV_id << "    " << std::setw(3) << summary.FED_id << "   " << std::setw(3)
0305             << summary.FED_ch << "   " << std::setw(3) << summary.i2cAdd << "   " << std::setw(7)
0306             << summary.gain_from_scan << std::endl;
0307 
0308         if (gain != k_InvalidGain) {
0309           summary.is_scanned = true;
0310           if (gain > gainThreshold_) {
0311             if (doGainNormalization_) {
0312               // divide the tickmark by the normalization factor (640)
0313               gain /= k_GainNormalizationFactor;
0314             }
0315             summary.gain_in_db = gain;
0316             if (!summary.is_connected)
0317               ex_summary_.push_back(summary);
0318             else
0319               summary_.push_back(summary);
0320           } else {
0321             if (gain == 0.f) {
0322               summary.gain_in_db = (putDummyIntoOffChannels_ ? dummyAPVGain_ : 0.f);
0323               ex_summary_.push_back(summary);
0324             } else if (gain < 0.f) {
0325               summary.gain_in_db = (putDummyIntoBadChannels_ ? dummyAPVGain_ : 0.f);
0326               ex_summary_.push_back(summary);
0327             }
0328           }
0329         } else {
0330           summary.is_scanned = false;
0331           if (!summary.is_connected) {
0332             summary.gain_in_db = (putDummyIntoUncabled_ ? dummyAPVGain_ : 0.f);
0333           } else {
0334             summary.gain_in_db = (putDummyIntoUnscanned_ ? dummyAPVGain_ : 0.f);
0335           }
0336           ex_summary_.push_back(summary);
0337         }
0338 
0339         theSiStripVector.push_back(summary.gain_in_db);
0340         LogTrace("SiStripApvGainFromFileBuilder") << "output gain:" << summary.gain_in_db;
0341       } catch (std::exception& e) {
0342         std::cerr << e.what() << std::endl;
0343         edm::LogError("MappingError") << "@SUB=analyze"
0344                                       << "Job end prematurely.";
0345         return;
0346       }
0347     }
0348 
0349     SiStripApvGain::Range range(theSiStripVector.begin(), theSiStripVector.end());
0350     if (!obj->put(it.first, range))
0351       edm::LogError("IndexError") << "@SUB=analyze"
0352                                   << "detid already exists.";
0353   }
0354 
0355   if (outputSummary_)
0356     output_summary();
0357 
0358   //End now write sistripnoises data in DB
0359   edm::Service<cond::service::PoolDBOutputService> mydbservice;
0360 
0361   if (mydbservice.isAvailable()) {
0362     if (mydbservice->isNewTagRequest("SiStripApvGainRcd")) {
0363       mydbservice->createOneIOV<SiStripApvGain>(*obj, mydbservice->beginOfTime(), "SiStripApvGainRcd");
0364     } else {
0365       mydbservice->appendOneIOV<SiStripApvGain>(*obj, mydbservice->currentTime(), "SiStripApvGainRcd");
0366     }
0367   } else {
0368     edm::LogError("DBServiceNotAvailable") << "@SUB=analyze"
0369                                            << "DB Service is unavailable";
0370   }
0371 }
0372 
0373 void SiStripApvGainFromFileBuilder::read_tickmark() {
0374   // Connect file for input
0375   const auto& filename = tfp_.fullPath();
0376   std::ifstream thickmark_heights(filename.c_str());
0377 
0378   if (!thickmark_heights.is_open()) {
0379     edm::LogError("FileNotFound") << "@SUB=read_ticlmark"
0380                                   << "File with thickmark height file " << filename.c_str() << " cannot be opened!";
0381     return;
0382   }
0383 
0384   // clear internal maps
0385   for_each(gains_.begin(), gains_.end(), CleanUp);
0386   for_each(negative_gains_.begin(), negative_gains_.end(), CleanUp);
0387   for_each(null_gains_.begin(), null_gains_.end(), CleanUp);
0388 
0389   // read file and fill internal map
0390   uint32_t det_id = 0;
0391   uint32_t APV_id = 0;
0392   float tick_h = 0.;
0393 
0394   int count = -1;
0395 
0396   for (;;) {
0397     count++;
0398     thickmark_heights >> det_id >> APV_id >> tick_h;
0399 
0400     if (!(thickmark_heights.eof() || thickmark_heights.fail())) {
0401       if (count == 0) {
0402         LogTrace("Debug") << "Reading " << filename.c_str() << " for gathering the tickmark heights" << std::endl;
0403         LogTrace("Debug") << "|  Det Id   |  APV Id  |  Tickmark" << std::endl;
0404         LogTrace("Debug") << "+-----------+----------+----------" << std::endl;
0405       }
0406       LogTrace("Debug") << std::setw(11) << det_id << std::setw(8) << APV_id << std::setw(14) << tick_h << std::endl;
0407 
0408       // retrieve the map corresponding to the gain collection
0409       Gain* map = nullptr;
0410       if (tick_h > 0.f) {
0411         map = get_map(&gains_, APV_id);
0412       } else if (tick_h < 0.f) {
0413         map = get_map(&negative_gains_, APV_id);
0414       } else {
0415         // if tick_h == 0.f
0416         map = get_map(&null_gains_, APV_id);
0417       }
0418 
0419       // insert the gain value in the map
0420       if (map) {
0421         std::pair<Gain::iterator, bool> ret = map->insert(std::pair<uint32_t, float>(det_id, tick_h));
0422 
0423         if (ret.second == false) {
0424           edm::LogError("MapError") << "@SUB=read_tickmark"
0425                                     << "Cannot not insert gain for detector id " << det_id
0426                                     << " into the internal map: detector id already in the map.";
0427         }
0428       } else {
0429         edm::LogError("MapError") << "@SUB=read_tickmark"
0430                                   << "Cannot get the online-offline APV mapping!";
0431       }
0432     } else if (thickmark_heights.eof()) {
0433       edm::LogInfo("SiStripApvGainFromFileBuilder") << "@SUB=read_tickmark"
0434                                                     << "EOF of " << filename.c_str() << " reached.";
0435       break;
0436     } else if (thickmark_heights.fail()) {
0437       edm::LogError("FileiReadError") << "@SUB=read_tickmark"
0438                                       << "error while reading " << filename.c_str();
0439       break;
0440     }
0441   }
0442 
0443   thickmark_heights.close();
0444 }
0445 
0446 SiStripApvGainFromFileBuilder::Gain* SiStripApvGainFromFileBuilder::get_map(std::vector<Gain*>* maps,
0447                                                                             int onlineAPV_id) {
0448   Gain* map = nullptr;
0449   if (onlineAPV_id < 0 || onlineAPV_id > 5)
0450     return map;
0451 
0452   try {
0453     map = maps->at(onlineAPV_id);
0454   } catch (const std::out_of_range&) {
0455     if (maps->size() < static_cast<unsigned int>(onlineAPV_id))
0456       maps->resize(onlineAPV_id);
0457     maps->insert(maps->begin() + onlineAPV_id, new Gain());
0458     map = (*maps)[onlineAPV_id];
0459   }
0460 
0461   if (map == nullptr) {
0462     (*maps)[onlineAPV_id] = new Gain();
0463     map = (*maps)[onlineAPV_id];
0464   }
0465 
0466   return map;
0467 }
0468 
0469 void SiStripApvGainFromFileBuilder::output_maps(std::vector<Gain*>* maps, const char* basename) const {
0470   for (unsigned int APV = 0; APV < maps->size(); APV++) {
0471     Gain* map = (*maps)[APV];
0472     if (map != nullptr) {
0473       // open output file
0474       std::stringstream name;
0475       name << basename << "_APV" << APV << ".txt";
0476       std::ofstream* ofile = new std::ofstream(name.str(), std::ofstream::trunc);
0477       if (!ofile->is_open())
0478         throw "cannot open output file!";
0479       for (Gain::const_iterator el = map->begin(); el != map->end(); el++) {
0480         (*ofile) << (*el).first << "    " << (*el).second << std::endl;
0481       }
0482       ofile->close();
0483       delete ofile;
0484     }
0485   }
0486 }
0487 
0488 void SiStripApvGainFromFileBuilder::output_summary() const {
0489   std::ofstream* ofile = new std::ofstream("SiStripApvGainSummary.txt", std::ofstream::trunc);
0490   (*ofile) << "  det id  | APV | isConnected | FED |FEDCH|i2cAd|APVON| is_scanned |tickGain|gainInDB|" << std::endl;
0491   (*ofile) << "----------+-----+-------------+-----+-----+-----+-----+------------+--------+--------+" << std::endl;
0492   for (unsigned int s = 0; s < summary_.size(); s++) {
0493     Summary summary = summary_[s];
0494 
0495     std::stringstream line;
0496 
0497     format_summary(line, summary);
0498 
0499     (*ofile) << line.str() << std::endl;
0500   }
0501   ofile->close();
0502   delete ofile;
0503 
0504   ofile = new std::ofstream("SiStripApvGainExceptionSummary.txt", std::ofstream::trunc);
0505   (*ofile) << "  det id  | APV | isConnected | FED |FEDCH|i2cAd|APVON| is_scanned |tickGain|gainInDB|" << std::endl;
0506   (*ofile) << "----------+-----+-------------+-----+-----+-----+-----+------------+--------+--------+" << std::endl;
0507   for (unsigned int s = 0; s < ex_summary_.size(); s++) {
0508     Summary summary = ex_summary_[s];
0509 
0510     std::stringstream line;
0511 
0512     format_summary(line, summary);
0513 
0514     (*ofile) << line.str() << std::endl;
0515   }
0516   ofile->close();
0517   delete ofile;
0518 }
0519 
0520 void SiStripApvGainFromFileBuilder::format_summary(std::stringstream& line, Summary summary) const {
0521   std::string conn = (summary.is_connected) ? "CONNECTED" : "NOT_CONNECTED";
0522   std::string scan = (summary.is_scanned) ? "IN_SCAN" : "NOT_IN_SCAN";
0523 
0524   line << summary.det_id << "  " << std::setw(3) << summary.offlineAPV_id << "  " << std::setw(13) << conn << "   "
0525        << std::setw(3) << summary.FED_id << "   " << std::setw(3) << summary.FED_ch << "   " << std::setw(3)
0526        << summary.i2cAdd << "  " << std::setw(3) << summary.onlineAPV_id << "   " << std::setw(11) << scan << "  "
0527        << std::setw(7) << summary.gain_from_scan << "  " << std::setw(7) << summary.gain_in_db;
0528 }
0529 
0530 bool SiStripApvGainFromFileBuilder::gain_from_maps(uint32_t det_id, int onlineAPV_id, float& gain) {
0531   Gain* map = nullptr;
0532 
0533   // search det_id and APV in the good scan map
0534   map = get_map(&gains_, onlineAPV_id);
0535   if (map != nullptr) {
0536     Gain::const_iterator el = map->find(det_id);
0537     if (el != map->end()) {
0538       gain = el->second;
0539       return true;
0540     }
0541   }
0542 
0543   // search det_id and APV in the zero gain scan map
0544   map = get_map(&negative_gains_, onlineAPV_id);
0545   if (map != nullptr) {
0546     Gain::const_iterator el = map->find(det_id);
0547     if (el != map->end()) {
0548       gain = el->second;
0549       return true;
0550     }
0551   }
0552 
0553   //search det_id and APV in the negative gain scan map
0554   map = get_map(&null_gains_, onlineAPV_id);
0555   if (map != nullptr) {
0556     Gain::const_iterator el = map->find(det_id);
0557     if (el != map->end()) {
0558       gain = el->second;
0559       return true;
0560     }
0561   }
0562 
0563   return false;
0564 }
0565 
0566 void SiStripApvGainFromFileBuilder::gain_from_maps(uint32_t det_id,
0567                                                    uint16_t totalAPVs,
0568                                                    std::vector<std::pair<int, float>>& gain) const {
0569   std::stringstream ex_msg;
0570   ex_msg << "two APVs with the same online id for det id " << det_id
0571          << ". Please check the tick mark file or the read_tickmark routine." << std::endl;
0572 
0573   for (unsigned int i = 0; i < 6; i++) {
0574     int offlineAPV_id = online2offline(i, totalAPVs);
0575     try {
0576       Gain* map = gains_.at(i);
0577       if (map != nullptr) {
0578         Gain::const_iterator el = map->find(det_id);
0579         if (el != map->end()) {
0580           if (gain[offlineAPV_id].second != k_InvalidGain)
0581             throw(ex_msg.str());
0582           gain[offlineAPV_id].second = el->second;
0583         }
0584       }
0585     } catch (const std::out_of_range&) {
0586       // nothing to do, just pass over
0587     }
0588 
0589     try {
0590       Gain* map = negative_gains_.at(i);
0591       if (map != nullptr) {
0592         Gain::const_iterator el = map->find(det_id);
0593         if (el != map->end()) {
0594           if (gain[offlineAPV_id].second != k_InvalidGain)
0595             throw(ex_msg.str());
0596           gain[offlineAPV_id].second = el->second;
0597         }
0598       }
0599     } catch (const std::out_of_range&) {
0600       // nothing to do, just pass over
0601     }
0602 
0603     try {
0604       Gain* map = null_gains_.at(i);
0605       if (map != nullptr) {
0606         Gain::const_iterator el = map->find(det_id);
0607         if (el != map->end()) {
0608           if (gain[offlineAPV_id].second != k_InvalidGain)
0609             throw(ex_msg.str());
0610           gain[offlineAPV_id].second = el->second;
0611         }
0612       }
0613     } catch (const std::out_of_range&) {
0614       // nothing to do, just pass over
0615     }
0616   }
0617 }
0618 
0619 int SiStripApvGainFromFileBuilder::online2offline(uint16_t onlineAPV_id, uint16_t totalAPVs) const {
0620   return (onlineAPV_id >= totalAPVs) ? onlineAPV_id - 2 : onlineAPV_id;
0621 }
0622 
0623 void SiStripApvGainFromFileBuilder::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0624   edm::ParameterSetDescription desc;
0625   desc.setComment("Conditions Builder for SiStripApvGain Objects (G1 gain) from tickmark height file");
0626   desc.add<edm::FileInPath>("tickFile", edm::FileInPath("CondTools/SiStrip/data/tickheight.txt"));
0627   desc.add<double>("gainThreshold", 0.)->setComment("threshold to retain the scan vale");
0628   desc.add<double>("dummyAPVGain", (690. / k_GainNormalizationFactor));  // from TDR
0629   desc.add<bool>("doGainNormalization", false)->setComment("normalize the output gain in DB by 640");
0630   desc.add<bool>("putDummyIntoUncabled", false)->setComment("use default gain for uncabled APVs");
0631   desc.add<bool>("putDummyIntoUnscanned", false)->setComment("use default gain for unscanned APVs");
0632   desc.add<bool>("putDummyIntoOffChannels", false)->setComment("use default gain for APVs reading HV off modules");
0633   desc.add<bool>("putDummyIntoBadChannels", false)->setComment("use default gain for bad APV channels");
0634   desc.add<bool>("outputMaps", false)->setComment("prints ouput maps");
0635   desc.add<bool>("outputSummary", false)->setComment("prints output summary");
0636   descriptions.addWithDefaultLabel(desc);
0637 }
0638 
0639 #include "FWCore/PluginManager/interface/ModuleDef.h"
0640 #include "FWCore/Framework/interface/MakerMacros.h"
0641 DEFINE_FWK_MODULE(SiStripApvGainFromFileBuilder);