File indexing completed on 2024-12-20 03:13:41
0001 #include "FWCore/Framework/interface/ConsumesCollector.h"
0002
0003 #include "FWCore/Framework/interface/one/EDProducer.h"
0004 #include "FWCore/Framework/interface/Event.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "FWCore/Framework/interface/EventSetup.h"
0007 #include "FWCore/Utilities/interface/InputTag.h"
0008
0009 #include "DataFormats/L1CSCTrackFinder/interface/L1CSCTrackCollection.h"
0010 #include "DataFormats/L1CSCTrackFinder/interface/CSCTriggerContainer.h"
0011 #include "DataFormats/L1CSCTrackFinder/interface/TrackStub.h"
0012
0013 #include <string>
0014
0015 class CSCTFPacker : public edm::one::EDProducer<> {
0016 private:
0017 edm::InputTag lctProducer, mbProducer, trackProducer;
0018
0019 bool zeroSuppression;
0020 unsigned short nTBINs;
0021 unsigned short activeSectors;
0022 bool putBufferToEvent;
0023
0024 bool swapME1strips;
0025
0026 FILE* file;
0027
0028 int m_minBX, m_maxBX, central_lct_bx, central_sp_bx;
0029
0030 edm::EDGetTokenT<CSCCorrelatedLCTDigiCollection> CSCCDC_Tok;
0031 edm::EDGetTokenT<CSCTriggerContainer<csctf::TrackStub> > CSCTC_Tok;
0032 edm::EDGetTokenT<L1CSCTrackCollection> L1CSCTr_Tok;
0033
0034 public:
0035 void produce(edm::Event& e, const edm::EventSetup& c) override;
0036
0037 explicit CSCTFPacker(const edm::ParameterSet& conf);
0038 ~CSCTFPacker(void) override;
0039 };
0040
0041 #include "EventFilter/CSCTFRawToDigi/src/CSCTFEvent.h"
0042
0043 #include <strings.h>
0044 #include <cerrno>
0045 #include <iostream>
0046 #include <cstdio>
0047
0048 #include "DataFormats/Common/interface/Handle.h"
0049 #include "FWCore/Framework/interface/ESHandle.h"
0050 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0051 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigi.h"
0052 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiCollection.h"
0053 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0054 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0055 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0056 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0057 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0058 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0059 #include "FWCore/Utilities/interface/CRC16.h"
0060
0061 CSCTFPacker::CSCTFPacker(const edm::ParameterSet& conf) : edm::one::EDProducer<>() {
0062
0063 zeroSuppression = conf.getParameter<bool>("zeroSuppression");
0064 nTBINs = conf.getParameter<int>("nTBINs");
0065 activeSectors = conf.getParameter<int>("activeSectors");
0066
0067
0068 putBufferToEvent = conf.getParameter<bool>("putBufferToEvent");
0069 std::string outputFile = conf.getParameter<std::string>("outputFile");
0070 lctProducer = conf.getParameter<edm::InputTag>("lctProducer");
0071 mbProducer = conf.getParameter<edm::InputTag>("mbProducer");
0072 trackProducer = conf.getParameter<edm::InputTag>("trackProducer");
0073
0074
0075 swapME1strips = conf.getParameter<bool>("swapME1strips");
0076
0077 file = nullptr;
0078 if (!outputFile.empty() && (file = fopen(outputFile.c_str(), "wt")) == nullptr)
0079 throw cms::Exception("OutputFile ") << "CSCTFPacker: cannot open output file (errno=" << errno
0080 << "). Try outputFile=\"\"";
0081
0082
0083 m_minBX = conf.getParameter<int>("MinBX");
0084 m_maxBX = conf.getParameter<int>("MaxBX");
0085
0086
0087
0088 central_lct_bx = (m_maxBX + m_minBX) / 2;
0089
0090
0091 central_sp_bx = int(nTBINs / 2);
0092
0093 produces<FEDRawDataCollection>("CSCTFRawData");
0094
0095 CSCTC_Tok =
0096 consumes<CSCTriggerContainer<csctf::TrackStub> >(edm::InputTag(mbProducer.label(), mbProducer.instance()));
0097 CSCCDC_Tok = consumes<CSCCorrelatedLCTDigiCollection>(edm::InputTag(lctProducer.label(), lctProducer.instance()));
0098 L1CSCTr_Tok = consumes<L1CSCTrackCollection>(edm::InputTag(trackProducer.label(), trackProducer.instance()));
0099 }
0100
0101 CSCTFPacker::~CSCTFPacker(void) {
0102 if (file)
0103 fclose(file);
0104 }
0105
0106 void CSCTFPacker::produce(edm::Event& e, const edm::EventSetup& c) {
0107 edm::Handle<CSCCorrelatedLCTDigiCollection> corrlcts;
0108 e.getByToken(CSCCDC_Tok, corrlcts);
0109
0110 CSCSP_MEblock meDataRecord[12][7][5][9][2];
0111 bzero(&meDataRecord, sizeof(meDataRecord));
0112 CSCSPRecord meDataHeader[12][7];
0113 bzero(&meDataHeader, sizeof(meDataHeader));
0114
0115 for (CSCCorrelatedLCTDigiCollection::DigiRangeIterator csc = corrlcts.product()->begin();
0116 csc != corrlcts.product()->end();
0117 csc++) {
0118 CSCCorrelatedLCTDigiCollection::Range range1 = corrlcts.product()->get((*csc).first);
0119 int lctId = 0;
0120 for (CSCCorrelatedLCTDigiCollection::const_iterator lct = range1.first; lct != range1.second; lct++, lctId++) {
0121 int station = (*csc).first.station() - 1;
0122 int cscId = (*csc).first.triggerCscId() - 1;
0123 int sector = (*csc).first.triggerSector() - 1 + ((*csc).first.endcap() == 1 ? 0 : 6);
0124 int subSector = CSCTriggerNumbering::triggerSubSectorFromLabels((*csc).first);
0125 int tbin = lct->getBX() - (central_lct_bx - central_sp_bx);
0126 if (tbin > 6 || tbin < 0) {
0127 edm::LogError("CSCTFPacker|produce") << " LCT's BX=" << tbin << " is out of 0-6 window";
0128 continue;
0129 }
0130 int fpga = (subSector ? subSector - 1 : station + 1);
0131
0132
0133
0134 if (sector < 0 || sector > 11 || station < 0 || station > 3 || cscId < 0 || cscId > 8 || lctId < 0 || lctId > 1) {
0135 edm::LogInfo("CSCTFPacker: CSC digi are out of range: ")
0136 << "sector=" << sector << ", station=" << station << ", cscId=" << cscId << ", lctId=" << lctId;
0137 continue;
0138 }
0139
0140 meDataRecord[sector][tbin][fpga][cscId][lctId].clct_pattern_number = lct->getPattern();
0141 meDataRecord[sector][tbin][fpga][cscId][lctId].quality_ = lct->getQuality();
0142 meDataRecord[sector][tbin][fpga][cscId][lctId].wire_group_id = lct->getKeyWG();
0143
0144 meDataRecord[sector][tbin][fpga][cscId][lctId].clct_pattern_id =
0145 (swapME1strips && cscId < 3 && station == 0 && (*csc).first.endcap() == 2 && lct->getStrip() < 65
0146 ? 65 - lct->getStrip()
0147 : lct->getStrip());
0148 meDataRecord[sector][tbin][fpga][cscId][lctId].csc_id = (*csc).first.triggerCscId();
0149 meDataRecord[sector][tbin][fpga][cscId][lctId].left_right = lct->getBend();
0150 meDataRecord[sector][tbin][fpga][cscId][lctId].bx0_ = 0;
0151 meDataRecord[sector][tbin][fpga][cscId][lctId].bc0_ = 0;
0152
0153 meDataRecord[sector][tbin][fpga][cscId][lctId].me_bxn = 0;
0154 meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_er1 = 0;
0155 meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_dv1 = 0;
0156 meDataRecord[sector][tbin][fpga][cscId][lctId].aligment_fifo_full = 0;
0157
0158 meDataRecord[sector][tbin][fpga][cscId][lctId].link_id = lct->getMPCLink();
0159 meDataRecord[sector][tbin][fpga][cscId][lctId].mpc_id = 0;
0160 meDataRecord[sector][tbin][fpga][cscId][lctId].err_prop_cnt = 0;
0161 meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_er2 = 0;
0162 meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_dv2 = 0;
0163 meDataRecord[sector][tbin][fpga][cscId][lctId].aligment_fifo_empty = 0;
0164
0165 if (lct->isValid()) {
0166 switch ((meDataHeader[sector][tbin].vp_bits >> (fpga * 3)) & 0x7) {
0167 case 0x0:
0168 meDataHeader[sector][tbin].vp_bits |= (0x1 << (fpga * 3));
0169 break;
0170 case 0x1:
0171 meDataHeader[sector][tbin].vp_bits |= (0x3 << (fpga * 3));
0172 break;
0173 case 0x3:
0174 meDataHeader[sector][tbin].vp_bits |= (0x7 << (fpga * 3));
0175 break;
0176 default:
0177 edm::LogInfo("CSCTFPacker: more than 3 LCTs from a single MPC in one BX!!!");
0178 continue;
0179 break;
0180 }
0181 meDataRecord[sector][tbin][fpga][cscId][lctId].valid_pattern = 1;
0182 }
0183 meDataHeader[sector][tbin].vq_a = 0;
0184 meDataHeader[sector][tbin].vq_b = 0;
0185 meDataHeader[sector][tbin].se_bits = 0;
0186 meDataHeader[sector][tbin].sm_bits = 0;
0187 meDataHeader[sector][tbin].af_bits = 0;
0188 meDataHeader[sector][tbin].bx_bits = 0;
0189
0190 meDataHeader[sector][tbin].spare_1 = 0;
0191 }
0192 }
0193
0194 CSCSP_MBblock mbDataRecord[12][2][7];
0195 bzero(&mbDataRecord, sizeof(mbDataRecord));
0196 edm::Handle<CSCTriggerContainer<csctf::TrackStub> > barrelStubs;
0197 if (mbProducer.label() != "null") {
0198 e.getByToken(CSCTC_Tok, barrelStubs);
0199 if (barrelStubs.isValid()) {
0200 std::vector<csctf::TrackStub> stubs = barrelStubs.product()->get();
0201 for (std::vector<csctf::TrackStub>::const_iterator dt = stubs.begin(); dt != stubs.end(); dt++) {
0202 int sector = dt->sector() - 1 + (dt->endcap() == 1 ? 0 : 6);
0203 int subSector = dt->subsector() - 1;
0204 int tbin = dt->getBX() - (central_lct_bx - central_sp_bx);
0205 if (tbin < 0 || tbin > 6 || sector < 0 || sector > 11 || subSector < 0 || subSector > 11) {
0206 edm::LogInfo("CSCTFPacker: CSC DT digi are out of range: ")
0207 << " sector=" << sector << " subSector=" << subSector << " tbin=" << tbin;
0208 continue;
0209 }
0210 mbDataRecord[sector][subSector][tbin].quality_ = dt->getQuality();
0211 mbDataRecord[sector][subSector][tbin].phi_bend_ = dt->getBend();
0212 mbDataRecord[sector][subSector][tbin].flag_ = dt->getStrip();
0213 mbDataRecord[sector][subSector][tbin].cal_ = dt->getKeyWG();
0214 mbDataRecord[sector][subSector][tbin].phi_ = dt->phiPacked();
0215 mbDataRecord[sector][subSector][tbin].bxn1_ = (dt->getBX0() >> 1) & 0x1;
0216 mbDataRecord[sector][subSector][tbin].bxn0_ = dt->getBX0() & 0x1;
0217 mbDataRecord[sector][subSector][tbin].bc0_ = dt->getPattern();
0218 mbDataRecord[sector][subSector][tbin].mb_bxn_ = dt->getCSCID();
0219 switch (subSector) {
0220 case 0:
0221 meDataHeader[sector][tbin].vq_a = 1;
0222 break;
0223 case 1:
0224 meDataHeader[sector][tbin].vq_b = 1;
0225 break;
0226 default:
0227 edm::LogInfo("CSCTFPacker: subSector=") << subSector;
0228 break;
0229 }
0230 mbDataRecord[sector][subSector][tbin].id_ = dt->getMPCLink();
0231 }
0232 }
0233 }
0234
0235 CSCSP_SPblock spDataRecord[12][7][3];
0236 bzero(&spDataRecord, sizeof(spDataRecord));
0237 int nTrk[12][7];
0238 bzero(&nTrk, sizeof(nTrk));
0239
0240 edm::Handle<L1CSCTrackCollection> tracks;
0241 if (trackProducer.label() != "null") {
0242 e.getByToken(L1CSCTr_Tok, tracks);
0243
0244 for (L1CSCTrackCollection::const_iterator trk = tracks->begin(); trk != tracks->end(); trk++) {
0245 int sector = 6 * (trk->first.endcap() - 1) + trk->first.sector() - 1;
0246 int tbin = trk->first.BX() + central_sp_bx;
0247
0248 if (tbin > 6 || tbin < 0) {
0249 edm::LogError("CSCTFPacker|analyze") << " Track's BX=" << tbin << " is out of 0-6 window";
0250 continue;
0251 }
0252 if (sector < 0 || sector > 11) {
0253 edm::LogError("CSCTFPacker|analyze") << " Track's sector=" << sector << " is out of range";
0254 continue;
0255 }
0256 spDataRecord[sector][tbin][nTrk[sector][tbin]].phi_ = trk->first.localPhi();
0257 spDataRecord[sector][tbin][nTrk[sector][tbin]].sign_ = (trk->first.ptLUTAddress() >> 20) & 0x1;
0258 spDataRecord[sector][tbin][nTrk[sector][tbin]].front_rear = trk->first.front_rear();
0259 spDataRecord[sector][tbin][nTrk[sector][tbin]].charge_ = trk->first.charge_packed();
0260 spDataRecord[sector][tbin][nTrk[sector][tbin]].eta_ = trk->first.eta_packed();
0261
0262 spDataRecord[sector][tbin][nTrk[sector][tbin]].halo_ = trk->first.finehalo_packed();
0263 spDataRecord[sector][tbin][nTrk[sector][tbin]].se = 0;
0264 spDataRecord[sector][tbin][nTrk[sector][tbin]].deltaPhi12_ = trk->first.ptLUTAddress() & 0xFF;
0265 spDataRecord[sector][tbin][nTrk[sector][tbin]].deltaPhi23_ = (trk->first.ptLUTAddress() >> 8) & 0xF;
0266 spDataRecord[sector][tbin][nTrk[sector][tbin]].bxn0_ = 0;
0267 spDataRecord[sector][tbin][nTrk[sector][tbin]].bc0_ = 0;
0268
0269 spDataRecord[sector][tbin][nTrk[sector][tbin]].me1_id = trk->first.me1ID();
0270 spDataRecord[sector][tbin][nTrk[sector][tbin]].me2_id = trk->first.me2ID();
0271 spDataRecord[sector][tbin][nTrk[sector][tbin]].me3_id = trk->first.me3ID();
0272 spDataRecord[sector][tbin][nTrk[sector][tbin]].me4_id = trk->first.me4ID();
0273 spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_id = trk->first.mb1ID();
0274 spDataRecord[sector][tbin][nTrk[sector][tbin]].ms_id = 0;
0275
0276
0277 spDataRecord[sector][tbin][nTrk[sector][tbin]].me1_tbin = trk->first.me1Tbin();
0278 spDataRecord[sector][tbin][nTrk[sector][tbin]].me2_tbin = trk->first.me2Tbin();
0279 spDataRecord[sector][tbin][nTrk[sector][tbin]].me3_tbin = trk->first.me3Tbin();
0280 spDataRecord[sector][tbin][nTrk[sector][tbin]].me4_tbin = trk->first.me4Tbin();
0281 spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_tbin = trk->first.mb1Tbin();
0282
0283 if (trk->first.mb1ID()) {
0284 int subSector = (trk->first.mb1ID() - 1) % 2;
0285 int MBtbin = tbin - spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_tbin;
0286 if (subSector < 0 || subSector > 1 || MBtbin < 0 || MBtbin > 7 || !mbDataRecord[sector][subSector][MBtbin].id_)
0287 spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_id = (subSector ? 6 : 5);
0288 }
0289 spDataRecord[sector][tbin][nTrk[sector][tbin]].id_ = nTrk[sector][tbin] + 1;
0290
0291 nTrk[sector][tbin]++;
0292 switch (nTrk[sector][tbin]) {
0293 case 1:
0294 meDataHeader[sector][tbin].mode1 = (trk->first.ptLUTAddress() >> 16) & 0xF;
0295 break;
0296 case 2:
0297 meDataHeader[sector][tbin].mode2 = (trk->first.ptLUTAddress() >> 16) & 0xF;
0298 break;
0299 case 3:
0300 meDataHeader[sector][tbin].mode3 = (trk->first.ptLUTAddress() >> 16) & 0xF;
0301 break;
0302 default:
0303 edm::LogInfo("More than 3 tracks from one SP in the BX");
0304 continue;
0305 break;
0306 }
0307 }
0308 }
0309
0310 CSCSPHeader header;
0311 bzero(&header, sizeof(header));
0312
0313 header.header_mark_1 = 0x9;
0314 header.header_mark_2 = 0x9;
0315 header.header_mark_3 = 0x9;
0316 header.header_mark_4 = 0x9;
0317
0318 header.header_mark_5 = 0xA;
0319 header.header_mark_6 = 0xA;
0320 header.header_mark_7 = 0xA;
0321 header.header_mark_8 = 0xA;
0322
0323 header.csr_dfc = nTBINs;
0324 header.csr_dfc |= (zeroSuppression ? 0x8 : 0x0);
0325 header.csr_dfc |= 0x7F0;
0326 header.skip = 0;
0327 header.sp_ersv = 2;
0328
0329 CSCSPCounters counters;
0330 bzero(&counters, sizeof(counters));
0331
0332 CSCSPTrailer trailer;
0333 bzero(&trailer, sizeof(trailer));
0334
0335 trailer.trailer_mark_1 = 0xF;
0336 trailer.trailer_mark_2 = 0xF;
0337 trailer.trailer_mark_3 = 0x7;
0338 trailer.trailer_mark_4 = 0xF;
0339 trailer.trailer_mark_5 = 0xF;
0340 trailer.trailer_mark_6 = 0xF;
0341 trailer.trailer_mark_7 = 0xE;
0342 trailer.trailer_mark_8 = 0xE;
0343 trailer.trailer_mark_9 = 0xE;
0344 trailer.trailer_mark_10 = 0xE;
0345
0346 unsigned short spDDUrecord[700 * 12], *pos = spDDUrecord;
0347 bzero(&spDDUrecord, sizeof(spDDUrecord));
0348 int eventNumber = e.id().event();
0349 *pos++ = 0x0000;
0350 *pos++ = 0x0000;
0351 *pos++ = 0xFFFF & eventNumber;
0352 *pos++ = 0x5000 | (eventNumber >> 16);
0353 *pos++ = 0x0000;
0354 *pos++ = 0x8000;
0355 *pos++ = 0x0001;
0356 *pos++ = 0x8000;
0357 *pos++ = 0x0000;
0358 *pos++ = 0x0000;
0359 *pos++ = 0x0000;
0360 *pos++ = 0x0000;
0361
0362 for (int sector = 0; sector < 12; sector++) {
0363 if (!(activeSectors & (1 << sector)))
0364 continue;
0365 header.sp_trigger_sector = sector + 1;
0366 memcpy(pos, &header, 16);
0367 pos += 8;
0368 memcpy(pos, &counters, 8);
0369 pos += 4;
0370
0371 for (int tbin = 0; tbin < nTBINs; tbin++) {
0372 memcpy(pos, &meDataHeader[sector][tbin], 16);
0373 pos += 8;
0374 for (int fpga = 0; fpga < 5; fpga++) {
0375 int nLCTs = 0;
0376 for (int link = 0; link < 3; link++) {
0377 for (int cscId = 0; cscId < 9; cscId++)
0378 for (int lctId = 0; lctId < 2; lctId++)
0379
0380 if (meDataRecord[sector][tbin][fpga][cscId][lctId].valid_pattern &&
0381 meDataRecord[sector][tbin][fpga][cscId][lctId].link_id == link + 1) {
0382 memcpy(pos, &meDataRecord[sector][tbin][fpga][cscId][lctId], 8);
0383 pos += 4;
0384 nLCTs++;
0385 }
0386 }
0387 if (!zeroSuppression)
0388 pos += 4 * (3 - nLCTs);
0389 }
0390 for (int subSector = 0; subSector < 2; subSector++)
0391 if (!zeroSuppression || (subSector == 0 && meDataHeader[sector][tbin].vq_a) ||
0392 (subSector == 1 && meDataHeader[sector][tbin].vq_b)) {
0393 memcpy(pos, &mbDataRecord[sector][subSector][tbin], 8);
0394 pos += 4;
0395 }
0396 for (int trk = 0; trk < 3; trk++) {
0397 if (!zeroSuppression || spDataRecord[sector][tbin][trk].id_) {
0398 memcpy(pos, &spDataRecord[sector][tbin][trk], 8);
0399 pos += 4;
0400 }
0401 }
0402 }
0403 memcpy(pos, &trailer, 16);
0404 pos += 8;
0405 }
0406
0407 *pos++ = 0x8000;
0408 *pos++ = 0x8000;
0409 *pos++ = 0xFFFF;
0410 *pos++ = 0x8000;
0411 *pos++ = 0x0000;
0412 *pos++ = 0x0000;
0413 *pos++ = 0x0000;
0414 *pos++ = 0x0000;
0415 *pos++ = 0x0000;
0416 *pos++ = 0x0000;
0417 *pos++ = 0x0000;
0418 *pos++ = 0x0000;
0419
0420 if (putBufferToEvent) {
0421 auto data = std::make_unique<FEDRawDataCollection>();
0422 FEDRawData& fedRawData = data->FEDData((unsigned int)FEDNumbering::MINCSCTFFEDID);
0423 fedRawData.resize((pos - spDDUrecord) * sizeof(unsigned short));
0424 std::copy((unsigned char*)spDDUrecord, (unsigned char*)pos, fedRawData.data());
0425 FEDHeader csctfFEDHeader(fedRawData.data());
0426 csctfFEDHeader.set(fedRawData.data(), 0, e.id().event(), 0, FEDNumbering::MINCSCTFFEDID);
0427 FEDTrailer csctfFEDTrailer(fedRawData.data() + (fedRawData.size() - 8));
0428 csctfFEDTrailer.set(fedRawData.data() + (fedRawData.size() - 8),
0429 fedRawData.size() / 8,
0430 evf::compute_crc(fedRawData.data(), fedRawData.size()),
0431 0,
0432 0);
0433 e.put(std::move(data), "CSCTFRawData");
0434 }
0435
0436 if (file)
0437 fwrite(spDDUrecord, 2, pos - spDDUrecord, file);
0438 }
0439
0440 #include "FWCore/Framework/interface/MakerMacros.h"
0441 DEFINE_FWK_MODULE(CSCTFPacker);