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
#include "EventFilter/SiPixelRawToDigi/interface/ErrorCheckerPhase0.h"

#include "CondFormats/SiPixelObjects/interface/SiPixelFrameConverter.h"

#include "DataFormats/DetId/interface/DetId.h"
#include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
#include "DataFormats/FEDRawData/interface/FEDHeader.h"
#include "DataFormats/FEDRawData/interface/FEDTrailer.h"

#include "FWCore/MessageLogger/interface/MessageLogger.h"

#include <bitset>
#include <sstream>
#include <iostream>

using namespace std;
using namespace edm;
using namespace sipixelobjects;
using namespace sipixelconstants;

ErrorCheckerPhase0::ErrorCheckerPhase0() : ErrorCheckerBase() {}

bool ErrorCheckerPhase0::checkROC(bool& errorsInEvent,
                                  int fedId,
                                  const SiPixelFrameConverter* converter,
                                  const SiPixelFedCabling* theCablingTree,
                                  Word32& errorWord,
                                  SiPixelFormatterErrors& errors) const {
  int errorType = (errorWord >> ROC_shift) & ERROR_mask;
  if LIKELY (errorType < 25)
    return true;

  switch (errorType) {
    case (25): {
      LogDebug("") << "  invalid ROC=25 found (errorType=25)";
      errorsInEvent = true;
      break;
    }
    case (26): {
      return false;
    }
    case (27): {
      return false;
    }
    case (28): {
      LogDebug("") << "  error fifo nearly full (errorType=28)";
      errorsInEvent = true;
      break;
    }
    case (29): {
      LogDebug("") << "  timeout on a channel (errorType=29)";
      errorsInEvent = true;
      if ((errorWord >> OMIT_ERR_shift) & OMIT_ERR_mask) {
        LogDebug("") << "  ...first errorType=29 error, this gets masked out";
        return false;
      }
      break;
    }
    case (30): {
      LogDebug("") << "  TBM error trailer (errorType=30)";
      errorsInEvent = true;
      break;
    }
    case (31): {
      LogDebug("") << "  event number error (errorType=31)";
      errorsInEvent = true;
      break;
    }
    default:
      return true;
  };

  if (includeErrors_) {
    // check to see if overflow error for type 30, change type to 40 if so
    if (errorType == 30) {
      int StateMach_bits = 4;
      int StateMach_shift = 8;
      uint32_t StateMach_mask = ~(~uint32_t(0) << StateMach_bits);
      int StateMach = (errorWord >> StateMach_shift) & StateMach_mask;
      if (StateMach == 4 || StateMach == 9)
        errorType = 40;
    }

    // store error
    SiPixelRawDataError error(errorWord, errorType, fedId);
    cms_uint32_t detId;
    detId = errorDetId(converter, errorType, errorWord);
    errors[detId].push_back(error);
  }
  return false;
}

// this function finds the detId for an error word that cannot be processed in word2digi
cms_uint32_t ErrorCheckerPhase0::errorDetId(const SiPixelFrameConverter* converter,
                                            int errorType,
                                            const Word32& word) const {
  if (!converter)
    return dummyDetId;

  ElectronicIndex cabling;

  switch (errorType) {
    case 25:
    case 30:
    case 31:
    case 36:
    case 40: {
      // set dummy values for cabling just to get detId from link if in Barrel
      cabling.dcol = 0;
      cabling.pxid = 2;
      cabling.roc = 1;
      cabling.link = (word >> LINK_shift) & LINK_mask;

      DetectorIndex detIdx;
      int status = converter->toDetector(cabling, detIdx);
      if (status)
        break;
      if (DetId(detIdx.rawId).subdetId() == static_cast<int>(PixelSubdetector::PixelBarrel))
        return detIdx.rawId;
      break;
    }
    case 29: {
      int chanNmbr = 0;
      const int DB0_shift = 0;
      const int DB1_shift = DB0_shift + 1;
      const int DB2_shift = DB1_shift + 1;
      const int DB3_shift = DB2_shift + 1;
      const int DB4_shift = DB3_shift + 1;
      const cms_uint32_t DataBit_mask = ~(~cms_uint32_t(0) << 1);

      int CH1 = (word >> DB0_shift) & DataBit_mask;
      int CH2 = (word >> DB1_shift) & DataBit_mask;
      int CH3 = (word >> DB2_shift) & DataBit_mask;
      int CH4 = (word >> DB3_shift) & DataBit_mask;
      int CH5 = (word >> DB4_shift) & DataBit_mask;
      int BLOCK_bits = 3;
      int BLOCK_shift = 8;
      cms_uint32_t BLOCK_mask = ~(~cms_uint32_t(0) << BLOCK_bits);
      int BLOCK = (word >> BLOCK_shift) & BLOCK_mask;
      int localCH = 1 * CH1 + 2 * CH2 + 3 * CH3 + 4 * CH4 + 5 * CH5;
      if (BLOCK % 2 == 0)
        chanNmbr = (BLOCK / 2) * 9 + localCH;
      else
        chanNmbr = ((BLOCK - 1) / 2) * 9 + 4 + localCH;
      if ((chanNmbr < 1) || (chanNmbr > 36))
        break;  // signifies unexpected result

      // set dummy values for cabling just to get detId from link if in Barrel
      cabling.dcol = 0;
      cabling.pxid = 2;
      cabling.roc = 1;
      cabling.link = chanNmbr;
      DetectorIndex detIdx;
      int status = converter->toDetector(cabling, detIdx);
      if (status)
        break;
      if (DetId(detIdx.rawId).subdetId() == static_cast<int>(PixelSubdetector::PixelBarrel))
        return detIdx.rawId;
      break;
    }
    case 37:
    case 38: {
      cabling.dcol = 0;
      cabling.pxid = 2;
      cabling.roc = (word >> ROC_shift) & ROC_mask;
      cabling.link = (word >> LINK_shift) & LINK_mask;

      DetectorIndex detIdx;
      int status = converter->toDetector(cabling, detIdx);
      if (status)
        break;

      return detIdx.rawId;
      break;
    }
    default:
      break;
  };
  return dummyDetId;
}