Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:47:16

0001 // -*- C++ -*-
0002 //
0003 // Package:    HcalDbProducer
0004 // Class:      HcalDbProducer
0005 //
0006 /**\class HcalDbProducer HcalDbProducer.h CalibFormats/HcalDbProducer/interface/HcalDbProducer.h
0007 
0008  Description: <one line class summary>
0009 
0010  Implementation:
0011      <Notes on implementation>
0012 */
0013 //
0014 // Original Author:  Fedor Ratnikov
0015 //         Created:  Tue Aug  9 19:10:10 CDT 2005
0016 //
0017 //
0018 
0019 // system include files
0020 #include <iostream>
0021 #include <fstream>
0022 #include <memory>
0023 
0024 #include "FWCore/Framework/interface/ModuleFactory.h"
0025 #include "FWCore/Framework/interface/DependentRecordImplementation.h"
0026 #include "FWCore/Framework/interface/ESProducer.h"
0027 #include "FWCore/Framework/interface/ESProductHost.h"
0028 #include "FWCore/Framework/interface/ESTransientHandle.h"
0029 #include "FWCore/Utilities/interface/ReusableObjectHolder.h"
0030 #include "FWCore/Utilities/interface/TypeDemangler.h"
0031 
0032 #include "CondFormats/HcalObjects/interface/AllObjects.h"
0033 #include "CondFormats/DataRecord/interface/HcalAllRcds.h"
0034 #include "CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h"
0035 #include "CalibFormats/HcalObjects/interface/HcalDbService.h"
0036 #include "CalibFormats/HcalObjects/interface/HcalDbRecord.h"
0037 
0038 class HcalDbProducer : public edm::ESProducer {
0039 public:
0040   HcalDbProducer(const edm::ParameterSet&);
0041   ~HcalDbProducer() override;
0042 
0043   std::shared_ptr<HcalDbService> produce(const HcalDbRecord&);
0044 
0045 private:
0046   using HostType = edm::ESProductHost<HcalDbService,
0047                                       HcalPedestalsRcd,
0048                                       HcalPedestalWidthsRcd,
0049                                       HcalGainsRcd,
0050                                       HcalGainWidthsRcd,
0051                                       HcalQIEDataRcd,
0052                                       HcalQIETypesRcd,
0053                                       HcalChannelQualityRcd,
0054                                       HcalZSThresholdsRcd,
0055                                       HcalRespCorrsRcd,
0056                                       HcalL1TriggerObjectsRcd,
0057                                       HcalTimeCorrsRcd,
0058                                       HcalLUTCorrsRcd,
0059                                       HcalPFCorrsRcd,
0060                                       HcalLutMetadataRcd,
0061                                       HcalSiPMParametersRcd,
0062                                       HcalTPChannelParametersRcd,
0063                                       HcalMCParamsRcd,
0064                                       HcalRecoParamsRcd,
0065                                       HcalElectronicsMapRcd,
0066                                       HcalFrontEndMapRcd,
0067                                       HcalSiPMCharacteristicsRcd,
0068                                       HcalTPParametersRcd>;
0069 
0070   // Helper functions and class for the tokens and work for HcalDbService
0071   template <typename ProductType>
0072   static void serviceSetData(HostType& host, const ProductType& item, std::false_type) {
0073     host.setData(&item);
0074   }
0075   template <typename ProductType>
0076   static void serviceSetData(HostType& host, const ProductType& item, std::true_type) {
0077     host.setData(&item, true);
0078   }
0079   template <typename ProductType, typename RecordType, const char* LABEL, typename EffectiveType>
0080   class ServiceTokenImpl {
0081   public:
0082     ServiceTokenImpl()
0083         : dumpName_(edm::typeDemangle(typeid(ProductType).name()).substr(4))  // remove leading "Hcal"
0084     {
0085       if constexpr (EffectiveType::value) {
0086         dumpName_ = "Effective" + dumpName_;
0087       }
0088     }
0089     void setConsumes(edm::ESConsumesCollector& cc) { token_ = cc.consumes(edm::ESInputTag{"", LABEL}); }
0090     void setupHcalDbService(HostType& host,
0091                             const RecordType& record,
0092                             const std::vector<std::string>& dumpRequest,
0093                             std::ostream* dumpStream) {
0094       const auto& item = record.get(token_);
0095       serviceSetData(host, item, EffectiveType{});
0096 
0097       if (std::find(dumpRequest.begin(), dumpRequest.end(), dumpName_) != dumpRequest.end()) {
0098         *dumpStream << "New HCAL " << dumpName_ << " set" << std::endl;
0099         HcalDbASCIIIO::dumpObject(*dumpStream, item);
0100       }
0101     }
0102 
0103   private:
0104     edm::ESGetToken<ProductType, RecordType> token_;
0105     std::string dumpName_;
0106   };
0107 
0108   template <typename ProductType, const char* LABEL, typename EffectiveType = std::false_type>
0109   struct ServiceToken {
0110     using Product = ProductType;
0111     static constexpr const char* label = LABEL;
0112     using Effective = EffectiveType;
0113   };
0114 
0115   template <typename RecordType, typename... TokenHolders>
0116   class TokensForServiceHolder {
0117   public:
0118     void setConsumes(edm::ESConsumesCollector& cc) {
0119       std::apply([&cc](auto&&... item) { ((item.setConsumes(cc)), ...); }, tokens_);
0120     }
0121     void setupHcalDbService(HostType& host,
0122                             const HcalDbRecord& record,
0123                             const std::vector<std::string>& dumpRequest,
0124                             std::ostream* dumpStream) {
0125       host.ifRecordChanges<RecordType>(record, [this, &host, &dumpRequest, &dumpStream](auto const& rec) {
0126         std::apply([&host, &rec, &dumpRequest, &dumpStream](
0127                        auto&&... item) { ((item.setupHcalDbService(host, rec, dumpRequest, dumpStream)), ...); },
0128                    tokens_);
0129       });
0130     }
0131 
0132   private:
0133     std::tuple<ServiceTokenImpl<typename TokenHolders::Product,
0134                                 RecordType,
0135                                 TokenHolders::label,
0136                                 typename TokenHolders::Effective>...>
0137         tokens_;
0138   };
0139 
0140   // Helper class and functions for the individual products
0141   template <typename ProductT, typename RecordT>
0142   class TokenAndTopologyHolder {
0143   public:
0144     using Product = ProductT;
0145     using Record = RecordT;
0146 
0147     TokenAndTopologyHolder() = default;
0148 
0149     void setConsumes(edm::ESConsumesCollector&& cc, const edm::ESInputTag& tag) {
0150       token_ = cc.consumes(tag);
0151       topoToken_ = cc.consumes();
0152     }
0153 
0154     const auto& token() const { return token_; }
0155 
0156     const auto& topoToken() const { return topoToken_; }
0157 
0158   private:
0159     edm::ESGetToken<ProductT, RecordT> token_;
0160     edm::ESGetToken<HcalTopology, HcalRecNumberingRecord> topoToken_;
0161   };
0162 
0163   template <typename ProductType, typename RecordType, size_t IND1, size_t IND2>
0164   std::unique_ptr<ProductType> produceWithTopology(RecordType const& record) {
0165     const auto& tokenHolder = std::get<IND2>(std::get<IND1>(tokenHolders_));
0166     auto item = record.getTransientHandle(tokenHolder.token());
0167 
0168     auto productWithTopology = std::make_unique<ProductType>(*item);
0169     const auto& topo = record.get(tokenHolder.topoToken());
0170     productWithTopology->setTopo(&topo);
0171 
0172     return productWithTopology;
0173   }
0174 
0175   template <size_t IND1, size_t IND2>
0176   void setupProduce(const char* label, const edm::ESInputTag& tag) {
0177     auto& holder = std::get<IND2>(std::get<IND1>(tokenHolders_));
0178 
0179     using HolderT = typename std::remove_reference<decltype(holder)>::type;
0180     using ProductT = typename HolderT::Product;
0181     using RecordT = typename HolderT::Record;
0182 
0183     holder.setConsumes(
0184         setWhatProduced(
0185             this, &HcalDbProducer::produceWithTopology<ProductT, RecordT, IND1, IND2>, edm::es::Label(label)),
0186         tag);
0187   }
0188 
0189   template <size_t IND1, size_t... IND2s>
0190   void setupProduceAllImpl(const char* label, const edm::ESInputTag& tag, std::index_sequence<IND2s...>) {
0191     ((setupProduce<IND1, IND2s>(label, tag)), ...);
0192   }
0193 
0194   template <size_t IND1>
0195   void setupProduceAll(const char* label, const edm::ESInputTag& tag) {
0196     setupProduceAllImpl<IND1>(
0197         label, tag, std::make_index_sequence<std::tuple_size_v<std::tuple_element_t<IND1, decltype(tokenHolders_)>>>{});
0198   }
0199 
0200   // ----------member data ---------------------------
0201   edm::ReusableObjectHolder<HostType> holder_;
0202 
0203   // Tokens for the "service" produce function
0204   constexpr static const char kWithTopoEff[] = "withTopoEff";
0205   constexpr static const char kWithTopo[] = "withTopo";
0206   constexpr static const char kEmpty[] = "";
0207   std::tuple<TokensForServiceHolder<HcalPedestalWidthsRcd,
0208                                     ServiceToken<HcalPedestalWidths, kWithTopoEff, std::true_type>,
0209                                     ServiceToken<HcalPedestalWidths, kWithTopo>>,
0210              TokensForServiceHolder<HcalPedestalsRcd,
0211                                     ServiceToken<HcalPedestals, kWithTopoEff, std::true_type>,
0212                                     ServiceToken<HcalPedestals, kWithTopo>>,
0213              TokensForServiceHolder<HcalRecoParamsRcd, ServiceToken<HcalRecoParams, kWithTopo>>,
0214              TokensForServiceHolder<HcalMCParamsRcd, ServiceToken<HcalMCParams, kWithTopo>>,
0215              TokensForServiceHolder<HcalLutMetadataRcd, ServiceToken<HcalLutMetadata, kWithTopo>>,
0216              TokensForServiceHolder<HcalTPParametersRcd, ServiceToken<HcalTPParameters, kEmpty>>,
0217              TokensForServiceHolder<HcalTPChannelParametersRcd, ServiceToken<HcalTPChannelParameters, kWithTopo>>,
0218              TokensForServiceHolder<HcalSiPMCharacteristicsRcd, ServiceToken<HcalSiPMCharacteristics, kEmpty>>,
0219              TokensForServiceHolder<HcalSiPMParametersRcd, ServiceToken<HcalSiPMParameters, kWithTopo>>,
0220              TokensForServiceHolder<HcalFrontEndMapRcd, ServiceToken<HcalFrontEndMap, kEmpty>>,
0221              TokensForServiceHolder<HcalElectronicsMapRcd, ServiceToken<HcalElectronicsMap, kEmpty>>,
0222              TokensForServiceHolder<HcalL1TriggerObjectsRcd, ServiceToken<HcalL1TriggerObjects, kWithTopo>>,
0223              TokensForServiceHolder<HcalZSThresholdsRcd, ServiceToken<HcalZSThresholds, kWithTopo>>,
0224              TokensForServiceHolder<HcalChannelQualityRcd, ServiceToken<HcalChannelQuality, kWithTopo>>,
0225              TokensForServiceHolder<HcalGainWidthsRcd, ServiceToken<HcalGainWidths, kWithTopo>>,
0226              TokensForServiceHolder<HcalQIETypesRcd, ServiceToken<HcalQIETypes, kWithTopo>>,
0227              TokensForServiceHolder<HcalQIEDataRcd, ServiceToken<HcalQIEData, kWithTopo>>,
0228              TokensForServiceHolder<HcalTimeCorrsRcd, ServiceToken<HcalTimeCorrs, kWithTopo>>,
0229              TokensForServiceHolder<HcalPFCorrsRcd, ServiceToken<HcalPFCorrs, kWithTopo>>,
0230              TokensForServiceHolder<HcalLUTCorrsRcd, ServiceToken<HcalLUTCorrs, kWithTopo>>,
0231              TokensForServiceHolder<HcalGainsRcd, ServiceToken<HcalGains, kWithTopo>>,
0232              TokensForServiceHolder<HcalRespCorrsRcd, ServiceToken<HcalRespCorrs, kWithTopo>>>
0233       tokensForService_;
0234 
0235   // Tokens for the produceWithTopology functions
0236   std::tuple<
0237       // First are withTopo
0238       std::tuple<TokenAndTopologyHolder<HcalPedestals, HcalPedestalsRcd>,
0239                  TokenAndTopologyHolder<HcalPedestalWidths, HcalPedestalWidthsRcd>,
0240                  TokenAndTopologyHolder<HcalGains, HcalGainsRcd>,
0241                  TokenAndTopologyHolder<HcalGainWidths, HcalGainWidthsRcd>,
0242                  TokenAndTopologyHolder<HcalQIEData, HcalQIEDataRcd>,
0243                  TokenAndTopologyHolder<HcalQIETypes, HcalQIETypesRcd>,
0244                  TokenAndTopologyHolder<HcalChannelQuality, HcalChannelQualityRcd>,
0245                  TokenAndTopologyHolder<HcalZSThresholds, HcalZSThresholdsRcd>,
0246                  TokenAndTopologyHolder<HcalRespCorrs, HcalRespCorrsRcd>,
0247                  TokenAndTopologyHolder<HcalL1TriggerObjects, HcalL1TriggerObjectsRcd>,
0248                  TokenAndTopologyHolder<HcalTimeCorrs, HcalTimeCorrsRcd>,
0249                  TokenAndTopologyHolder<HcalLUTCorrs, HcalLUTCorrsRcd>,
0250                  TokenAndTopologyHolder<HcalPFCorrs, HcalPFCorrsRcd>,
0251                  TokenAndTopologyHolder<HcalLutMetadata, HcalLutMetadataRcd>,
0252                  TokenAndTopologyHolder<HcalSiPMParameters, HcalSiPMParametersRcd>,
0253                  TokenAndTopologyHolder<HcalTPChannelParameters, HcalTPChannelParametersRcd>,
0254                  TokenAndTopologyHolder<HcalMCParams, HcalMCParamsRcd>,
0255                  TokenAndTopologyHolder<HcalRecoParams, HcalRecoParamsRcd>>,
0256       // Then withTopoEff
0257       std::tuple<TokenAndTopologyHolder<HcalPedestals, HcalPedestalsRcd>,
0258                  TokenAndTopologyHolder<HcalPedestalWidths, HcalPedestalWidthsRcd>>>
0259       tokenHolders_;
0260 
0261   std::vector<std::string> mDumpRequest;
0262   std::ostream* mDumpStream;
0263 };
0264 
0265 HcalDbProducer::HcalDbProducer(const edm::ParameterSet& fConfig) : ESProducer(), mDumpRequest(), mDumpStream(nullptr) {
0266   auto cc = setWhatProduced(this);
0267   std::apply([&cc](auto&&... item) { ((item.setConsumes(cc)), ...); }, tokensForService_);
0268 
0269   // Setup all withTopo produces functions and their consumes
0270   setupProduceAll<0>("withTopo", edm::ESInputTag{});
0271   // Setup all withTopoEff produces functions and their consumes
0272   setupProduceAll<1>("withTopoEff", edm::ESInputTag{"", "effective"});
0273 
0274   mDumpRequest = fConfig.getUntrackedParameter<std::vector<std::string>>("dump", std::vector<std::string>());
0275   if (!mDumpRequest.empty()) {
0276     std::string otputFile = fConfig.getUntrackedParameter<std::string>("file", "");
0277     mDumpStream = otputFile.empty() ? &std::cout : new std::ofstream(otputFile.c_str());
0278   }
0279 }
0280 
0281 HcalDbProducer::~HcalDbProducer() {
0282   if (mDumpStream != &std::cout)
0283     delete mDumpStream;
0284 }
0285 
0286 // ------------ method called to produce the data  ------------
0287 std::shared_ptr<HcalDbService> HcalDbProducer::produce(const HcalDbRecord& record) {
0288   auto host = holder_.makeOrGet([]() { return new HostType; });
0289 
0290   std::apply([this, &host, &record](
0291                  auto&&... item) { ((item.setupHcalDbService(*host, record, mDumpRequest, mDumpStream)), ...); },
0292              tokensForService_);
0293 
0294   return host;
0295 }
0296 
0297 DEFINE_FWK_EVENTSETUP_MODULE(HcalDbProducer);