40 if( outputFile.length() && (file = fopen(outputFile.c_str(),
"wt"))==
nullptr )
41 throw cms::Exception(
"OutputFile ")<<
"CSCTFPacker: cannot open output file (errno="<<errno<<
"). Try outputFile=\"\"";
54 produces<FEDRawDataCollection>(
"CSCTFRawData");
57 CSCCDC_Tok = consumes<CSCCorrelatedLCTDigiCollection>(
edm::InputTag(lctProducer.label(),lctProducer.instance()) );
72 bzero(&meDataRecord,
sizeof(meDataRecord));
74 bzero(&meDataHeader,
sizeof(meDataHeader));
80 int station = (*csc).first.station()-1;
81 int cscId = (*csc).first.triggerCscId()-1;
82 int sector = (*csc).first.triggerSector()-1 + ( (*csc).first.endcap()==1 ? 0 : 6 );
85 if( tbin>6 || tbin<0 ){
86 edm::LogError(
"CSCTFPacker|produce")<<
" LCT's BX="<<tbin<<
" is out of 0-6 window";
89 int fpga = ( subSector ? subSector-1 : station+1 );
93 if( sector<0 || sector>11 || station<0 || station>3 || cscId<0 || cscId>8 || lctId<0 || lctId>1){
94 edm::LogInfo(
"CSCTFPacker: CSC digi are out of range: ")<<
"sector="<<sector<<
", station="<<station<<
", cscId="<<cscId<<
", lctId="<<lctId;
99 meDataRecord[sector][tbin][fpga][cscId][lctId].
quality_ = lct->getQuality();
100 meDataRecord[sector][tbin][fpga][cscId][lctId].
wire_group_id = lct->getKeyWG();
102 meDataRecord[sector][tbin][fpga][cscId][lctId].
clct_pattern_id = (
swapME1strips && cscId<3 && station==0 && (*csc).first.endcap()==2 && lct->getStrip()<65 ? 65 - lct->getStrip() : lct->getStrip() );
103 meDataRecord[sector][tbin][fpga][cscId][lctId].
csc_id = (*csc).first.triggerCscId();
104 meDataRecord[sector][tbin][fpga][cscId][lctId].
left_right = lct->getBend();
105 meDataRecord[sector][tbin][fpga][cscId][lctId].
bx0_ = 0;
106 meDataRecord[sector][tbin][fpga][cscId][lctId].
bc0_ = 0;
108 meDataRecord[sector][tbin][fpga][cscId][lctId].
me_bxn = 0;
113 meDataRecord[sector][tbin][fpga][cscId][lctId].
link_id = lct->getMPCLink();
114 meDataRecord[sector][tbin][fpga][cscId][lctId].
mpc_id = 0;
115 meDataRecord[sector][tbin][fpga][cscId][lctId].
err_prop_cnt = 0;
120 if( lct->isValid() ){
121 switch( (meDataHeader[sector][tbin].vp_bits>>(fpga*3)) & 0x7 ){
122 case 0x0: meDataHeader[sector][tbin].
vp_bits |= (0x1 << (fpga*3));
break;
123 case 0x1: meDataHeader[sector][tbin].
vp_bits |= (0x3 << (fpga*3));
break;
124 case 0x3: meDataHeader[sector][tbin].
vp_bits |= (0x7 << (fpga*3));
break;
126 edm::LogInfo(
"CSCTFPacker: more than 3 LCTs from a single MPC in one BX!!!");
130 meDataRecord[sector][tbin][fpga][cscId][lctId].
valid_pattern = 1;
132 meDataHeader[sector][tbin].
vq_a = 0;
133 meDataHeader[sector][tbin].
vq_b = 0;
134 meDataHeader[sector][tbin].
se_bits = 0;
135 meDataHeader[sector][tbin].
sm_bits = 0;
136 meDataHeader[sector][tbin].
af_bits = 0;
137 meDataHeader[sector][tbin].
bx_bits = 0;
139 meDataHeader[sector][tbin].
spare_1 = 0;
144 bzero(&mbDataRecord,
sizeof(mbDataRecord));
149 std::vector<csctf::TrackStub> stubs = barrelStubs.
product()->get();
150 for(std::vector<csctf::TrackStub>::const_iterator
dt=stubs.begin();
dt!=stubs.end();
dt++){
151 int sector =
dt->sector()-1 + (
dt->endcap()==1 ? 0 : 6 );
152 int subSector =
dt->subsector()-1;
154 if( tbin<0 || tbin>6 || sector<0 || sector>11 || subSector<0 || subSector>11 ){
155 edm::LogInfo(
"CSCTFPacker: CSC DT digi are out of range: ")<<
" sector="<<sector<<
" subSector="<<subSector<<
" tbin="<<tbin;
158 mbDataRecord[sector][subSector][tbin].
quality_ =
dt->getQuality();
159 mbDataRecord[sector][subSector][tbin].
phi_bend_ =
dt->getBend();
160 mbDataRecord[sector][subSector][tbin].
flag_ =
dt->getStrip();
161 mbDataRecord[sector][subSector][tbin].
cal_ =
dt->getKeyWG();
162 mbDataRecord[sector][subSector][tbin].
phi_ =
dt->phiPacked();
163 mbDataRecord[sector][subSector][tbin].
bxn1_ =(
dt->getBX0()>>1)&0
x1;
164 mbDataRecord[sector][subSector][tbin].
bxn0_ =
dt->getBX0()&0x1;
165 mbDataRecord[sector][subSector][tbin].
bc0_ =
dt->getPattern();
166 mbDataRecord[sector][subSector][tbin].
mb_bxn_ =
dt->getCSCID();
168 case 0: meDataHeader[sector][tbin].
vq_a = 1;
break;
169 case 1: meDataHeader[sector][tbin].
vq_b = 1;
break;
170 default:
edm::LogInfo(
"CSCTFPacker: subSector=")<<subSector;
break;
172 mbDataRecord[sector][subSector][tbin].
id_ =
dt->getMPCLink();
178 bzero(&spDataRecord,
sizeof(spDataRecord));
180 bzero(&nTrk,
sizeof(nTrk));
186 for(L1CSCTrackCollection::const_iterator trk=tracks->begin(); trk!=tracks->end(); trk++){
187 int sector = 6*(trk->first.endcap()-1)+trk->first.sector()-1;
190 if( tbin>6 || tbin<0 ){
191 edm::LogError(
"CSCTFPacker|analyze")<<
" Track's BX="<<tbin<<
" is out of 0-6 window";
194 if( sector<0 || sector>11 ){
195 edm::LogError(
"CSCTFPacker|analyze")<<
" Track's sector="<<sector<<
" is out of range";
198 spDataRecord[sector][tbin][nTrk[sector][tbin]].
phi_ = trk->first.localPhi();
199 spDataRecord[sector][tbin][nTrk[sector][tbin]].
sign_ =(trk->first.ptLUTAddress()>>20)&0
x1;
200 spDataRecord[sector][tbin][nTrk[sector][tbin]].
front_rear = trk->first.front_rear();
201 spDataRecord[sector][tbin][nTrk[sector][tbin]].
charge_ = trk->first.charge_packed();
202 spDataRecord[sector][tbin][nTrk[sector][tbin]].
eta_ = trk->first.eta_packed();
204 spDataRecord[sector][tbin][nTrk[sector][tbin]].
halo_ = trk->first.finehalo_packed();
205 spDataRecord[sector][tbin][nTrk[sector][tbin]].
se = 0;
206 spDataRecord[sector][tbin][nTrk[sector][tbin]].
deltaPhi12_= trk->first.ptLUTAddress()&0xFF;
207 spDataRecord[sector][tbin][nTrk[sector][tbin]].
deltaPhi23_=(trk->first.ptLUTAddress()>>8)&0xF;
208 spDataRecord[sector][tbin][nTrk[sector][tbin]].
bxn0_ = 0;
209 spDataRecord[sector][tbin][nTrk[sector][tbin]].
bc0_ = 0;
211 spDataRecord[sector][tbin][nTrk[sector][tbin]].
me1_id = trk->first.me1ID();
212 spDataRecord[sector][tbin][nTrk[sector][tbin]].
me2_id = trk->first.me2ID();
213 spDataRecord[sector][tbin][nTrk[sector][tbin]].
me3_id = trk->first.me3ID();
214 spDataRecord[sector][tbin][nTrk[sector][tbin]].
me4_id = trk->first.me4ID();
215 spDataRecord[sector][tbin][nTrk[sector][tbin]].
mb_id = trk->first.mb1ID();
216 spDataRecord[sector][tbin][nTrk[sector][tbin]].
ms_id = 0;
219 spDataRecord[sector][tbin][nTrk[sector][tbin]].
me1_tbin = trk->first.me1Tbin();
220 spDataRecord[sector][tbin][nTrk[sector][tbin]].
me2_tbin = trk->first.me2Tbin();
221 spDataRecord[sector][tbin][nTrk[sector][tbin]].
me3_tbin = trk->first.me3Tbin();
222 spDataRecord[sector][tbin][nTrk[sector][tbin]].
me4_tbin = trk->first.me4Tbin();
223 spDataRecord[sector][tbin][nTrk[sector][tbin]].
mb_tbin = trk->first.mb1Tbin();
225 if( trk->first.mb1ID() ){
226 int subSector = (trk->first.mb1ID() - 1)%2;
227 int MBtbin = tbin - spDataRecord[sector][tbin][nTrk[sector][tbin]].
mb_tbin;
228 if( subSector<0 || subSector>1 || MBtbin<0 || MBtbin>7 || !mbDataRecord[sector][subSector][MBtbin].id_ )
229 spDataRecord[sector][tbin][nTrk[sector][tbin]].
mb_id = ( subSector ? 6 : 5 );
231 spDataRecord[sector][tbin][nTrk[sector][tbin]].
id_ = nTrk[sector][tbin]+1;
233 nTrk[sector][tbin]++;
234 switch(nTrk[sector][tbin]){
235 case 1: meDataHeader[sector][tbin].
mode1 = (trk->first.ptLUTAddress()>>16)&0xF;
break;
236 case 2: meDataHeader[sector][tbin].
mode2 = (trk->first.ptLUTAddress()>>16)&0xF;
break;
237 case 3: meDataHeader[sector][tbin].
mode3 = (trk->first.ptLUTAddress()>>16)&0xF;
break;
239 edm::LogInfo(
"More than 3 tracks from one SP in the BX");
247 bzero(&header,
sizeof(header));
266 bzero(&counters,
sizeof(counters));
269 bzero(&trailer,
sizeof(trailer));
282 unsigned short spDDUrecord[700*12], *
pos=spDDUrecord;
283 bzero(&spDDUrecord,
sizeof(spDDUrecord));
284 int eventNumber = e.
id().
event();
285 *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0xFFFF&eventNumber; *pos++ = 0x5000|(eventNumber>>16);
286 *pos++ = 0x0000; *pos++ = 0x8000; *pos++ = 0x0001; *pos++ = 0x8000;
287 *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000;
289 for(
int sector=0; sector<12; sector++){
292 memcpy(pos,&header,16);
294 memcpy(pos,&counters,8);
297 for(
int tbin=0; tbin<
nTBINs; tbin++){
298 memcpy(pos,&meDataHeader[sector][tbin],16);
300 for(
int fpga=0; fpga<5; fpga++){
302 for(
int link=0; link<3; link++){
303 for(
int cscId=0; cscId<9; cscId++)
304 for(
int lctId=0; lctId<2; lctId++)
306 if( meDataRecord[sector][tbin][fpga][cscId][lctId].valid_pattern
307 && meDataRecord[sector][tbin][fpga][cscId][lctId].link_id==link+1 ){
308 memcpy(pos,&meDataRecord[sector][tbin][fpga][cscId][lctId],8);
315 for(
int subSector=0; subSector<2; subSector++)
316 if( !
zeroSuppression || (subSector==0 && meDataHeader[sector][tbin].vq_a) || (subSector==1 && meDataHeader[sector][tbin].
vq_b) ){
317 memcpy(pos,&mbDataRecord[sector][subSector][tbin],8);
320 for(
int trk=0; trk<3; trk++){
322 memcpy(pos,&spDataRecord[sector][tbin][trk],8);
327 memcpy(pos,&trailer,16);
331 *pos++ = 0x8000; *pos++ = 0x8000; *pos++ = 0xFFFF; *pos++ = 0x8000;
332 *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000;
333 *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000;
336 auto data = std::make_unique<FEDRawDataCollection>();
338 fedRawData.resize((pos-spDDUrecord)*
sizeof(
unsigned short));
339 std::copy((
unsigned char*)spDDUrecord,(
unsigned char*)pos,fedRawData.data());
340 FEDHeader csctfFEDHeader (fedRawData.data());
342 FEDTrailer csctfFEDTrailer(fedRawData.data()+(fedRawData.size()-8));
343 csctfFEDTrailer.
set(fedRawData.data()+(fedRawData.size()-8), fedRawData.size()/8,
evf::compute_crc(fedRawData.data(),fedRawData.size()), 0, 0);
347 if(
file) fwrite(spDDUrecord,2,pos-spDDUrecord,
file);
T getParameter(std::string const &) const
EventNumber_t event() const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
unsigned aligment_fifo_empty
bool getByToken(EDGetToken token, Handle< PROD > &result) const
unsigned clct_pattern_number
unsigned aligment_fifo_full
CSCTFPacker(const edm::ParameterSet &conf)
edm::EDGetTokenT< CSCTriggerContainer< csctf::TrackStub > > CSCTC_Tok
~CSCTFPacker(void) override
static void set(unsigned char *trailer, uint32_t lenght, uint16_t crc, uint8_t evt_stat, uint8_t tts, bool moreTrailers=false)
Set all fields in the trailer.
unsigned receiver_status_dv2
edm::InputTag trackProducer
unsigned receiver_status_dv1
unsigned short compute_crc(unsigned char *buffer, unsigned int bufSize)
void produce(edm::Event &e, const edm::EventSetup &c) override
unsigned receiver_status_er2
unsigned receiver_status_er1
unsigned short activeSectors
T const * product() const
edm::InputTag lctProducer
std::vector< DigiType >::const_iterator const_iterator
static int triggerSubSectorFromLabels(int station, int chamber)
edm::EDGetTokenT< CSCCorrelatedLCTDigiCollection > CSCCDC_Tok
char data[epos_bytes_allocation]
std::pair< const_iterator, const_iterator > Range
unsigned int valid_pattern
edm::EDGetTokenT< L1CSCTrackCollection > L1CSCTr_Tok