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
#include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
#include "EventFilter/EcalRawToDigi/interface/DCCEBEventBlock.h"
#include "EventFilter/EcalRawToDigi/interface/DCCEEEventBlock.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "Geometry/EcalMapping/interface/EcalElectronicsMapping.h"
#include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
#include <set>

std::atomic<bool> DCCDataUnpacker::silentMode_(false);

DCCDataUnpacker::DCCDataUnpacker(EcalElectronicsMapper* mapper,
                                 bool hU,
                                 bool srpU,
                                 bool tccU,
                                 bool feU,
                                 bool memU,
                                 bool syncCheck,
                                 bool feIdCheck,
                                 bool forceToKeepFRdata) {
  electronicsMapper_ = mapper;
  ebEventBlock_ = new DCCEBEventBlock(this, mapper, hU, srpU, tccU, feU, memU, forceToKeepFRdata);
  eeEventBlock_ = new DCCEEEventBlock(this, mapper, hU, srpU, tccU, feU, memU, forceToKeepFRdata);
  if (syncCheck) {
    ebEventBlock_->enableSyncChecks();
    eeEventBlock_->enableSyncChecks();
  }
  if (feIdCheck) {
    ebEventBlock_->enableFeIdChecks();
    eeEventBlock_->enableFeIdChecks();
  }
}

void DCCDataUnpacker::unpack(const uint64_t* buffer, size_t bufferSize, unsigned int smId, unsigned int fedId) {
  //buffer is pointer to binary data
  //See if this fed is on EB or in EE

  if (smId > 9 && smId < 46) {
    currentEvent_ = ebEventBlock_;
    ebEventBlock_->updateCollectors();
    ebEventBlock_->unpack(buffer, bufferSize, fedId);

  } else {
    currentEvent_ = eeEventBlock_;
    eeEventBlock_->updateCollectors();
    eeEventBlock_->unpack(buffer, bufferSize, fedId);
  }
}

DCCDataUnpacker::~DCCDataUnpacker() {
  delete ebEventBlock_;
  delete eeEventBlock_;
}

uint16_t DCCDataUnpacker::getChannelStatus(const DetId& id) const {
  // return code for situation of missing channel record
  // equal to "non responding isolated channel (dead of type other)":
  //   https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideEcalRecoLocalReco#Treatment_of_problematic_channel
  // TODO: think on a better way how to cover this case
  const uint16_t NO_DATA = 11;

  if (chdb_ == nullptr) {
    edm::LogError("IncorrectMapping") << "ECAL channel status database do not initialized";
    return NO_DATA;
  }

  EcalChannelStatus::const_iterator pCh = chdb_->find(id);

  if (pCh != chdb_->end()) {
    return pCh->getStatusCode();
  } else {
    edm::LogError("IncorrectMapping") << "No channel status record found for detit = " << id.rawId();
    return NO_DATA;
  }
}

uint16_t DCCDataUnpacker::getChannelValue(const DetId& id) const { return getChannelStatus(id) & 0x1F; }

uint16_t DCCDataUnpacker::getChannelValue(const int fed, const int ccu, const int strip, const int xtal) const {
  // conversion FED ID [601 - 654] -> DCC ID [1 - 54]
  const int dcc = electronicsMapper_->getSMId(fed);

  // convert (dcc, ccu, strip, xtal) -> DetId
  const EcalElectronicsId eid(dcc, ccu, strip, xtal);
  const DetId id = electronicsMapper_->mapping()->getDetId(eid);

  return getChannelStatus(id) & 0x1F;
}

uint16_t DCCDataUnpacker::getCCUValue(const int fed, const int ccu) const {
  // get list of crystals (DetId) which correspond to given CCU
  // (return empty list for MEM channels [CCU > 68])
  const int dcc = electronicsMapper_->getSMId(fed);
  const std::vector<DetId> xtals =
      (ccu <= 68) ? electronicsMapper_->mapping()->dccTowerConstituents(dcc, ccu) : std::vector<DetId>();

  // collect set of status codes of given CCU
  std::set<uint16_t> set;
  for (size_t i = 0; i < xtals.size(); ++i) {
    const uint16_t val = getChannelValue(xtals[i]);
    set.insert(val);
  }

  // if all crystals in CCU have the same status
  // then this status is treated as CCU status
  if (set.size() == 1)
    return *set.begin();

  // if there are several or no statuses:
  return 0;
}