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
#include "CondFormats/SiStripObjects/interface/SiStripLatency.h"
#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"

#include <algorithm>
#include <iterator>
#include <iostream>
#include <sstream>

bool SiStripLatency::put(const uint32_t detId, const uint16_t apv, const uint16_t latency, const uint16_t mode) {
  if (detId > 536870911) {
    std::stringstream error;
    error << "ERROR: the detId = " << detId
          << " is bigger than the maximum acceptable value = 2^(29) - 1 = " << 536870911 << std::endl;
    error << "Since we are using 29 bits for the detId and 3 bits for the apv value. The maximum tracker detId at the "
             "moment"
          << std::endl;
    error
        << "of the writing of this class was 47017836 as defined in CalibTracker/SiStripCommon/data/SiStripDetInfo.dat."
        << std::endl;
    error << "If the maximum value has changed a revision of this calss is needed, possibly changing the detIdAndApv "
             "value from"
          << std::endl;
    error << "from uint32_t to uint64_t." << std::endl;
    edm::LogError("SiStripLatency::put") << error.str();
    throw cms::Exception("InsertFailure");
  }

  // Store all the values in the vectors
  uint32_t detIdAndApv = (detId << 3) | apv;
  latIt pos = lower_bound(latencies_.begin(), latencies_.end(), detIdAndApv, OrderByDetIdAndApv());

  if (pos != latencies_.end() && pos->detIdAndApv == detIdAndApv) {
    std::cout << "Value already inserted, skipping insertion" << std::endl;
    return false;
  }
  // std::cout << "Filling with: latency = " << latency << ", mode = " << mode << std::endl;
  latencies_.insert(pos, Latency(detIdAndApv, latency, mode));

  return true;
}

void SiStripLatency::compress() {
  latIt lat = latencies_.begin();
  while (lat != latencies_.end()) {
    // If it is not the last and it has the same latency and mode as the next one remove it
    if (((lat + 1) != latencies_.end()) && ((lat + 1)->mode == lat->mode) && ((lat + 1)->latency == lat->latency)) {
      lat = latencies_.erase(lat);
    } else {
      ++lat;
    }
  }
}

uint16_t SiStripLatency::latency(const uint32_t detId, const uint16_t apv) const {
  const latConstIt& pos = position(detId, apv);
  if (pos == latencies_.end()) {
    return 255;
  }
  return pos->latency;
}

uint16_t SiStripLatency::mode(const uint32_t detId, const uint16_t apv) const {
  const latConstIt& pos = position(detId, apv);
  if (pos == latencies_.end()) {
    return 0;
  }
  return pos->mode;
}

std::pair<uint16_t, uint16_t> SiStripLatency::latencyAndMode(const uint32_t detId, const uint16_t apv) const {
  const latConstIt& pos = position(detId, apv);
  if (pos == latencies_.end()) {
    return std::make_pair(255, 0);
  }
  return std::make_pair(pos->latency, pos->mode);
}

uint16_t SiStripLatency::singleLatency() const {
  if (latencies_.empty()) {
    return 255;
  }
  if (latencies_.size() == 1) {
    return latencies_[0].latency;
  }
  int differentLatenciesNum = 0;
  // Count the number of different latencies
  for (latConstIt it = latencies_.begin(); it != latencies_.end() - 1; ++it) {
    if (it->latency != (it + 1)->latency) {
      ++differentLatenciesNum;
    }
  }
  if (differentLatenciesNum == 0) {
    return latencies_[0].latency;
  }
  return 255;
}

uint16_t SiStripLatency::singleMode() const {
  if (latencies_.empty()) {
    return 0;
  }
  if (latencies_.size() == 1) {
    return latencies_[0].mode;
  }
  int differentModesNum = 0;
  // Count the number of different modes
  for (latConstIt it = latencies_.begin(); it != latencies_.end() - 1; ++it) {
    if (it->mode != (it + 1)->mode) {
      ++differentModesNum;
    }
  }
  if (differentModesNum == 0) {
    return latencies_[0].mode;
  }
  return 0;
}

