CSCALCTHeader

FIFO_MODE

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 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
#ifndef EventFilter_CSCRawToDigi_CSCALCTHeader_h
#define EventFilter_CSCRawToDigi_CSCALCTHeader_h

/** documented in  flags
  http://www.phys.ufl.edu/~madorsky/alctv/alct2000_spec.PDF
*/
#include <bitset>
#include <vector>
#include <iosfwd>
#ifndef LOCAL_UNPACK
#include <atomic>
#endif
#include "DataFormats/CSCDigi/interface/CSCALCTDigi.h"
#include "DataFormats/CSCDigi/interface/CSCALCTStatusDigi.h"
#include "DataFormats/CSCDigi/interface/CSCShowerDigi.h"
#include "EventFilter/CSCRawToDigi/interface/CSCALCTHeader2006.h"
#include "EventFilter/CSCRawToDigi/interface/CSCALCTHeader2007.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Utilities/interface/Exception.h"
#include <boost/dynamic_bitset.hpp>

class CSCALCTHeader {
public:
  explicit CSCALCTHeader(int chamberType);  ///for packing

  explicit CSCALCTHeader(const unsigned short *buf);

  CSCALCTHeader(const CSCALCTStatusDigi &digi);  /// to access data by via status digis

  /// turns on the debug flag for this class
  static void setDebug(bool value) { debug = value; };

  void setEventInformation(const CSCDMBHeader &);  ///for packing
  unsigned short int nLCTChipRead() const;

  std::vector<CSCALCTDigi> ALCTDigis() const;

  ///some accessors here are only applicable to 2006 header
  ///some to both 2006 and 2007

