Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:30

0001 /****************************************************************************
0002 *
0003 * This is a part of TOTEM offline software.
0004 * Authors:
0005 *   Jan Kašpar (jan.kaspar@gmail.com)
0006 *   Nicola Minafra
0007 *   Laurent Forthomme
0008 *
0009 ****************************************************************************/
0010 
0011 #include "FWCore/Framework/interface/stream/EDProducer.h"
0012 #include "FWCore/Framework/interface/Event.h"
0013 #include "FWCore/Framework/interface/MakerMacros.h"
0014 #include "FWCore/Utilities/interface/InputTag.h"
0015 #include "FWCore/Framework/interface/ESHandle.h"
0016 #include "FWCore/Framework/interface/EventSetup.h"
0017 #include "FWCore/Utilities/interface/ESGetToken.h"
0018 
0019 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0020 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0021 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0022 
0023 #include "DataFormats/CTPPSDigi/interface/TotemRPDigi.h"
0024 #include "DataFormats/CTPPSDigi/interface/TotemVFATStatus.h"
0025 #include "DataFormats/CTPPSDigi/interface/TotemFEDInfo.h"
0026 
0027 #include "CondFormats/DataRecord/interface/TotemReadoutRcd.h"
0028 #include "CondFormats/DataRecord/interface/TotemAnalysisMaskRcd.h"
0029 #include "CondFormats/PPSObjects/interface/TotemDAQMapping.h"
0030 #include "CondFormats/PPSObjects/interface/TotemAnalysisMask.h"
0031 
0032 #include "EventFilter/CTPPSRawToDigi/interface/CTPPSRawToDigiErrorSummary.h"
0033 #include "EventFilter/CTPPSRawToDigi/interface/SimpleVFATFrameCollection.h"
0034 #include "EventFilter/CTPPSRawToDigi/interface/RawDataUnpacker.h"
0035 #include "EventFilter/CTPPSRawToDigi/interface/RawToDigiConverter.h"
0036 
0037 #include "DataFormats/CTPPSDigi/interface/TotemTimingDigi.h"
0038 #include "DataFormats/TotemReco/interface/TotemT2Digi.h"
0039 
0040 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0041 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0042 
0043 #include <string>
0044 
0045 class TotemVFATRawToDigi : public edm::stream::EDProducer<> {
0046 public:
0047   explicit TotemVFATRawToDigi(const edm::ParameterSet &);
0048   ~TotemVFATRawToDigi() override;
0049 
0050   void produce(edm::Event &, const edm::EventSetup &) override;
0051   void endStream() override;
0052   static void fillDescriptions(edm::ConfigurationDescriptions &);
0053 
0054 private:
0055   std::string subSystemName;
0056 
0057   enum { ssUndefined, ssTrackingStrip, ssTimingDiamond, ssTotemTiming, ssTotemT2 } subSystem;
0058 
0059   std::vector<unsigned int> fedIds;
0060 
0061   edm::EDGetTokenT<FEDRawDataCollection> fedDataToken;
0062   edm::ESGetToken<TotemDAQMapping, TotemReadoutRcd> totemMappingToken;
0063   edm::ESGetToken<TotemAnalysisMask, TotemAnalysisMaskRcd> analysisMaskToken;
0064 
0065   pps::RawDataUnpacker rawDataUnpacker;
0066   RawToDigiConverter rawToDigiConverter;
0067   CTPPSRawToDigiErrorSummary errSummary;
0068 
0069   template <typename DigiType>
0070   void run(edm::Event &, const edm::EventSetup &);
0071 };
0072 
0073 using namespace edm;
0074 using namespace std;
0075 
0076 TotemVFATRawToDigi::TotemVFATRawToDigi(const edm::ParameterSet &conf)
0077     : subSystemName(conf.getParameter<string>("subSystem")),
0078       subSystem(ssUndefined),
0079       fedIds(conf.getParameter<vector<unsigned int>>("fedIds")),
0080       rawDataUnpacker(conf.getParameterSet("RawUnpacking")),
0081       rawToDigiConverter(conf.getParameterSet("RawToDigi")),
0082       errSummary("TotemVFATRawToDigi", "[TotemVFATRawToDigi]", false) {
0083   fedDataToken = consumes<FEDRawDataCollection>(conf.getParameter<edm::InputTag>("rawDataTag"));
0084 
0085   // validate chosen subSystem
0086   if (subSystemName == "TrackingStrip")
0087     subSystem = ssTrackingStrip;
0088   else if (subSystemName == "TimingDiamond")
0089     subSystem = ssTimingDiamond;
0090   else if (subSystemName == "TotemTiming")
0091     subSystem = ssTotemTiming;
0092   else if (subSystemName == "TotemT2")
0093     subSystem = ssTotemT2;
0094 
0095   if (subSystem == ssUndefined)
0096     throw cms::Exception("TotemVFATRawToDigi::TotemVFATRawToDigi")
0097         << "Unknown sub-system string " << subSystemName << "." << endl;
0098 
0099   // FED (OptoRx) headers and footers
0100   produces<vector<TotemFEDInfo>>(subSystemName);
0101 
0102   // declare products
0103   if (subSystem == ssTrackingStrip)
0104     produces<DetSetVector<TotemRPDigi>>(subSystemName);
0105 
0106   else if (subSystem == ssTimingDiamond)
0107     produces<DetSetVector<CTPPSDiamondDigi>>(subSystemName);
0108 
0109   else if (subSystem == ssTotemTiming)
0110     produces<DetSetVector<TotemTimingDigi>>(subSystemName);
0111 
0112   else if (subSystem == ssTotemT2)
0113     produces<edmNew::DetSetVector<TotemT2Digi>>(subSystemName);
0114 
0115   // set default IDs
0116   if (fedIds.empty()) {
0117     if (subSystem == ssTrackingStrip) {
0118       for (int id = FEDNumbering::MINTotemRPHorizontalFEDID; id <= FEDNumbering::MAXTotemRPHorizontalFEDID; ++id)
0119         fedIds.push_back(id);
0120 
0121       for (int id = FEDNumbering::MINTotemRPVerticalFEDID; id <= FEDNumbering::MAXTotemRPVerticalFEDID; ++id)
0122         fedIds.push_back(id);
0123     }
0124 
0125     else if (subSystem == ssTimingDiamond) {
0126       for (int id = FEDNumbering::MINCTPPSDiamondFEDID; id <= FEDNumbering::MAXCTPPSDiamondFEDID; ++id)
0127         fedIds.push_back(id);
0128     }
0129 
0130     else if (subSystem == ssTotemTiming) {
0131       for (int id = FEDNumbering::MINTotemRPTimingVerticalFEDID; id <= FEDNumbering::MAXTotemRPTimingVerticalFEDID;
0132            ++id)
0133         fedIds.push_back(id);
0134     }
0135 
0136     else if (subSystem == ssTotemT2) {
0137       for (int id = FEDNumbering::MINTotemT2FEDID; id <= FEDNumbering::MAXTotemT2FEDID; ++id)
0138         fedIds.push_back(id);
0139     }
0140   }
0141   LogDebug("TotemVFATRawToDigi").log([this](auto &log) {
0142     log << "List of FEDs handled by this instance: ";
0143     string sep;
0144     for (const auto &fedId : fedIds)
0145       log << sep << fedId, sep = ", ";
0146   });
0147 
0148   // conversion status
0149   produces<DetSetVector<TotemVFATStatus>>(subSystemName);
0150 
0151   totemMappingToken = esConsumes<TotemDAQMapping, TotemReadoutRcd>(ESInputTag("", subSystemName));
0152   analysisMaskToken = esConsumes<TotemAnalysisMask, TotemAnalysisMaskRcd>(ESInputTag("", subSystemName));
0153 }
0154 
0155 TotemVFATRawToDigi::~TotemVFATRawToDigi() {}
0156 
0157 void TotemVFATRawToDigi::produce(edm::Event &event, const edm::EventSetup &es) {
0158   if (subSystem == ssTrackingStrip)
0159     run<DetSetVector<TotemRPDigi>>(event, es);
0160 
0161   else if (subSystem == ssTimingDiamond)
0162     run<DetSetVector<CTPPSDiamondDigi>>(event, es);
0163 
0164   else if (subSystem == ssTotemTiming)
0165     run<DetSetVector<TotemTimingDigi>>(event, es);
0166 
0167   else if (subSystem == ssTotemT2)
0168     run<edmNew::DetSetVector<TotemT2Digi>>(event, es);
0169 }
0170 
0171 template <typename DigiType>
0172 void TotemVFATRawToDigi::run(edm::Event &event, const edm::EventSetup &es) {
0173   // mapping and analysis mask
0174   ESHandle<TotemDAQMapping> mapping;
0175   ESHandle<TotemAnalysisMask> analysisMaskHandle;
0176   TotemAnalysisMask analysisMask;
0177 
0178   // raw data handle
0179   edm::Handle<FEDRawDataCollection> rawData;
0180   event.getByToken(fedDataToken, rawData);
0181 
0182   // book output products
0183   vector<TotemFEDInfo> fedInfo;
0184   DigiType digi;
0185   DetSetVector<TotemVFATStatus> conversionStatus;
0186 
0187   // raw-data unpacking
0188   bool data_exist = false;
0189   SimpleVFATFrameCollection vfatCollection;
0190   for (const auto &fedId : fedIds) {
0191     const FEDRawData &data = rawData->FEDData(fedId);
0192     if (data.size() > 0) {
0193       rawDataUnpacker.run(fedId, data, fedInfo, vfatCollection);
0194       data_exist = true;
0195     }
0196   }
0197 
0198   // get mapping records and do raw-to-digi conversion only if some data exists
0199   if (data_exist) {
0200     // get DAQ mapping
0201     mapping = es.getHandle(totemMappingToken);
0202     if (!mapping.isValid() || mapping.failedToGet()) {
0203       throw cms::Exception("TotemVFATRawToDigi::TotemVFATRawToDigi")
0204           << "No DAQMapping found for " << subSystemName << "." << endl;
0205     }
0206 
0207     // get analysis mask to mask channels
0208     analysisMaskHandle = es.getHandle(analysisMaskToken);
0209     if (analysisMaskHandle.isValid() && !analysisMaskHandle.failedToGet()) {
0210       analysisMask = *analysisMaskHandle;
0211     } else {
0212       errSummary.add(fmt::format("No AnalysisMask found for {0}", subSystemName), "");
0213       analysisMask = TotemAnalysisMask();
0214     }
0215 
0216     // raw-to-digi conversion
0217     rawToDigiConverter.run(vfatCollection, *mapping, analysisMask, digi, conversionStatus);
0218   }
0219 
0220   // commit products to event
0221   event.put(make_unique<vector<TotemFEDInfo>>(fedInfo), subSystemName);
0222   event.put(make_unique<DigiType>(digi), subSystemName);
0223   event.put(make_unique<DetSetVector<TotemVFATStatus>>(conversionStatus), subSystemName);
0224 }
0225 
0226 void TotemVFATRawToDigi::endStream() {
0227   rawToDigiConverter.printSummaries();
0228   errSummary.printSummary();
0229 }
0230 
0231 void TotemVFATRawToDigi::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0232   // totemVFATRawToDigi
0233   edm::ParameterSetDescription desc;
0234   desc.add<edm::InputTag>("rawDataTag", edm::InputTag(""));
0235   desc.add<std::string>("subSystem", "")->setComment("options: RP");
0236   desc.add<std::vector<unsigned int>>("fedIds", {})
0237       ->setComment(
0238           "IMPORTANT: leave empty to load the default configuration from "
0239           "DataFormats/FEDRawData/interface/FEDNumbering.h");
0240   {
0241     edm::ParameterSetDescription psd0;
0242     psd0.addUntracked<unsigned int>("verbosity", 0);
0243     desc.add<edm::ParameterSetDescription>("RawUnpacking", psd0);
0244   }
0245   {
0246     edm::ParameterSetDescription psd0;
0247     psd0.addUntracked<unsigned int>("verbosity", 0)
0248         ->setComment(
0249             "0-3: 1=one line/event with some corrupted VFAT frame, 2=list all corrupt VFAT frames/event, 3=all "
0250             "problems with every corrupt frame");
0251     psd0.add<unsigned int>("testFootprint", 2)->setComment("0=no test, 1=warn only, 2=warn and skip");
0252     psd0.add<unsigned int>("testCRC", 2);
0253     psd0.add<unsigned int>("testID", 2)->setComment("compare the ID from data and mapping");
0254     psd0.add<unsigned int>("testECMostFrequent", 2)
0255         ->setComment("compare frame EC with the most frequent value in the event");
0256     psd0.add<unsigned int>("testBCMostFrequent", 2);
0257     psd0.addUntracked<unsigned int>("EC_min", 10)
0258         ->setComment("minimal number of frames to search for the most frequent counter value");
0259     psd0.addUntracked<unsigned int>("BC_min", 10);
0260     psd0.addUntracked<double>("EC_fraction", 0.6)
0261         ->setComment(
0262             "the most frequent counter value is accepted provided its relative occupancy is higher than this fraction");
0263     psd0.addUntracked<double>("BC_fraction", 0.6);
0264     psd0.add<bool>("useOlderT2TestFile", false)
0265         ->setComment("treat hwID field as two separate 8-bit fields instead of one 16-bit");
0266     psd0.addUntracked<bool>("printErrorSummary", false)->setComment("per-VFAT error summary at the end of the job");
0267     psd0.addUntracked<bool>("printUnknownFrameSummary", false)
0268         ->setComment("summary of frames found in data, but not in the mapping");
0269     desc.add<edm::ParameterSetDescription>("RawToDigi", psd0);
0270   }
0271   descriptions.add("totemVFATRawToDigi", desc);
0272   // or use the following to generate the label from the module's C++ type
0273   //descriptions.addWithDefaultLabel(desc);
0274 }
0275 
0276 DEFINE_FWK_MODULE(TotemVFATRawToDigi);