void SiStripLatency::allModes(std::vector<uint16_t>& allModesVector) const {
  for (latConstIt it = latencies_.begin(); it != latencies_.end(); ++it) {
    allModesVector.push_back(it->mode);
  }
  // The Latencies are sorted by DetIdAndApv, we need to sort the modes again and then remove duplicates
  sort(allModesVector.begin(), allModesVector.end());
  allModesVector.erase(unique(allModesVector.begin(), allModesVector.end()), allModesVector.end());
}

int16_t SiStripLatency::singleReadOutMode() const {
  uint16_t mode = singleMode();
  if (mode != 0) {
    if ((mode & READMODEMASK) == READMODEMASK)
      return 1;
    if ((mode & READMODEMASK) == 0)
      return 0;
  } else {
    // If we are here the Tracker is not in single mode. Check if it is in single Read-out mode.
    bool allInPeakMode = true;
    bool allInDecoMode = true;
    std::vector<uint16_t> allModesVector;
    allModes(allModesVector);
    std::vector<uint16_t>::const_iterator it = allModesVector.begin();
    if (allModesVector.size() == 1 && allModesVector[0] == 0)
      allInPeakMode = false;
    else {
      for (; it != allModesVector.end(); ++it) {
        if ((*it) % 2 == 0)
          continue;
        if (((*it) & READMODEMASK) == READMODEMASK)
          allInDecoMode = false;
        if (((*it) & READMODEMASK) == 0)
          allInPeakMode = false;
      }
    }
    if (allInPeakMode)
      return 1;
    if (allInDecoMode)
      return 0;
  }
  return -1;
}

void SiStripLatency::allLatencies(std::vector<uint16_t>& allLatenciesVector) const {
  for (latConstIt it = latencies_.begin(); it != latencies_.end(); ++it) {
    allLatenciesVector.push_back(it->latency);
  }
  // The Latencies are sorted by DetIdAndApv, we need to sort the latencies again and then remove duplicates
  sort(allLatenciesVector.begin(), allLatenciesVector.end());
  allLatenciesVector.erase(unique(allLatenciesVector.begin(), allLatenciesVector.end()), allLatenciesVector.end());
}

std::vector<SiStripLatency::Latency> SiStripLatency::allUniqueLatencyAndModes() {
  std::vector<Latency> latencyCopy(latencies_);
  sort(latencyCopy.begin(), latencyCopy.end(), OrderByLatencyAndMode());
  latencyCopy.erase(unique(latencyCopy.begin(), latencyCopy.end(), SiStripLatency::EqualByLatencyAndMode()),
                    latencyCopy.end());
  return latencyCopy;
}

void SiStripLatency::printSummary(std::stringstream& ss, const TrackerTopology* trackerTopo) const {
  ss << std::endl;
  if (singleReadOutMode() == 1) {
    ss << "SingleReadOut = PEAK" << std::endl;
  } else if (singleReadOutMode() == 0) {
    ss << "SingleReadOut = DECO" << std::endl;
  } else {
    ss << "SingleReadOut = MIXED" << std::endl;
  }
  uint16_t lat = singleLatency();
  if (lat != 255) {
    ss << "All the Tracker has the same latency = " << lat << std::endl;
  } else {
    std::vector<uint16_t> allLatenciesVector;
    allLatencies(allLatenciesVector);
    if (allLatenciesVector.size() > 1) {
      ss << "There is more than one latency value in the Tracker" << std::endl;
    } else {
      ss << "Latency value is " << lat << " that means invalid" << std::endl;
    }
  }
  ss << "Total number of ranges = " << latencies_.size() << std::endl;
  printDebug(ss, trackerTopo);
}

void SiStripLatency::printDebug(std::stringstream& ss, const TrackerTopology* /*trackerTopo*/) const {
  ss << "List of all the latencies and modes for the " << latencies_.size() << " ranges in the object:" << std::endl;
  for (latConstIt it = latencies_.begin(); it != latencies_.end(); ++it) {
    int detId = it->detIdAndApv >> 3;
    int apv = it->detIdAndApv & 7;  // 7 is 0...0111
    ss << "for detId = " << detId << " and apv pair = " << apv << " latency = " << int(it->latency)
       << " and mode = " << int(it->mode) << std::endl;
  }
}

#undef READMODEMASK