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

ErrorChecker::ErrorChecker() : ErrorCheckerBase() {}

bool ErrorChecker::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;
  unsigned int channel = (errorWord >> LINK_shift) & LINK_mask;
  unsigned int roc = 1;

  switch (errorType) {
    case (25): {
      CablingPathToDetUnit cablingPath = {unsigned(fedId), channel, 1};
      if (!theCablingTree->findItem(cablingPath)) {
        return false;
      }
      LogDebug("") << "  invalid ROC=25 found (errorType=25)";
      errorsInEvent = true;
      break;
    }
    case (26): {
      //LogDebug("")<<"  gap word found (errorType=26)";
      return false;
    }
    case (27): {
      //LogDebug("")<<"  dummy word found (errorType=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)) {  //exit on the 2nd TO word
        LogDebug("") << "  ...2nd errorType=29 error, skip";
        return false;
      }
      break;
    }
    case (30): {
      LogDebug("") << "  TBM error trailer (errorType=30)";
      int StateMatch_bits = 4;
      int StateMatch_shift = 8;
      uint32_t StateMatch_mask = ~(~uint32_t(0) << StateMatch_bits);
      int StateMatch = (errorWord >> StateMatch_shift) & StateMatch_mask;
      if (StateMatch != 1 && StateMatch != 8) {
        LogDebug("") << " FED error 30 with unexpected State Bits (errorType=30)";
        return false;
      }
      if (StateMatch == 1)
        errorType = 40;  // 1=Overflow -> 40, 8=number of ROCs -> 30
      errorsInEvent = true;
      break;
    }
    case (31): {
      LogDebug("") << "  event number error (errorType=31)";
      errorsInEvent = true;
      break;
    }
    case (37):
    case (38): {
      roc = (errorWord >> ROC_shift) & ROC_mask;
      break;
    }
    default:
      return true;
  };

  if (includeErrors_) {
    // store error
    SiPixelRawDataError error(errorWord, errorType, fedId);
    cms_uint32_t detId = errorDetIdSimple(converter, errorType, channel, roc);
    errors[detId].push_back(error);
  }
  return false;
}

// new, simpler version
cms_uint32_t ErrorChecker::errorDetIdSimple(const SiPixelFrameConverter* converter,
                                            int errorType,
                                            unsigned int channel,
                                            unsigned int roc) const {
  if (!converter) {
    return dummyDetId;
  }

  ElectronicIndex cabling;
  DetectorIndex detIdx;
  cabling.dcol = 0;
  cabling.pxid = 2;
  cabling.roc = roc;
  cabling.link = channel;
  int status = converter->toDetector(cabling, detIdx);
  if (!status) {
    return detIdx.rawId;
  }  // all OK return valid module id

  return dummyDetId;  // failed, return dummy
}

// this function finds the detId for an error word that cannot be processed in word2digi
cms_uint32_t ErrorChecker::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
      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) {
        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  WRONG!
      }
      // 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) {
        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;
}