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
#include "EventFilter/EcalRawToDigi/interface/DCCFEBlock.h"
#include "EventFilter/EcalRawToDigi/interface/DCCEventBlock.h"
#include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
#include <cstdio>
#include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"

DCCFEBlock::DCCFEBlock(
    DCCDataUnpacker* u, EcalElectronicsMapper* m, DCCEventBlock* e, bool unpack, bool forceToKeepFRdata)
    : DCCDataBlockPrototype(u, m, e, unpack), checkFeId_(false), forceToKeepFRdata_(forceToKeepFRdata) {
  expXtalTSamples_ = mapper_->numbXtalTSamples();
  numbDWInXtalBlock_ = (expXtalTSamples_ - 2) / 4 + 1;
  unfilteredDataBlockLength_ = mapper_->getUnfilteredTowerBlockLength();
  xtalGains_ = new short[expXtalTSamples_];
}

void DCCFEBlock::updateCollectors() {
  invalidBlockLengths_ = unpacker_->invalidBlockLengthsCollection();
  invalidTTIds_ = unpacker_->invalidTTIdsCollection();
  invalidZSXtalIds_ = unpacker_->invalidZSXtalIdsCollection();
}

int DCCFEBlock::unpack(const uint64_t** data, unsigned int* dwToEnd, bool zs, unsigned int expectedTowerID) {
  zs_ = zs;
  datap_ = data;
  data_ = *data;
  dwToEnd_ = dwToEnd;

  const unsigned int activeDCC = mapper_->getActiveSM();

  if ((*dwToEnd_) < 1) {
    if (!DCCDataUnpacker::silentMode_) {
      edm::LogWarning("IncorrectEvent") << "\n Unable to unpack Tower block for event " << event_->l1A() << " in fed "
                                        << activeDCC << "\n The end of event was reached "
                                        << "\n(or, previously, pointers intended to navigate outside of FedBlock "
                                           "(based on block sizes), and were stopped by setting dwToEnd_ to zero)";
      //TODO : add this to a dcc event size collection error?
    }
    return STOP_EVENT_UNPACKING;
  }

  lastStripId_ = 0;
  lastXtalId_ = 0;
  expTowerID_ = expectedTowerID;

  //Point to begin of block
  data_++;

  towerId_ = (*data_) & TOWER_ID_MASK;
  nTSamples_ = (*data_ >> TOWER_NSAMP_B) & TOWER_NSAMP_MASK;
  bx_ = (*data_ >> TOWER_BX_B) & TOWER_BX_MASK;
  l1_ = (*data_ >> TOWER_L1_B) & TOWER_L1_MASK;
  blockLength_ = (*data_ >> TOWER_LENGTH_B) & TOWER_LENGTH_MASK;

  event_->setFESyncNumbers(l1_, bx_, (short)(expTowerID_ - 1));

  //debugging
  //display(cout);

  ////////////////////////////////////////////////////
  // check that expected fe_id==fe_expected is on
  if (checkFeId_ && expTowerID_ != towerId_ &&
      expTowerID_ <= mapper_->getNumChannelsInDcc(activeDCC)) {  // fe_id must be within range foreseen in the FED
    if (!DCCDataUnpacker::silentMode_) {
      edm::LogWarning("IncorrectBlock") << "Expected tower ID is " << expTowerID_ << " while " << towerId_
                                        << " was found"
                                        << " (L1A " << event_->l1A() << " fed " << mapper_->getActiveDCC() << ")\n"
                                        << "  => Skipping to next FE block...";
    }

    fillEcalElectronicsError(invalidTTIds_);

    updateEventPointers();
    return SKIP_BLOCK_UNPACKING;
  }

  //////////////////////////////////////////////////////////
  // check that expected fe_id==fe_expected is off
  else if ((!checkFeId_) && towerId_ > mapper_->getNumChannelsInDcc(
                                           activeDCC)) {  // fe_id must still be within range foreseen in the FED
    if (!DCCDataUnpacker::silentMode_) {
      edm::LogWarning("IncorrectBlock") << "For event " << event_->l1A() << " and fed " << mapper_->getActiveDCC()
                                        << " (there's no check fe_id==dcc_channel)"
                                        << "\n the FE_id found: " << towerId_
                                        << " exceeds max number of FE foreseen in fed"
                                        << "\n => Skipping to next FE block...";
    }

    updateEventPointers();
    return SKIP_BLOCK_UNPACKING;
  }

  // Check synchronization
  if (sync_) {
    const unsigned int dccBx = (event_->bx()) & TCC_BX_MASK;
    const unsigned int dccL1 = (event_->l1A()) & TCC_L1_MASK;
    const unsigned int fov = (event_->fov()) & H_FOV_MASK;

    if (!isSynced(dccBx, bx_, dccL1, l1_, FE_MEM, fov)) {
      if (!DCCDataUnpacker::silentMode_) {
        // TODO: add check for status from Channel Status DB

        edm::LogWarning("IncorrectBlock")
            << "Synchronization error for Tower Block"
            << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << " tower "
            << towerId_ << ")\n"
            << "  dccBx = " << dccBx << " bx_ = " << bx_ << " dccL1 = " << dccL1 << " l1_ = " << l1_ << "\n"
            << "  => Skipping to next tower block";
      }

      //Note : add to error collection ?
      updateEventPointers();
      return SKIP_BLOCK_UNPACKING;
    }
  }

  // check number of samples
  if (nTSamples_ != expXtalTSamples_) {
    if (!DCCDataUnpacker::silentMode_) {
      edm::LogWarning("IncorrectBlock") << "Unable to unpack Tower Block " << towerId_ << " for event L1A "
                                        << event_->l1A() << " in fed " << mapper_->getActiveDCC()
                                        << "\n Number of time samples " << nTSamples_
                                        << " is not the same as expected (" << expXtalTSamples_ << ")"
                                        << "\n => Skipping to next tower block...";
    }
    //Note : add to error collection ?
    updateEventPointers();
    return SKIP_BLOCK_UNPACKING;
  }

  xtalBlockSize_ = numbDWInXtalBlock_ * 8;
  blockSize_ = blockLength_ * 8;

  if ((*dwToEnd_) < blockLength_) {
    if (!DCCDataUnpacker::silentMode_) {
      edm::LogWarning("IncorrectEvent") << "\n Unable to unpack Tower Block " << towerId_ << " for event L1A "
                                        << event_->l1A() << " in fed " << mapper_->getActiveDCC() << "\n Only "
                                        << ((*dwToEnd_) * 8) << " bytes are available while " << blockSize_
                                        << " are needed!"
                                        << "\n => Skipping to next fed block...";
    }
    //TODO : add to error collections
    return STOP_EVENT_UNPACKING;
  }

  if (!zs_ && !forceToKeepFRdata_) {
    if (unfilteredDataBlockLength_ != blockLength_) {
      if (!DCCDataUnpacker::silentMode_) {
        edm::LogWarning("IncorrectEvent")
            << "\n For event L1A " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " and tower " << towerId_
            << "\n Expected block size is " << (unfilteredDataBlockLength_ * 8) << " bytes while " << (blockLength_ * 8)
            << " was found"
            << "\n => Skipping to next fed block...";
      }

      fillEcalElectronicsError(invalidBlockLengths_);

      //Safer approach...  - why pointers do not navigate in this case?
      return STOP_EVENT_UNPACKING;
    }

  } else if (!zs && forceToKeepFRdata_) {
    if (unfilteredDataBlockLength_ != blockLength_) {
      if (!DCCDataUnpacker::silentMode_) {
        edm::LogWarning("IncorrectBlock")
            << "For event L1A " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " and tower " << towerId_
            << "\n Expected block size is " << (unfilteredDataBlockLength_ * 8) << " bytes while " << (blockLength_ * 8)
            << " was found"
            << "\n => Keeps unpacking as the unpacker was forced to keep FR data (by configuration) ...";
      }

      fillEcalElectronicsError(invalidBlockLengths_);
    }

  } else if (blockLength_ > unfilteredDataBlockLength_ || (blockLength_ - 1) < numbDWInXtalBlock_) {
    if (!DCCDataUnpacker::silentMode_) {
      edm::LogWarning("IncorrectEvent") << "\n For event L1A " << event_->l1A() << " and fed "
                                        << mapper_->getActiveDCC() << "\n The tower " << towerId_
                                        << " has a wrong number of bytes : " << (blockLength_ * 8)
                                        << "\n => Skipping to next fed block...";
    }

    fillEcalElectronicsError(invalidBlockLengths_);

    //Safer approach... - why pointers do not navigate in this case?
    return STOP_EVENT_UNPACKING;
  }

  // If the HLT says to skip this tower we skip it...
  if (!event_->getHLTChannel(towerId_)) {
    updateEventPointers();
    return SKIP_BLOCK_UNPACKING;
  }
  /////////////////////////////////////////////////

  unsigned int numbOfXtalBlocks = (blockLength_ - 1) / numbDWInXtalBlock_;

  // get XTAL Data
  unsigned int expStripID(0), expXtalID(0);
  //point to xtal data
  data_++;

  int statusUnpackXtal = 0;

  for (unsigned int numbXtal = 1; numbXtal <= numbOfXtalBlocks && statusUnpackXtal != SKIP_BLOCK_UNPACKING;
       numbXtal++) {
    if (!zs_ && !forceToKeepFRdata_) {
      expStripID = (numbXtal - 1) / 5 + 1;
      expXtalID = numbXtal - (expStripID - 1) * 5;
    }

    statusUnpackXtal = unpackXtalData(expStripID, expXtalID);
    if (statusUnpackXtal == SKIP_BLOCK_UNPACKING) {
      if (!DCCDataUnpacker::silentMode_) {
        edm::LogWarning("IncorrectBlock") << "For event L1A " << event_->l1A() << " and fed " << mapper_->getActiveDCC()
                                          << "\n The tower " << towerId_ << " won't be unpacked further";
      }
    }

  }  // end loop over xtals of given FE

  updateEventPointers();
  return BLOCK_UNPACKED;
}

void DCCFEBlock::display(std::ostream& o) {
  o << "\n Unpacked Info for DCC Tower Block"
    << "\n DW1 ============================="
    << "\n Tower Id " << towerId_ << "\n Numb Samp " << nTSamples_ << "\n Bx " << bx_ << "\n L1 " << l1_
    << "\n blockLength " << blockLength_;
}