  enum FIFO_MODE { NO_DUMP, FULL_DUMP, LOCAL_DUMP };
  unsigned short int FIFOMode() const { return header2006.fifoMode; }
  unsigned short int NTBins() const {
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        return header2006.nTBins;
      case 2007:
        return header2007.rawBins;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi")
            << "trying to access NTBINs: ALCT firmware version is bad/not defined!";
        return 0;
    }
  }
  unsigned short int BoardID() const { return header2006.boardID; }
  unsigned short int ExtTrig() const { return header2006.extTrig; }
  unsigned short int CSCID() const { return header2006.cscID; }
  unsigned short int BXNCount() const {
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        return header2006.bxnCount;
      case 2007:
        return header2007.bxnCount;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi")
            << "trying to access BXNcount: ALCT firmware version is bad/not defined!";
        return 0;
    }
  }

  void setBXNCount(unsigned int bxn) {
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        header2006.bxnCount = bxn % 0xFFF;
        break;
      case 2007:
        header2007.bxnCount = bxn % 0xFFF;
        break;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi")
            << "trying to set BXNcount: ALCT firmware version is bad/not defined!";
        break;
    }
  }

  unsigned short int L1Acc() const {
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        return header2006.l1Acc;
      case 2007:
        return header2007.l1aCounter;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi")
            << "trying to access L1Acc: ALCT firmware version is bad/not defined!";
        return 0;
    }
  }

  void setL1Acc(unsigned int l1a) {
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        header2006.l1Acc = l1a % 0xF;
        break;
      case 2007:
        header2007.l1aCounter = l1a % 0xFFF;
        break;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi") << "trying to set L1Acc: ALCT firmware version is bad/not defined!";
        break;
    }
  }

  unsigned short int L1AMatch() const { return header2006.l1aMatch; }
  unsigned short int ActiveFEBs() const { return header2006.activeFEBs; }
  unsigned short int Promote1() const { return header2006.promote1; }
  unsigned short int Promote2() const { return header2006.promote2; }
  unsigned short int LCTChipRead() const { return header2006.lctChipRead; }
  unsigned short int alctFirmwareVersion() const { return firmwareVersion; }
  unsigned short int alctFirmwareRevision() const {
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        return 0;
      case 2007:
        return header2007.firmwareVersion;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi")
            << "trying to access ALCT firmware revision bits: ALCT firmware version is bad/not defined!";
        return 0;
    }
  }

  std::vector<CSCShowerDigi> alctShowerDigis() const {
    std::vector<CSCShowerDigi> results;
    results.clear();
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        return results;
      case 2007:
        // if (alctFirmwareRevision() >= 0) // TODO: Need ALCT Run3 firmware revision to properly detect presense of HMT bits in data format
        // {
        if ((!theALCTs.empty()) && (theALCTs.size() == unsigned(header2007.lctBins * 2))) {
          for (unsigned bx = 0; bx < header2007.lctBins; bx++) {
            //CSCID is set to be 0
            //ALCTshower, showerType_= 1, wireNHits and ComparatorNHits are not available in data
            results.push_back(
                CSCShowerDigi(theALCTs[bx * 2].reserved & 0x3, 0, 0, bx, CSCShowerDigi::ShowerType::kALCTShower, 0, 0));
          }
          return results;
        } else
          return results;
        // } else return results;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi")
            << "trying to access ALCT HMT Shower Digis bits: ALCT firmware version is bad/not defined!";
        return results;
    }
  }

  std::vector<unsigned short int> alctHMTs() const {
    std::vector<unsigned short int> results;
    results.clear();
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        return results;
      case 2007:
        // if (alctFirmwareRevision() >= 0) // TODO: Need ALCT Run3 firmware revision to properly detect presense of HMT bits in data format
        // {
        if ((!theALCTs.empty()) && (theALCTs.size() == unsigned(header2007.lctBins * 2))) {
          for (unsigned bx = 0; bx < header2007.lctBins; bx++) {
            results.push_back(theALCTs[bx * 2].reserved & 0x3);
          }
          return results;
        } else
          return results;
        // } else return results;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi")
            << "trying to access ALCT HMT bits: ALCT firmware version is bad/not defined!";
        return results;
    }
  }

  void setDAVForChannel(int wireGroup) {
    if (firmwareVersion == 2006) {
      header2006.setDAV((wireGroup - 1) / 16);
    }
  }

  CSCALCTHeader2007 alctHeader2007() const { return header2007; }
  CSCALCTHeader2006 alctHeader2006() const { return header2006; }

  unsigned short int *data() { return theOriginalBuffer; }

  /// in 16-bit words
  int sizeInWords() {
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        return 8;
      case 2007:
        return sizeInWords2007_;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi") << "SizeInWords(): ALCT firmware version is bad/not defined!";
        return 0;
    }
  }

  bool check() const {
#ifdef LOCAL_UNPACK
    switch (firmwareVersion) {
#else
    switch (firmwareVersion.load()) {
#endif
      case 2006:
        return header2006.flag_0 == 0xC;
      case 2007:
        return header2007.flag1 == 0xDB0A;
      default:
        edm::LogError("CSCALCTHeader|CSCRawToDigi") << "check(): ALCT firmware version is bad/not defined!";
        return false;
    }
  }

  void add(const std::vector<CSCALCTDigi> &digis);
  /// Add Run3 ALCT HMT shower bits
  void addShower(const std::vector<CSCShowerDigi> &digis);

  boost::dynamic_bitset<> pack();

  /// tests that we unpack what we packed
  static void selfTest(int firmware);

private:
  CSCALCTHeader2006 header2006;
  CSCALCTHeader2007 header2007;
  std::vector<CSCALCT> theALCTs;
  CSCALCTs2006 alcts2006;
  CSCVirtexID virtexID;
  CSCConfigurationRegister configRegister;
  std::vector<CSCCollisionMask> collisionMasks;
  std::vector<CSCHotChannelMask> hotChannelMasks;

  //raw data also stored in this buffer
  //maximum header size is 116 words
  unsigned short int theOriginalBuffer[116];

#ifdef LOCAL_UNPACK
  static bool debug;
  static unsigned short int firmwareVersion;
#else
  static std::atomic<bool> debug;
  static std::atomic<unsigned short int> firmwareVersion;
#endif

  ///size of the 2007 header in words
  unsigned short int sizeInWords2007_, bxn0, bxn1;
};

std::ostream &operator<<(std::ostream &os, const CSCALCTHeader &header);

#endif