-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
quarter core processor for HL-LHC inner tracker developments #45759
Changes from 4 commits
5a35f2c
63fae6f
a927dcb
cfa1103
6118c11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#ifndef DataFormats_Phase2TrackerDigi_Phase2ITChip_H | ||
#define DataFormats_Phase2TrackerDigi_Phase2ITChip_H | ||
#include <vector> | ||
#include <utility> | ||
#include <string> | ||
#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<Phase2ITDigiHit> hl); | ||
|
||
unsigned int size(); | ||
int rocnum() const { return rocnum_; } | ||
|
||
std::vector<Phase2ITQCore> get_organized_QCores(); | ||
std::vector<bool> get_chip_code(); | ||
|
||
private: | ||
std::vector<Phase2ITDigiHit> hitList_; | ||
int rocnum_; | ||
|
||
std::pair<int, int> get_QCore_pos(Phase2ITDigiHit hit); | ||
|
||
Phase2ITQCore get_QCore_from_hit(Phase2ITDigiHit pixel); | ||
std::vector<Phase2ITQCore> rem_duplicates(std::vector<Phase2ITQCore> qcores); | ||
std::vector<Phase2ITQCore> organize_QCores(std::vector<Phase2ITQCore> qcores); | ||
}; | ||
|
||
#endif // DataFormats_Phase2TrackerDigi_Phase2ITChip_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef DataFormats_Phase2TrackerDigi_Phase2ITChipBitStream_H | ||
#define DataFormats_Phase2TrackerDigi_Phase2ITChipBitStream_H | ||
#include <vector> | ||
|
||
class Phase2ITChipBitStream { | ||
// Encoded bit stream output from chips | ||
public: | ||
Phase2ITChipBitStream(int rocid, const std::vector<bool>& bitstream) { | ||
rocid_ = rocid; | ||
bitstream_ = bitstream; | ||
} | ||
|
||
Phase2ITChipBitStream() { rocid_ = -1; } | ||
|
||
int get_rocid() const { return rocid_; } | ||
|
||
const std::vector<bool>& get_bitstream() const { return bitstream_; } | ||
|
||
const bool operator<(const Phase2ITChipBitStream& other) { return rocid_ < other.rocid_; } | ||
|
||
private: | ||
int rocid_; // Chip index | ||
std::vector<bool> bitstream_; // Chip bit stream output | ||
}; | ||
#endif // DataFormats_Phase2TrackerDigi_Phase2ITChipBitStream_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#ifndef DataFormats_Phase2TrackerDigi_Phase2ITQCore_H | ||
#define DataFormats_Phase2TrackerDigi_Phase2ITQCore_H | ||
#include <vector> | ||
|
||
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<int>& adcs_in, | ||
const std::vector<int>& 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<bool> getHitmap(); | ||
std::vector<int> getADCs(); | ||
std::vector<bool> 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<int> adcs_; // Full array of adc values in a quarter core | ||
std::vector<int> 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<bool> toRocCoordinates(std::vector<bool>& hitmap); | ||
std::vector<bool> intToBinary(int num, int length); | ||
bool containsHit(std::vector<bool>& hitmap); | ||
std::vector<bool> getHitmapCode(std::vector<bool> hitmap); | ||
}; | ||
|
||
#endif // DataFormats_Phase2TrackerDigi_Phase2ITQCore_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
#include <vector> | ||
#include <utility> | ||
#include <string> | ||
#include <iostream> | ||
#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<Phase2ITDigiHit> 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<int, int> 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<int> adcs(16, 0), hits(16, 0); | ||
std::pair<int, int> 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<Phase2ITQCore> Phase2ITChip::rem_duplicates(std::vector<Phase2ITQCore> qcores) { | ||
std::vector<Phase2ITQCore> 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<Phase2ITQCore> Phase2ITChip::organize_QCores(std::vector<Phase2ITQCore> qcores) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment here about possible cost of copying ( |
||
std::vector<Phase2ITQCore> organized_list = {}; | ||
while (qcores.size() > 0) { | ||
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<Phase2ITQCore> link_QCores(std::vector<Phase2ITQCore> qcores) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment here about possible cost of copying ( |
||
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.size() > 0) { | ||
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<Phase2ITQCore> Phase2ITChip::get_organized_QCores() { | ||
std::vector<Phase2ITQCore> qcores = {}; | ||
|
||
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<bool> Phase2ITChip::get_chip_code() { | ||
std::vector<bool> code = {}; | ||
|
||
if (hitList_.size() > 0) { | ||
std::vector<Phase2ITQCore> qcores = get_organized_QCores(); | ||
bool is_new_col = true; | ||
|
||
for (auto& qcore : qcores) { | ||
std::vector<bool> qcore_code = qcore.encodeQCore(is_new_col); | ||
code.insert(code.end(), qcore_code.begin(), qcore_code.end()); | ||
|
||
is_new_col = qcore.islast(); | ||
} | ||
} | ||
|
||
return code; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As
Phase2ITQCore
containsstd::vectors
, copying avector<Phase2ITQCore>
can be expensive (depending on the frequency this function is called).Given how this function (and the other functions following the same pattern) are called in
get_organized_QCores()
, how about organizing these functions in a way that they treat would treat theqcores
as in-out parameter (i.e. taking it by reference), and just modifying it instead of copying thePhase2ITQCore
objects? (maybe in a subsequent PR if that would need a long time to do)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, for this I'll take note and fix it in the next PR. This is going to be a tentative innertracker chip data processor so that we can first do the DAQ studies