APVModeFilter

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
// -*- C++ -*-
//
// Package:    Alignment/CommonAlignment
// Class:      APVModeFilter
//
/**\class APVModeFilter APVModeFilter.cc Alignment/CommonAlignment/plugins/APVModeFilter.cc

 Description: Plugin to filter events based on the APV mode

 Implementation:
     The filter checks the bit configuration used for a given run and selects
     only events according to the configured APV mode.

     General reference:
     https://twiki.cern.ch/twiki/bin/view/CMS/SiStripConditionObjects#SiStripLatency

     Document describing the bit configuration (section 5.5):
     https://cds.cern.ch/record/1069892/files/cer-002725643.pdf

     Summary given here:
     https://hypernews.cern.ch/HyperNews/CMS/get/recoTracking/1590/1/1/1.html

     bit 1: 0 = 3-sample,      1 = 1-sample
     bit 3: 0 = deconvolution, 1 = peak

     if both bits are zero: deco
     if both bits are one: peak
     if 1 is zero and bit 3 is one: multi (not used in actual data taking)

*/
//
// Original Author:  Gregor Mittag
//         Created:  Thu, 03 Dec 2015 16:51:33 GMT
//
//

// system include files
#include <bitset>
#include <array>

// user include files
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/stream/EDFilter.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/Exception.h"
#include "CondFormats/SiStripObjects/interface/SiStripLatency.h"
#include "CondFormats/DataRecord/interface/SiStripCondDataRecords.h"

//
// class declaration
//

class APVModeFilter : public edm::stream::EDFilter<> {
public:
  explicit APVModeFilter(const edm::ParameterSet&);
  ~APVModeFilter() override = default;

  static void fillDescriptions(edm::ConfigurationDescriptions&);

private:
  bool filter(edm::Event&, const edm::EventSetup&) override;
  void beginRun(const edm::Run&, const edm::EventSetup&) override;

  using BitMask = std::bitset<16>;  /// APV mode is encoded in uin16_t

  /// converts configuration parameter into type used for APV mode filtering
  BitMask convertMode(const std::string& mode) const;

  /// converts latency record content into type used for APV mode filtering
  BitMask convertMode(const uint16_t& mode) const;

  // ----------member data ---------------------------

  // esConsumes
  const edm::ESGetToken<SiStripLatency, SiStripLatencyRcd> latencyToken_;

  /// bits of interest for the APV mode
  static constexpr std::array<size_t, 2> bits_ = {{1, 3}};
  static constexpr BitMask deco_ = BitMask(0);   /// deco mode bit mask (0000)
  static constexpr BitMask peak_ = BitMask(10);  /// peak mode bit mask (1010)
  static constexpr BitMask multi_ = BitMask(8);  /// multi mode bit mask (1000)

  const BitMask mode_;      /// APV mode that is filtered
  BitMask modeCurrentRun_;  /// APV mode of the current run
};

//
// static data member definitions
//
constexpr std::array<size_t, 2> APVModeFilter::bits_;
constexpr APVModeFilter::BitMask APVModeFilter::deco_;
constexpr APVModeFilter::BitMask APVModeFilter::peak_;
constexpr APVModeFilter::BitMask APVModeFilter::multi_;

//
// constructors and destructor
//
APVModeFilter::APVModeFilter(const edm::ParameterSet& iConfig)
    : latencyToken_(esConsumes<edm::Transition::BeginRun>()),
      mode_(convertMode(iConfig.getUntrackedParameter<std::string>("apvMode"))) {
  edm::LogInfo("Alignment") << "@SUB=APVModeFilter::APVModeFilter"
                            << "Selecting events with APV mode '"
                            << iConfig.getUntrackedParameter<std::string>("apvMode") << "'.";
}

//
// member functions
//

// ------------ method called on each new Event  ------------
bool APVModeFilter::filter(edm::Event&, const edm::EventSetup&) { return mode_ == modeCurrentRun_; }

// ------------ method called when starting to processes a run  ------------
void APVModeFilter::beginRun(const edm::Run&, const edm::EventSetup& iSetup) {
  const auto& siStripLatency = &iSetup.getData(latencyToken_);
  modeCurrentRun_ = convertMode(siStripLatency->singleMode());
}

APVModeFilter::BitMask APVModeFilter::convertMode(const std::string& mode) const {
  if (mode == "deco") {
    return deco_;
  } else if (mode == "peak") {
    return peak_;
  } else if (mode == "multi") {
    return multi_;
  } else {
    throw cms::Exception("BadConfig") << "Your choice for the APV mode ('" << mode
                                      << "') is invalid.\nValid APV modes: deco, peak, multi" << std::endl;
  }
}

APVModeFilter::BitMask APVModeFilter::convertMode(const uint16_t& mode) const {
  BitMask input(mode);
  BitMask result;
  for (const auto& bit : bits_)
    result.set(bit, input[bit]);
  return result;
}

// ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
void APVModeFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
  edm::ParameterSetDescription desc;
  desc.setComment("Filters events with the APV mode 'apvMode' (deco/peak/multi).");
  desc.addUntracked<std::string>("apvMode", "deco");
  descriptions.add("apvModeFilter", desc);
}

//define this as a plug-in
DEFINE_FWK_MODULE(APVModeFilter);