Skip to content
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

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions DataFormats/Phase2TrackerDigi/interface/Phase2ITChip.h
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
25 changes: 25 additions & 0 deletions DataFormats/Phase2TrackerDigi/interface/Phase2ITChipBitStream.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
21 changes: 21 additions & 0 deletions DataFormats/Phase2TrackerDigi/interface/Phase2ITDigiHit.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
61 changes: 61 additions & 0 deletions DataFormats/Phase2TrackerDigi/interface/Phase2ITQCore.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
130 changes: 130 additions & 0 deletions DataFormats/Phase2TrackerDigi/src/Phase2ITChip.cc
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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As Phase2ITQCore contains std::vectors, copying a vector<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 the qcores as in-out parameter (i.e. taking it by reference), and just modifying it instead of copying the Phase2ITQCore objects? (maybe in a subsequent PR if that would need a long time to do)

Copy link
Contributor Author

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

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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here about possible cost of copying (vector of) Phase2ITQCore around.

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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here about possible cost of copying (vector of) Phase2ITQCore around.

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;
}
8 changes: 8 additions & 0 deletions DataFormats/Phase2TrackerDigi/src/Phase2ITDigiHit.cc
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;
}
Loading