diff --git a/DataFormats/Phase2TrackerDigi/interface/Phase2ITChip.h b/DataFormats/Phase2TrackerDigi/interface/Phase2ITChip.h new file mode 100644 index 0000000000000..521061aa870a6 --- /dev/null +++ b/DataFormats/Phase2TrackerDigi/interface/Phase2ITChip.h @@ -0,0 +1,32 @@ +#ifndef DataFormats_Phase2TrackerDigi_Phase2ITChip_H +#define DataFormats_Phase2TrackerDigi_Phase2ITChip_H +#include +#include +#include +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITDigiHit.h" + +class Phase2ITChip { + // Quarter cores collected into a chip (only active quarter cores with hits gets collected) + +public: + Phase2ITChip(int rocnum, const std::vector hl); + + unsigned int size(); + int rocnum() const { return rocnum_; } + + std::vector get_organized_QCores(); + std::vector get_chip_code(); + +private: + std::vector hitList_; + int rocnum_; + + std::pair get_QCore_pos(Phase2ITDigiHit hit); + + Phase2ITQCore get_QCore_from_hit(Phase2ITDigiHit pixel); + std::vector rem_duplicates(std::vector qcores); + std::vector organize_QCores(std::vector qcores); +}; + +#endif // DataFormats_Phase2TrackerDigi_Phase2ITChip_H diff --git a/DataFormats/Phase2TrackerDigi/interface/Phase2ITChipBitStream.h b/DataFormats/Phase2TrackerDigi/interface/Phase2ITChipBitStream.h new file mode 100644 index 0000000000000..09fb37dce0267 --- /dev/null +++ b/DataFormats/Phase2TrackerDigi/interface/Phase2ITChipBitStream.h @@ -0,0 +1,25 @@ +#ifndef DataFormats_Phase2TrackerDigi_Phase2ITChipBitStream_H +#define DataFormats_Phase2TrackerDigi_Phase2ITChipBitStream_H +#include + +class Phase2ITChipBitStream { + // Encoded bit stream output from chips +public: + Phase2ITChipBitStream(int rocid, const std::vector& bitstream) { + rocid_ = rocid; + bitstream_ = bitstream; + } + + Phase2ITChipBitStream() { rocid_ = -1; } + + int get_rocid() const { return rocid_; } + + const std::vector& get_bitstream() const { return bitstream_; } + + const bool operator<(const Phase2ITChipBitStream& other) { return rocid_ < other.rocid_; } + +private: + int rocid_; // Chip index + std::vector bitstream_; // Chip bit stream output +}; +#endif // DataFormats_Phase2TrackerDigi_Phase2ITChipBitStream_H diff --git a/DataFormats/Phase2TrackerDigi/interface/Phase2ITDigiHit.h b/DataFormats/Phase2TrackerDigi/interface/Phase2ITDigiHit.h new file mode 100644 index 0000000000000..cc6d41b6ab0ce --- /dev/null +++ b/DataFormats/Phase2TrackerDigi/interface/Phase2ITDigiHit.h @@ -0,0 +1,21 @@ +#ifndef DataFormats_Phase2TrackerDigi_Phase2ITDigiHit_H +#define DataFormats_Phase2TrackerDigi_Phase2ITDigiHit_H + +class Phase2ITDigiHit { +private: + int row_; // Hit position row + int col_; // Hit position column + int adc_; // Hit position adc + +public: + Phase2ITDigiHit(int row_num, int col_num, int adc_num); + + void set_row(int row) { row_ = row; } + void set_col(int col) { col_ = col; } + + int row() const { return row_; } + int col() const { return col_; } + int adc() const { return adc_; } +}; + +#endif // DataFormats_Phase2TrackerDigi_Phase2ITDigiHit_H diff --git a/DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.h b/DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.h new file mode 100644 index 0000000000000..bdb829ac406db --- /dev/null +++ b/DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.h @@ -0,0 +1,61 @@ +#ifndef DataFormats_Phase2TrackerDigi_Phase2ITQCore_H +#define DataFormats_Phase2TrackerDigi_Phase2ITQCore_H +#include + +class Phase2ITQCore { + // Collects hits and creates a quarter core (16 pixel positions) + +public: + Phase2ITQCore(int rocid, + int ccol_in, + int qcrow_in, + bool isneighbour_in, + bool islast_in, + const std::vector& adcs_in, + const std::vector& hits_in); + + Phase2ITQCore() { + rocid_ = -1; + islast_ = false; + isneighbour_ = false; + ccol_ = -1; + qcrow_ = -1; + } + + void setIsLast(bool islast) { islast_ = islast; } + bool islast() const { return islast_; } + + void setIsNeighbour(bool isneighbour) { isneighbour_ = isneighbour; } + + int rocid() const { return rocid_; } + int get_col() const { return ccol_; } + int get_row() const { return qcrow_; } + + std::vector getHitmap(); + std::vector getADCs(); + std::vector encodeQCore(bool is_new_col); + + const bool operator<(const Phase2ITQCore& other) { + if (ccol_ == other.ccol_) { + return (ccol_ < other.ccol_); + } else { + return (qcrow_ < other.qcrow_); + } + } + +private: + std::vector adcs_; // Full array of adc values in a quarter core + std::vector hits_; // Full array of hit occurrences + bool islast_; // RD53 chip encoding bits + bool isneighbour_; // RD53 chip encoding bits + int rocid_; // Chip index number + int ccol_; // QCore position column + int qcrow_; // QCore position row + + std::vector toRocCoordinates(std::vector& hitmap); + std::vector intToBinary(int num, int length); + bool containsHit(std::vector& hitmap); + std::vector getHitmapCode(std::vector hitmap); +}; + +#endif // DataFormats_Phase2TrackerDigi_Phase2ITQCore_H diff --git a/DataFormats/Phase2TrackerDigi/src/Phase2ITChip.cc b/DataFormats/Phase2TrackerDigi/src/Phase2ITChip.cc new file mode 100644 index 0000000000000..14fbcd79c84c2 --- /dev/null +++ b/DataFormats/Phase2TrackerDigi/src/Phase2ITChip.cc @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITChip.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITDigiHit.h" + +Phase2ITChip::Phase2ITChip(int rocnum, const std::vector hl) { + hitList_ = hl; + rocnum_ = rocnum; +} + +unsigned int Phase2ITChip::size() { return hitList_.size(); } + +//Returns the position (row,col) of the 4x4 QCores that contains a hit +std::pair Phase2ITChip::get_QCore_pos(Phase2ITDigiHit hit) { + int row = hit.row() / 4; + int col = hit.col() / 4; + return {row, col}; +} + +//Takes a hit and returns the 4x4 QCore that contains it +Phase2ITQCore Phase2ITChip::get_QCore_from_hit(Phase2ITDigiHit pixel) { + std::vector adcs(16, 0), hits(16, 0); + std::pair pos = get_QCore_pos(pixel); + + for (const auto& hit : hitList_) { + if (get_QCore_pos(hit) == pos) { + int i = (4 * (hit.row() % 4) + (hit.col() % 4) + 8) % 16; + adcs[i] = hit.adc(); + hits[i] = 1; + } + } + + Phase2ITQCore qcore(0, pos.second, pos.first, false, false, adcs, hits); + return qcore; +} + +//Removes duplicated Phase2ITQCores +std::vector Phase2ITChip::rem_duplicates(std::vector qcores) { + std::vector list = {}; + + size_t i = 0; + while (i < qcores.size()) { + for (size_t j = i + 1; j < qcores.size();) { + if (qcores[j].get_col() == qcores[i].get_col() && qcores[j].get_row() == qcores[i].get_row()) { + qcores.erase(qcores.begin() + j); + } else { + ++j; + } + } + list.push_back(qcores[i]); + ++i; + } + + return list; +} + +//Returns a list of the qcores with hits arranged by increasing column and then row numbers +std::vector Phase2ITChip::organize_QCores(std::vector qcores) { + std::vector organized_list = {}; + while (!qcores.empty()) { + int min = 0; + + for (size_t i = 1; i < qcores.size(); i++) { + if (qcores[i].get_col() < qcores[min].get_col()) { + min = i; + } else if (qcores[i].get_col() == qcores[min].get_col() && qcores[i].get_row() < qcores[min].get_row()) { + min = i; + } + } + + organized_list.push_back(qcores[min]); + qcores.erase(qcores.begin() + min); + } + + return organized_list; +} + +//Takes in an oranized list of Phase2ITQCores and sets the islast and isneighbor properties of those qcores +std::vector link_QCores(std::vector qcores) { + for (size_t i = 1; i < qcores.size(); i++) { + if (qcores[i].get_row() == qcores[i - 1].get_row()) { + qcores[i].setIsNeighbour(true); + } + } + + //.size() is unsigned. If size is zero size()-1 is a huge number hence this needs to be protected + if (!qcores.empty()) { + for (size_t i = 0; i < qcores.size() - 1; i++) { + if (qcores[i].get_col() != qcores[i + 1].get_col()) { + qcores[i].setIsLast(true); + } + } + qcores[qcores.size() - 1].setIsLast(true); + } + + return qcores; +} + +//Takes in a list of hits and organizes them into the 4x4 QCores that contains them +std::vector Phase2ITChip::get_organized_QCores() { + std::vector qcores = {}; + + qcores.reserve(hitList_.size()); + for (const auto& hit : hitList_) { + qcores.push_back(get_QCore_from_hit(hit)); + } + + return (link_QCores(organize_QCores(rem_duplicates(qcores)))); +} + +//Returns the encoding of the readout chip +std::vector Phase2ITChip::get_chip_code() { + std::vector code = {}; + + if (!hitList_.empty()) { + std::vector qcores = get_organized_QCores(); + bool is_new_col = true; + + for (auto& qcore : qcores) { + std::vector qcore_code = qcore.encodeQCore(is_new_col); + code.insert(code.end(), qcore_code.begin(), qcore_code.end()); + + is_new_col = qcore.islast(); + } + } + + return code; +} diff --git a/DataFormats/Phase2TrackerDigi/src/Phase2ITDigiHit.cc b/DataFormats/Phase2TrackerDigi/src/Phase2ITDigiHit.cc new file mode 100644 index 0000000000000..6c4497ff9350f --- /dev/null +++ b/DataFormats/Phase2TrackerDigi/src/Phase2ITDigiHit.cc @@ -0,0 +1,8 @@ +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITDigiHit.h" + +// Describes the 4x4=16 bit hitmap with its row and column numbers and the ADC values +Phase2ITDigiHit::Phase2ITDigiHit(int row_num, int col_num, int adc_num) { + row_ = row_num; + col_ = col_num; + adc_ = adc_num; +} diff --git a/DataFormats/Phase2TrackerDigi/src/Phase2ITQCore.cc b/DataFormats/Phase2TrackerDigi/src/Phase2ITQCore.cc new file mode 100644 index 0000000000000..2a6a9cdd21fa2 --- /dev/null +++ b/DataFormats/Phase2TrackerDigi/src/Phase2ITQCore.cc @@ -0,0 +1,164 @@ +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.h" +#include +#include +#include + +//4x4 region of hits in sensor coordinates +Phase2ITQCore::Phase2ITQCore(int rocid, + int ccol_in, + int qcrow_in, + bool isneighbour_in, + bool islast_in, + const std::vector& adcs_in, + const std::vector& hits_in) { + rocid_ = rocid; + ccol_ = ccol_in; + qcrow_ = qcrow_in; + isneighbour_ = isneighbour_in; + islast_ = islast_in; + adcs_ = adcs_in; + hits_ = hits_in; +} + +//Takes a hitmap in sensor coordinates in 4x4 and converts it to readout chip coordinates with 2x8 +std::vector Phase2ITQCore::toRocCoordinates(std::vector& hitmap) { + std::vector ROC_hitmap(16, false); + + for (size_t i = 0; i < hitmap.size(); i++) { + int row = i / 4; + int col = i % 4; + int new_row; + int new_col; + + if (row % 2 == 0) { + new_row = row / 2; + new_col = 2 * col; + } else { + new_row = row / 2; + new_col = 2 * col + 1; + } + + int new_index = 8 * new_row + new_col; + ROC_hitmap[new_index] = hitmap[i]; + } + + return ROC_hitmap; +} + +//Returns the hitmap for the Phase2ITQCore in 4x4 sensor coordinates +std::vector Phase2ITQCore::getHitmap() { + std::vector hitmap = {}; + + hitmap.reserve(hits_.size()); + for (auto hit : hits_) { + hitmap.push_back(hit > 0); + } + + return (toRocCoordinates(hitmap)); +} + +std::vector Phase2ITQCore::getADCs() { + std::vector adcmap = {}; + + adcmap.reserve(adcs_.size()); + for (auto adc : adcs_) { + adcmap.push_back(adc); + } + + return adcmap; +} + +//Converts an integer into a binary, and formats it with the given length +std::vector Phase2ITQCore::intToBinary(int num, int length) { + std::vector bi_num(length, false); + + for (int i = 0; i < length; ++i) { + // Extract the (length - 1 - i)th bit from num + bi_num[i] = (num >> (length - 1 - i)) & 1; + } + + return bi_num; +} + +//Takes a hitmap and returns true if it contains any hits +bool Phase2ITQCore::containsHit(std::vector& hitmap) { + bool foundHit = false; + for (size_t i = 0; i < hitmap.size(); i++) { + if (hitmap[i]) { + foundHit = true; + break; + } + } + + return foundHit; +} + +//Returns the Huffman encoded hitmap, created iteratively within this function +std::vector Phase2ITQCore::getHitmapCode(std::vector hitmap) { + std::vector code = {}; + // If hitmap is a single bit, there is no need to further split the bits + if (hitmap.size() == 1) { + return code; + } + + std::vector left_hitmap = std::vector(hitmap.begin(), hitmap.begin() + hitmap.size() / 2); + std::vector right_hitmap = std::vector(hitmap.begin() + hitmap.size() / 2, hitmap.end()); + + bool hit_left = containsHit(left_hitmap); + bool hit_right = containsHit(right_hitmap); + + if (hit_left && hit_right) { + code.push_back(true); + code.push_back(true); + + std::vector left_code = getHitmapCode(left_hitmap); + std::vector right_code = getHitmapCode(right_hitmap); + + code.insert(code.end(), left_code.begin(), left_code.end()); + code.insert(code.end(), right_code.begin(), right_code.end()); + + } else if (hit_right) { + //Huffman encoding compresses 01 into 0 + code.push_back(false); + + std::vector right_code = getHitmapCode(right_hitmap); + code.insert(code.end(), right_code.begin(), right_code.end()); + + } else if (hit_left) { + code.push_back(true); + code.push_back(false); + + std::vector left_code = getHitmapCode(left_hitmap); + code.insert(code.end(), left_code.begin(), left_code.end()); + } + + return code; +} + +//Returns the bit code associated with the Phase2ITQCore +std::vector Phase2ITQCore::encodeQCore(bool is_new_col) { + std::vector code = {}; + + if (is_new_col) { + std::vector col_code = intToBinary(ccol_, 6); + code.insert(code.end(), col_code.begin(), col_code.end()); + } + + code.push_back(islast_); + code.push_back(isneighbour_); + + if (!isneighbour_) { + std::vector row_code = intToBinary(qcrow_, 8); + code.insert(code.end(), row_code.begin(), row_code.end()); + } + + std::vector hitmap_code = getHitmapCode(getHitmap()); + code.insert(code.end(), hitmap_code.begin(), hitmap_code.end()); + + for (auto adc : adcs_) { + std::vector adc_code = intToBinary(adc, 4); + code.insert(code.end(), adc_code.begin(), adc_code.end()); + } + + return code; +} diff --git a/DataFormats/Phase2TrackerDigi/src/classes.h b/DataFormats/Phase2TrackerDigi/src/classes.h index 7f6d6c995a67d..37bf4d4087960 100644 --- a/DataFormats/Phase2TrackerDigi/src/classes.h +++ b/DataFormats/Phase2TrackerDigi/src/classes.h @@ -2,6 +2,8 @@ #define PHASE2TRACKERDIGI_CLASSES_H #include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITChipBitStream.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.h" #include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/Common/interface/DetSetVector.h" #include "DataFormats/Common/interface/DetSetVectorNew.h" diff --git a/DataFormats/Phase2TrackerDigi/src/classes_def.xml b/DataFormats/Phase2TrackerDigi/src/classes_def.xml index 1738169b5f698..16e654356cc74 100644 --- a/DataFormats/Phase2TrackerDigi/src/classes_def.xml +++ b/DataFormats/Phase2TrackerDigi/src/classes_def.xml @@ -5,12 +5,20 @@ + + + + + + + + diff --git a/EventFilter/Phase2PixelRawToDigi/BuildFile.xml b/EventFilter/Phase2PixelRawToDigi/BuildFile.xml new file mode 100644 index 0000000000000..1b3cfd15f9375 --- /dev/null +++ b/EventFilter/Phase2PixelRawToDigi/BuildFile.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/EventFilter/Phase2PixelRawToDigi/plugins/BuildFile.xml b/EventFilter/Phase2PixelRawToDigi/plugins/BuildFile.xml new file mode 100644 index 0000000000000..8583f6fc74feb --- /dev/null +++ b/EventFilter/Phase2PixelRawToDigi/plugins/BuildFile.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/EventFilter/Phase2PixelRawToDigi/plugins/Phase2ITQCoreProducer.cc b/EventFilter/Phase2PixelRawToDigi/plugins/Phase2ITQCoreProducer.cc new file mode 100644 index 0000000000000..8692f5e56ea0c --- /dev/null +++ b/EventFilter/Phase2PixelRawToDigi/plugins/Phase2ITQCoreProducer.cc @@ -0,0 +1,207 @@ +// -*- C++ -*- +// Package: EventFilter/Phase2PixelRawToDigi +// Class: Phase2ITQCoreProducer +// Description: Make Phase2ITQCore objects for digis +// Maintainer: Si Hyun Jeon, shjeon@cern.ch +// Original Author: Rohan Misra +// Created: Thu, 30 Sep 2021 02:04:06 GMT +// + +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/transform.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "DataFormats/Math/interface/Point3D.h" +#include "DataFormats/Common/interface/DetSetVector.h" +#include "DataFormats/DetId/interface/DetId.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITDigiHit.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITChip.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2ITChipBitStream.h" +#include "DataFormats/SiPixelCluster/interface/SiPixelCluster.h" +#include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h" +#include "DataFormats/SiPixelDigi/interface/PixelDigi.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" + +class Phase2ITQCoreProducer : public edm::stream::EDProducer<> { +public: + Phase2ITQCoreProducer(const edm::ParameterSet&); + ~Phase2ITQCoreProducer() override = default; + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + + const edm::InputTag src_; + const edm::EDGetTokenT> pixelDigi_token_; + const edm::ESGetToken tTopoToken_; + typedef math::XYZPointD Point; + typedef std::vector PointCollection; +}; + +Phase2ITQCoreProducer::Phase2ITQCoreProducer(const edm::ParameterSet& iConfig) + : src_(iConfig.getParameter("src")), + pixelDigi_token_(consumes(iConfig.getParameter("siPixelDigi"))), + tTopoToken_(esConsumes()) { + produces>(); + produces>(); +} + +namespace { + // Dimension for 2 chips module = 672 X 434 = 672 X (216 + 1 + 216 + 1) + // Dimension for 4 chips module = 1354 X 434 = (672 + 5 + 672 + 5) X (216 + 1 + 216 + 1) + // Spacing 1 in column and 5 in row is introduced for each chip in between + // if neighboring chip exists + constexpr int kQCoresInChipRow = (672); + constexpr int kQCoresInChipColumn = (216); + constexpr int kQCoresInChipRowGap = (5); + constexpr int kQCoresInChipColumnGap = (10); +} // namespace + +void updateHitCoordinatesForLargePixels(Phase2ITDigiHit& hit) { + /* + In-place modification of Hit coordinates to take into account large pixels + Hits corresponding to large pixels are remapped so they lie on the boundary of the chip + Note that this operation can produce multiple hits with the same row/column coordinates + Duplicates get removed later on + */ + + // Current values before remapping + int row = hit.row(); + int col = hit.col(); + + // Values after remapping + int updated_row = 0; + int updated_col = 0; + + // Remapping of the row coordinate + if (row < kQCoresInChipRow) { + updated_row = row; + } else if (row < (kQCoresInChipRow + kQCoresInChipRowGap)) { + updated_row = kQCoresInChipRow - 1; + } // This will be ignored for 2 chips module + else if (row < (kQCoresInChipRow + 2 * kQCoresInChipRowGap)) { + updated_row = kQCoresInChipRow; + } else { + updated_row = (hit.row() - 2 * kQCoresInChipRowGap); + } + + // Remapping of the column coordinate + if (col < kQCoresInChipColumn) { + updated_col = col; + } else if (col < kQCoresInChipColumn + kQCoresInChipColumnGap) { + updated_col = kQCoresInChipColumn - kQCoresInChipColumnGap; + } else if (col < (kQCoresInChipColumn + 2 * kQCoresInChipColumn)) { + updated_col = kQCoresInChipColumn; + } else { + updated_col = (hit.col() - 2 * kQCoresInChipColumnGap); + } + + hit.set_row(updated_row); + hit.set_col(updated_col); +} + +void adjustEdges(std::vector hitList) { + /* + In-place modification of Hit coordinates to take into account large pixels + */ + std::for_each(hitList.begin(), hitList.end(), &updateHitCoordinatesForLargePixels); +} + +std::vector splitByChip(const std::vector& hitList) { + // Split the hit list by read out chip + std::array, 4> hits_per_chip; + for (auto hit : hitList) { + int chip_index = (hit.col() < kQCoresInChipColumn) ? 0 : 1; + if (hit.row() >= kQCoresInChipRow) { + chip_index += 2; + } + hits_per_chip[chip_index].push_back(hit); + } + + // Generate Phase2ITChip objects from the hit lists + std::vector chips; + chips.reserve(4); + for (int chip_index = 0; chip_index < 4; chip_index++) { + chips.push_back(Phase2ITChip(chip_index, hits_per_chip[chip_index])); + } + + return chips; +} + +std::vector processHits(std::vector hitList) { + adjustEdges(hitList); + std::vector chips = splitByChip(hitList); + + return chips; +} + +// ------------ method called to produce the data ------------ +void Phase2ITQCoreProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + using namespace std; + + unique_ptr> aQCoreVector = make_unique>(); + unique_ptr> aBitStreamVector = + make_unique>(); + + auto const& tTopo = iSetup.getData(tTopoToken_); + + auto pixelDigiHandle = iEvent.getHandle(pixelDigi_token_); + const edm::DetSetVector& pixelDigi = *pixelDigiHandle; + for (const auto& theDigis : pixelDigi) { + DetId tkId = theDigis.id; + std::vector hitlist; + std::vector id; + + if (tkId.subdetId() == PixelSubdetector::PixelBarrel) { + int layer_num = tTopo.pxbLayer(tkId.rawId()); + int ladder_num = tTopo.pxbLadder(tkId.rawId()); + int module_num = tTopo.pxbModule(tkId.rawId()); + id = {tkId.subdetId(), layer_num, ladder_num, module_num}; + } else if (tkId.subdetId() == PixelSubdetector::PixelEndcap) { + int module_num = tTopo.pxfModule(tkId()); + int disk_num = tTopo.pxfDisk(tkId()); + int blade_num = tTopo.pxfBlade(tkId()); + int panel_num = tTopo.pxfPanel(tkId()); + int side_num = tTopo.pxfSide(tkId()); + id = {tkId.subdetId(), module_num, disk_num, blade_num, panel_num, side_num}; + } + + for (const auto& digi : theDigis) { + hitlist.emplace_back(digi.row(), digi.column(), digi.adc()); + } + + std::vector chips = processHits(std::move(hitlist)); + + DetSet DetSetQCores(tkId); + DetSet DetSetBitStream(tkId); + + for (size_t i = 0; i < chips.size(); i++) { + Phase2ITChip chip = chips[i]; + std::vector qcores = chip.get_organized_QCores(); + for (auto& qcore : qcores) { + DetSetQCores.push_back(qcore); + } + + Phase2ITChipBitStream aChipBitStream(i, chip.get_chip_code()); + DetSetBitStream.push_back(aChipBitStream); + } + + aBitStreamVector->insert(DetSetBitStream); + aQCoreVector->insert(DetSetQCores); + } + + iEvent.put(std::move(aQCoreVector)); + iEvent.put(std::move(aBitStreamVector)); +} + +DEFINE_FWK_MODULE(Phase2ITQCoreProducer); diff --git a/EventFilter/Phase2PixelRawToDigi/test/Phase2ITDigiToRaw_cfg.py b/EventFilter/Phase2PixelRawToDigi/test/Phase2ITDigiToRaw_cfg.py new file mode 100644 index 0000000000000..618b30fb9416b --- /dev/null +++ b/EventFilter/Phase2PixelRawToDigi/test/Phase2ITDigiToRaw_cfg.py @@ -0,0 +1,95 @@ +import FWCore.ParameterSet.Config as cms + +from Configuration.Eras.Era_Phase2C17I13M9_cff import Phase2C17I13M9 +process = cms.Process('USER',Phase2C17I13M9) + +# import of standard configurations +process.load('Configuration.StandardSequences.Services_cff') +process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') +process.load('FWCore.MessageService.MessageLogger_cfi') +process.load('Configuration.EventContent.EventContent_cff') +process.load('SimGeneral.MixingModule.mixNoPU_cfi') +#process.load('SimGeneral.MixingModule.mix_POISSON_average_cfi') +process.load('Configuration.Geometry.GeometryExtended2026D91Reco_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.StandardSequences.Digi_cff') +process.load('Configuration.StandardSequences.SimL1Emulator_cff') +process.load('Configuration.StandardSequences.L1TrackTrigger_cff') +process.load('Configuration.StandardSequences.DigiToRaw_cff') +process.load('HLTrigger.Configuration.HLT_Fake2_cff') +process.load('Configuration.StandardSequences.RawToDigi_cff') +process.load('Configuration.StandardSequences.L1Reco_cff') +process.load('Configuration.StandardSequences.Reconstruction_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(3) +) + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring( +"file:/eos/cms/store/relval/CMSSW_13_1_0_pre3/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_131X_mcRun4_realistic_v2_PDMVRELVALS146-v7/2580000/1320a7f8-658e-48b4-80cd-ace713889f8c.root" + ) +) + + +process.options = cms.untracked.PSet( + +) + +# Production Info +process.configurationMetadata = cms.untracked.PSet( + annotation = cms.untracked.string('step2 nevts:10'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# MC vertice analyzer +process.load("Validation.RecoVertex.mcverticesanalyzer_cfi") +process.mcverticesanalyzer.pileupSummaryCollection = cms.InputTag("addPileupInfo","","HLT") + +process.Phase2ITQCoreProducer = cms.EDProducer('Phase2ITQCoreProducer', src = cms.InputTag("generalTracks"), siPixelDigi = cms.InputTag("simSiPixelDigis", "Pixel")) + +# # # -- Trajectory producer +process.load("RecoTracker.TrackProducer.TrackRefitters_cff") +process.TrackRefitter.src = "generalTracks" +process.TrackRefitter.NavigationSchool = "" + +# Additional output definition + +# Other statements +process.mix.digitizers = cms.PSet(process.theDigitizersValid) +# This pset is specific for producing simulated events for the designers of the PROC (InnerTracker) +# They need pixel RecHits where the charge is stored with high-granularity and large dynamic range + +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T30', '') + +# Path and EndPath definitions +process.digitisation_step = cms.Path(process.pdigi_valid) +process.L1simulation_step = cms.Path(process.SimL1Emulator) +process.L1TrackTrigger_step = cms.Path(process.L1TrackTrigger) +process.digi2raw_step = cms.Path(process.DigiToRaw) +process.raw2digi_step = cms.Path(process.RawToDigi) +process.L1Reco_step = cms.Path(process.L1Reco) +process.reconstruction_step = cms.Path(process.reconstruction) +process.user_step = cms.Path(process.TrackRefitter * process.Phase2ITQCoreProducer) +process.endjob_step = cms.EndPath(process.endOfProcess) + +# Schedule definition +process.schedule = cms.Schedule(process.digitisation_step,process.L1simulation_step,process.L1TrackTrigger_step,process.digi2raw_step) +process.schedule.extend([process.raw2digi_step,process.L1Reco_step,process.reconstruction_step,process.user_step,process.endjob_step]) + +# Have logErrorHarvester wait for the same EDProducers to finish as those providing data for the OutputModule +from FWCore.Modules.logErrorHarvester_cff import customiseLogErrorHarvesterUsingOutputCommands +process = customiseLogErrorHarvesterUsingOutputCommands(process) +# Add early deletion of temporary data products to reduce peak memory need +from Configuration.StandardSequences.earlyDeleteSettings_cff import customiseEarlyDelete +process = customiseEarlyDelete(process) + +# End adding early deletion +process.TFileService = cms.Service('TFileService', + fileName = cms.string("pixelbitstream.root") +) +