PixelClusterCount

PixelLumiDQM

Macros

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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
// -*- C++ -*-

// Package:    PixelLumiDQM
// Class:      PixelLumiDQM

/**\class PixelLumiDQM PixelLumiDQM.h
 PixelLumi/PixelLumiDQM/plugins/PixelLumiDQM.h

 Description: DQM Module producing Pixel Cluster Count Luminosity

 Implementation notes:
     1) Filling scheme is put in by 'hand' for now.
        Can obtain it from the cluster count but need higher rate in trigger;
        Best would be to have filling scheme in the DB.
     2) Afterglow correction is put in by hand.
     3) Currently barrel layer 0 is excluded, but a version using all pixel
 layers and disks is also in place. 4) A stable beam flag should be obtained
 from the DB to turn on actual checks. (Pixel Lumi does not make sense outside
 stable beams.) 5) Need a top module to correlate the info from the three
 trigger categories. NB: at present the module only uses the ZeroBias trigger
 providing about 85 Hz.
*/

// Original author:   Amita Raval

#ifndef __PixelLumi_PixelLumiDQM_PixelLumiDQM_h__
#define __PixelLumi_PixelLumiDQM_PixelLumiDQM_h__

#include <fstream>
#include <map>
#include <string>
#include <vector>

#include "DQMServices/Core/interface/DQMOneEDAnalyzer.h"
#include "DataFormats/SiPixelCluster/interface/SiPixelCluster.h"
#include "FWCore/Framework/interface/Frameworkfwd.h"

class ConfigurationDescriptions;
class TrackerGeometry;
class TrackerDigiGeometryRecord;
class PixelLumiDQM : public DQMOneEDAnalyzer<edm::one::WatchLuminosityBlocks> {
public:
  explicit PixelLumiDQM(const edm::ParameterSet &);
  ~PixelLumiDQM() override;
  static constexpr double FREQ_ORBIT = 11245.5;
  static constexpr double SECONDS_PER_LS = double(0x40000) / double(FREQ_ORBIT);

  // Using all pixel clusters:
  static constexpr double XSEC_PIXEL_CLUSTER = 10.08e-24;  // in cm^2
  static constexpr double XSEC_PIXEL_CLUSTER_UNC = 0.17e-24;

  // Excluding the inner barrel layer.
  static constexpr double rXSEC_PIXEL_CLUSTER = 9.4e-24;  // in cm^2
  static constexpr double rXSEC_PIXEL_CLUSTER_UNC = 0.119e-24;
  static constexpr double CM2_TO_NANOBARN = 1.0 / 1.e-33;
  static const unsigned int lastBunchCrossing = 3564;

  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);

private:
  void analyze(const edm::Event &, const edm::EventSetup &) override;
  void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
  void beginLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) override;
  void endLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) override;

  // This is a kludge method to infer the filled bunches from the cluster count;
  // notice that this cannot be used with random triggers.
  // The filling scheme should be acquired from the database once it's there.

  unsigned int calculateBunchMask(MonitorElement *, std::vector<bool> &);
  unsigned int calculateBunchMask(std::vector<float> &, unsigned int, std::vector<bool> &);
  // ---------- Member data ----------

  // Hard-coded numbers of layers and disks...
  static constexpr size_t kNumLayers = 5;
  static constexpr size_t kNumDisks = 12;
  static constexpr size_t kOffsetLayers = 0;
  static constexpr size_t kOffsetDisks = 4;

  class PixelClusterCount {
    // B for barrel, F for forwared, M for minus, P for plus side,
    // O for outer and I for inner. Numbers used for layers.
  public:
    PixelClusterCount()
        : numB(kNumLayers, 0),
          numFM(kNumDisks, 0),
          numFP(kNumDisks, 0),
          dnumB(kNumLayers, 0.0),
          dnumFM(kNumDisks, 0.0),
          dnumFP(kNumDisks, 0.0)

    {}
    void Reset() {
      for (unsigned int i = 0; i < numB.size(); i++) {
        numB[i] = 0;
        dnumB[i] = 0.0;
      }
      for (unsigned int i = 0; i < numFM.size(); i++) {
        numFM[i] = 0;
        numFP[i] = 0;
        dnumFM[i] = 0.0;
        dnumFP[i] = 0.0;
      }
    }
    std::vector<UInt_t> numB;
    std::vector<UInt_t> numFM;
    std::vector<UInt_t> numFP;
    std::vector<double> dnumB;
    std::vector<double> dnumFM;
    std::vector<double> dnumFP;

  private:
  };

  edm::EDGetTokenT<edmNew::DetSetVector<SiPixelCluster>> fPixelClusterLabel;
  edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> tkGeomToken_;

  UInt_t fRunNo;
  UInt_t fEvtNo;
  UInt_t fLSNo;
  UInt_t fBXNo;
  UInt_t fTimestamp;
  UInt_t fNumVtx;
  UInt_t fNumVtxGood;
  UInt_t fNumTrkPerVtx;
  Double_t fVtxX;
  Double_t fVtxY;
  Double_t fVtxZ;
  Double_t fChi2;
  Double_t fNdof;
  std::map<int, PixelClusterCount> fNumPixelClusters;

  bool fIncludeVertexInfo;
  bool fIncludePixelClusterInfo;
  bool fIncludePixelQualCheckHistos;
  int fResetIntervalInLumiSections;

  std::map<std::string, MonitorElement *> fHistContainerThisRun;

  // This is a list of modules to be ignored, either because they were
  // dead or are dead in part of the data-taking period.
  std::vector<uint32_t> fDeadModules;

  // The minimum number of pixels that should live in a cluster in
  // order for the cluster to be counted as a real cluster
  // (as opposed to, e.g., a noise pixel).
  int fMinPixelsPerCluster;

  // The minimum pixel cluster charge for a cluster to be counted.
  double fMinClusterCharge;

  // Use the module label to distinguish the three different streams.

  MonitorElement *fIntActiveCrossingsFromDB;
  MonitorElement *fHistnBClusVsLS[3];
  MonitorElement *fHistnFPClusVsLS[2];
  MonitorElement *fHistnFMClusVsLS[2];
  MonitorElement *fHistBunchCrossings;
  MonitorElement *fHistBunchCrossingsLastLumi;
  MonitorElement *fHistClusterCountByBxLastLumi;
  MonitorElement *fHistClusterCountByBxCumulative;
  MonitorElement *fHistClusByLS;
  MonitorElement *fHistTotalRecordedLumiByLS;
  MonitorElement *fHistRecordedByBxLastLumi;
  MonitorElement *fHistRecordedByBxCumulative;

  std::vector<bool> bunchTriggerMask;
  unsigned int filledAndUnmaskedBunches;
  bool useInnerBarrelLayer;
  unsigned int fFillNumber;
  std::string fLogFileName_;

  std::ofstream logFile_;
};

#endif