Skip to content

Commit

Permalink
Merge pull request #39388 from eyigitba/EMTF_unpackerRPCGEMRun3_Sept22
Browse files Browse the repository at this point in the history
Modify RPC and GEM unpacker blocks in EMTF unpacker to match the new Run 3 format
  • Loading branch information
cmsbuild authored Sep 15, 2022
2 parents 6d6ccc9 + 664c88a commit f3954b5
Show file tree
Hide file tree
Showing 3 changed files with 283 additions and 213 deletions.
242 changes: 138 additions & 104 deletions EventFilter/L1TRawToDigi/plugins/implementations_stage2/EMTFBlockGEM.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ namespace l1t {
// payload[0] = bits 0-15, payload[1] = 16-31, payload[3] = 32-47, etc.
auto payload = block.payload();

// Run 3 has a different EMTF DAQ output format since August 26th
// Computed as (Year - 2000)*2^9 + Month*2^5 + Day (see Block.cc and EMTFBlockTrailers.cc)
bool run3_DAQ_format =
(getAlgoVersion() >=
11546); // Firmware from 26.08.22 which enabled new Run 3 DAQ format for GEMs - EY 13.09.22

int nTPs = run3_DAQ_format ? 2 : 1;

// Check Format of Payload
l1t::emtf::GEM GEM_;
for (int err = 0; err < checkFormat(block); ++err) {
Expand All @@ -139,118 +147,144 @@ namespace l1t {
uint16_t GEMc = payload[2];
uint16_t GEMd = payload[3];

// res is a pointer to a collection of EMTFDaqOut class objects
// There is one EMTFDaqOut for each MTF7 (60 deg. sector) in the event
EMTFDaqOutCollection* res;
res = static_cast<EMTFCollections*>(coll)->getEMTFDaqOuts();
int iOut = res->size() - 1;

EMTFHitCollection* res_hit;
res_hit = static_cast<EMTFCollections*>(coll)->getEMTFHits();
EMTFHit Hit_;

// TODO: Verify this is correct for GEM
GEMPadDigiClusterCollection* res_GEM;
res_GEM = static_cast<EMTFCollections*>(coll)->getEMTFGEMPadClusters();

////////////////////////////
// Unpack the GEM Data Record
////////////////////////////

GEM_.set_pad(GetHexBits(GEMa, 0, 8));
GEM_.set_partition(GetHexBits(GEMa, 9, 11));
GEM_.set_cluster_size(GetHexBits(GEMa, 12, 14));

GEM_.set_cluster_id(GetHexBits(GEMb, 8, 11));
GEM_.set_link(GetHexBits(GEMb, 12, 14));

GEM_.set_gem_bxn(GetHexBits(GEMc, 0, 11));
GEM_.set_bc0(GetHexBits(GEMc, 14, 14));

GEM_.set_tbin(GetHexBits(GEMd, 0, 2));
GEM_.set_vp(GetHexBits(GEMd, 3, 3));

// GEM_.set_dataword(uint64_t dataword);

// Convert specially-encoded GEM quantities
// TODO: is the RPC or CSC method for this function better... - JS 06.07.20
int _station, _ring, _sector, _subsector, _neighbor, _layer;
convert_GEM_location(_station,
_ring,
_sector,
_subsector,
_neighbor,
_layer,
(res->at(iOut)).PtrEventHeader()->Sector(),
GEM_.ClusterID(),
GEM_.Link());

// Rotate by 20 deg to match GEM convention in CMSSW) // FIXME VERIFY
// int _sector_gem = (_subsector < 5) ? _sector : (_sector % 6) + 1; //
int _sector_gem = _sector;
// Rotate by 2 to match GEM convention in CMSSW (GEMDetId.h) // FIXME VERIFY
int _subsector_gem = ((_subsector + 1) % 6) + 1;
// Define chamber number) // FIXME VERIFY
int _chamber = (_sector_gem - 1) * 6 + _subsector_gem;
// Define CSC-like subsector) // FIXME WHY?? VERIFY
int _subsector_csc = (_station != 1) ? 0 : ((_chamber % 6 > 2) ? 1 : 2);

Hit_.set_station(_station);
Hit_.set_ring(_ring);
Hit_.set_sector(_sector);
Hit_.set_subsector(_subsector_csc);
Hit_.set_chamber(_chamber);
Hit_.set_neighbor(_neighbor);

// Fill the EMTFHit
ImportGEM(Hit_, GEM_, (res->at(iOut)).PtrEventHeader()->Endcap(), (res->at(iOut)).PtrEventHeader()->Sector());

// Set the stub number for this hit
// Each chamber can send up to 2 stubs per BX // FIXME is this true for GEM, are stubs relevant for GEMs?
// Also count stubs in corresponding CSC chamber; GEM hit counting is on top of LCT counting
Hit_.set_stub_num(0);
// See if matching hit is already in event record
bool exact_duplicate = false;
for (auto const& iHit : *res_hit) {
if (Hit_.BX() == iHit.BX() && Hit_.Endcap() == iHit.Endcap() && Hit_.Station() == iHit.Station() &&
Hit_.Chamber() == iHit.Chamber()) {
if ((iHit.Is_CSC() == 1 && iHit.Ring() == 2) ||
(iHit.Is_GEM() == 1)) { // Copied from RPC, but GEM has no ring 2/3...
if (Hit_.Neighbor() == iHit.Neighbor()) {
Hit_.set_stub_num(Hit_.Stub_num() + 1);
if (iHit.Is_GEM() == 1 && iHit.Ring() == Hit_.Ring() && iHit.Roll() == Hit_.Roll() &&
iHit.Pad() == Hit_.Pad()) {
exact_duplicate = true;
for (int i = 0; i < nTPs; i++) {
// res is a pointer to a collection of EMTFDaqOut class objects
// There is one EMTFDaqOut for each MTF7 (60 deg. sector) in the event
EMTFDaqOutCollection* res;
res = static_cast<EMTFCollections*>(coll)->getEMTFDaqOuts();
int iOut = res->size() - 1;

EMTFHitCollection* res_hit;
res_hit = static_cast<EMTFCollections*>(coll)->getEMTFHits();
EMTFHit Hit_;

// TODO: Verify this is correct for GEM
GEMPadDigiClusterCollection* res_GEM;
res_GEM = static_cast<EMTFCollections*>(coll)->getEMTFGEMPadClusters();

////////////////////////////
// Unpack the GEM Data Record
////////////////////////////
if (run3_DAQ_format) { // Run 3 DAQ format has 2 TPs per block
if (i == 1) {
GEM_.set_pad(GetHexBits(GEMa, 0, 8));
GEM_.set_partition(GetHexBits(GEMa, 9, 11));
GEM_.set_cluster_size(GetHexBits(GEMa, 12, 14));

GEM_.set_tbin(GetHexBits(GEMb, 0, 2));
GEM_.set_vp(GetHexBits(GEMb, 3, 3));
GEM_.set_bc0(GetHexBits(GEMb, 7, 7));
GEM_.set_cluster_id(GetHexBits(GEMb, 8, 11));
GEM_.set_link(GetHexBits(GEMb, 12, 14));
} else if (i == 2) {
GEM_.set_pad(GetHexBits(GEMc, 0, 8));
GEM_.set_partition(GetHexBits(GEMc, 9, 11));
GEM_.set_cluster_size(GetHexBits(GEMc, 12, 14));

GEM_.set_tbin(GetHexBits(GEMd, 0, 2));
GEM_.set_vp(GetHexBits(GEMd, 3, 3));
GEM_.set_bc0(GetHexBits(GEMd, 7, 7));
GEM_.set_cluster_id(GetHexBits(GEMd, 8, 11));
GEM_.set_link(GetHexBits(GEMd, 12, 14));
}
} else {
GEM_.set_pad(GetHexBits(GEMa, 0, 8));
GEM_.set_partition(GetHexBits(GEMa, 9, 11));
GEM_.set_cluster_size(GetHexBits(GEMa, 12, 14));

GEM_.set_cluster_id(GetHexBits(GEMb, 8, 11));
GEM_.set_link(GetHexBits(GEMb, 12, 14));

GEM_.set_gem_bxn(GetHexBits(GEMc, 0, 11));
GEM_.set_bc0(GetHexBits(GEMc, 14, 14));

GEM_.set_tbin(GetHexBits(GEMd, 0, 2));
GEM_.set_vp(GetHexBits(GEMd, 3, 3));

// GEM_.set_dataword(uint64_t dataword);
}

// Convert specially-encoded GEM quantities
// TODO: is the RPC or CSC method for this function better... - JS 06.07.20
int _station, _ring, _sector, _subsector, _neighbor, _layer;
convert_GEM_location(_station,
_ring,
_sector,
_subsector,
_neighbor,
_layer,
(res->at(iOut)).PtrEventHeader()->Sector(),
GEM_.ClusterID(),
GEM_.Link());

// Rotate by 20 deg to match GEM convention in CMSSW) // FIXME VERIFY
// int _sector_gem = (_subsector < 5) ? _sector : (_sector % 6) + 1; //
int _sector_gem = _sector;
// Rotate by 2 to match GEM convention in CMSSW (GEMDetId.h) // FIXME VERIFY
int _subsector_gem = ((_subsector + 1) % 6) + 1;
// Define chamber number) // FIXME VERIFY
int _chamber = (_sector_gem - 1) * 6 + _subsector_gem;
// Define CSC-like subsector) // FIXME WHY?? VERIFY
int _subsector_csc = (_station != 1) ? 0 : ((_chamber % 6 > 2) ? 1 : 2);

Hit_.set_station(_station);
Hit_.set_ring(_ring);
Hit_.set_sector(_sector);
Hit_.set_subsector(_subsector_csc);
Hit_.set_chamber(_chamber);
Hit_.set_neighbor(_neighbor);

// Fill the EMTFHit
ImportGEM(Hit_, GEM_, (res->at(iOut)).PtrEventHeader()->Endcap(), (res->at(iOut)).PtrEventHeader()->Sector());

// Set the stub number for this hit
// Each chamber can send up to 2 stubs per BX // FIXME is this true for GEM, are stubs relevant for GEMs?
// Also count stubs in corresponding CSC chamber; GEM hit counting is on top of LCT counting
Hit_.set_stub_num(0);
// See if matching hit is already in event record
bool exact_duplicate = false;
for (auto const& iHit : *res_hit) {
if (Hit_.BX() == iHit.BX() && Hit_.Endcap() == iHit.Endcap() && Hit_.Station() == iHit.Station() &&
Hit_.Chamber() == iHit.Chamber()) {
if ((iHit.Is_CSC() == 1 && iHit.Ring() == 2) ||
(iHit.Is_GEM() == 1)) { // Copied from RPC, but GEM has no ring 2/3...
if (Hit_.Neighbor() == iHit.Neighbor()) {
Hit_.set_stub_num(Hit_.Stub_num() + 1);
if (iHit.Is_GEM() == 1 && iHit.Ring() == Hit_.Ring() && iHit.Roll() == Hit_.Roll() &&
iHit.Pad() == Hit_.Pad()) {
exact_duplicate = true;
}
}
}
}
} // End loop: for (auto const & iHit : *res_hit)

// Reject TPs with out-of-range BX values. This needs to be adjusted if we increase l1a_window parameter in EMTF config - EY 03.08.2022
if (Hit_.BX() > 3 or Hit_.BX() < -3) {
edm::LogWarning("L1T|EMTF") << "EMTF unpacked GEM digis with out-of-range BX! BX " << Hit_.BX()
<< ", endcap " << Hit_.Endcap() << ", station " << Hit_.Station()
<< ", neighbor " << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber "
<< Hit_.Chamber() << ", roll " << Hit_.Roll() << ", pad " << Hit_.Pad()
<< std::endl;
return true;
}
} // End loop: for (auto const & iHit : *res_hit)

// Reject TPs with out-of-range BX values. This needs to be adjusted if we increase l1a_window parameter in EMTF config - EY 03.08.2022
if (Hit_.BX() > 3 or Hit_.BX() < -3) {
edm::LogWarning("L1T|EMTF") << "EMTF unpacked GEM digis with out-of-range BX! BX " << Hit_.BX()
<< ", endcap " << Hit_.Endcap() << ", station " << Hit_.Station() << ", neighbor "
<< Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber " << Hit_.Chamber()
<< ", roll " << Hit_.Roll() << ", pad " << Hit_.Pad() << std::endl;
return true;
}

// TODO: Re-enable once GEM TP data format is fixed
// if (exact_duplicate)
// edm::LogWarning("L1T|EMTF") << "EMTF unpacked duplicate GEM digis: BX " << Hit_.BX() << ", endcap "
// << Hit_.Endcap() << ", station " << Hit_.Station() << ", neighbor "
// << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber " << Hit_.Chamber()
// << ", roll " << Hit_.Roll() << ", pad " << Hit_.Pad() << std::endl;
// TODO: Re-enable once GEM TP data format is fixed
// if (exact_duplicate)
// edm::LogWarning("L1T|EMTF") << "EMTF unpacked duplicate GEM digis: BX " << Hit_.BX() << ", endcap "
// << Hit_.Endcap() << ", station " << Hit_.Station() << ", neighbor "
// << Hit_.Neighbor() << ", ring " << Hit_.Ring() << ", chamber " << Hit_.Chamber()
// << ", roll " << Hit_.Roll() << ", pad " << Hit_.Pad() << std::endl;

(res->at(iOut)).push_GEM(GEM_);
if (!exact_duplicate)
res_hit->push_back(Hit_);
(res->at(iOut)).push_GEM(GEM_);
if (!exact_duplicate)
res_hit->push_back(Hit_);

if (!exact_duplicate)
res_GEM->insertDigi(Hit_.GEM_DetId(), Hit_.CreateGEMPadDigiCluster());
if (!exact_duplicate)
res_GEM->insertDigi(Hit_.GEM_DetId(), Hit_.CreateGEMPadDigiCluster());

// Finished with unpacking one GEM Data Record
// Finished with unpacking one GEM Data Record
}
return true;

} // End bool GEMBlockUnpacker::unpack
Expand Down
Loading

0 comments on commit f3954b5

Please sign in to comment.