00001 #include "EventFilter/CSCTFRawToDigi/interface/CSCTFPacker.h"
00002 #include "EventFilter/CSCTFRawToDigi/src/CSCTFEvent.h"
00003
00004 #include <strings.h>
00005 #include <errno.h>
00006 #include <iostream>
00007 #include <cstdio>
00008
00009 #include "DataFormats/L1CSCTrackFinder/interface/L1CSCTrackCollection.h"
00010 #include "DataFormats/L1CSCTrackFinder/interface/CSCTriggerContainer.h"
00011 #include "DataFormats/L1CSCTrackFinder/interface/TrackStub.h"
00012
00013 #include "DataFormats/Common/interface/Handle.h"
00014 #include "FWCore/Framework/interface/ESHandle.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigi.h"
00017 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiCollection.h"
00018 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00019 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00020 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00021 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00022 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00023 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00024 #include "FWCore/Utilities/interface/CRC16.h"
00025
00026
00027 CSCTFPacker::CSCTFPacker(const edm::ParameterSet &conf):edm::EDProducer(){
00028
00029 zeroSuppression = conf.getParameter<bool>("zeroSuppression");
00030 nTBINs = conf.getParameter<int> ("nTBINs");
00031 activeSectors = conf.getParameter<int> ("activeSectors");
00032
00033
00034 putBufferToEvent = conf.getParameter<bool>("putBufferToEvent");
00035 std::string outputFile = conf.getParameter<std::string>("outputFile");
00036 lctProducer = conf.getParameter<edm::InputTag>("lctProducer");
00037 mbProducer = conf.getParameter<edm::InputTag>("mbProducer");
00038 trackProducer = conf.getParameter<edm::InputTag>("trackProducer");
00039
00040
00041 swapME1strips = conf.getParameter<bool>("swapME1strips");
00042
00043 file = 0;
00044 if( outputFile.length() && (file = fopen(outputFile.c_str(),"wt"))==NULL )
00045 throw cms::Exception("OutputFile ")<<"CSCTFPacker: cannot open output file (errno="<<errno<<"). Try outputFile=\"\"";
00046
00047
00048 m_minBX = conf.getParameter<int>("MinBX");
00049 m_maxBX = conf.getParameter<int>("MaxBX");
00050
00051
00052
00053 central_lct_bx = (m_maxBX + m_minBX)/2;
00054
00055
00056 central_sp_bx = int(nTBINs/2);
00057
00058 produces<FEDRawDataCollection>("CSCTFRawData");
00059 }
00060
00061 CSCTFPacker::~CSCTFPacker(void){
00062 if( file ) fclose(file);
00063 }
00064
00065 void CSCTFPacker::produce(edm::Event& e, const edm::EventSetup& c){
00066 edm::Handle<CSCCorrelatedLCTDigiCollection> corrlcts;
00067 e.getByLabel(lctProducer.label(),lctProducer.instance(),corrlcts);
00068
00069 CSCSP_MEblock meDataRecord[12][7][5][9][2];
00070 bzero(&meDataRecord,sizeof(meDataRecord));
00071 CSCSPRecord meDataHeader[12][7];
00072 bzero(&meDataHeader,sizeof(meDataHeader));
00073
00074 for(CSCCorrelatedLCTDigiCollection::DigiRangeIterator csc=corrlcts.product()->begin(); csc!=corrlcts.product()->end(); csc++){
00075 CSCCorrelatedLCTDigiCollection::Range range1 = corrlcts.product()->get((*csc).first);
00076 int lctId=0;
00077 for(CSCCorrelatedLCTDigiCollection::const_iterator lct=range1.first; lct!=range1.second; lct++,lctId++){
00078 int station = (*csc).first.station()-1;
00079 int cscId = (*csc).first.triggerCscId()-1;
00080 int sector = (*csc).first.triggerSector()-1 + ( (*csc).first.endcap()==1 ? 0 : 6 );
00081 int subSector = CSCTriggerNumbering::triggerSubSectorFromLabels((*csc).first);
00082 int tbin = lct->getBX() - (central_lct_bx-central_sp_bx);
00083 if( tbin>6 || tbin<0 ){
00084 edm::LogError("CSCTFPacker|produce")<<" LCT's BX="<<tbin<<" is out of 0-6 window";
00085 continue;
00086 }
00087 int fpga = ( subSector ? subSector-1 : station+1 );
00089
00090
00091 if( sector<0 || sector>11 || station<0 || station>3 || cscId<0 || cscId>8 || lctId<0 || lctId>1){
00092 edm::LogInfo("CSCTFPacker: CSC digi are out of range: ")<<"sector="<<sector<<", station="<<station<<", cscId="<<cscId<<", lctId="<<lctId;
00093 continue;
00094 }
00095
00096 meDataRecord[sector][tbin][fpga][cscId][lctId].clct_pattern_number = lct->getPattern();
00097 meDataRecord[sector][tbin][fpga][cscId][lctId].quality_ = lct->getQuality();
00098 meDataRecord[sector][tbin][fpga][cscId][lctId].wire_group_id = lct->getKeyWG();
00099
00100 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() );
00101 meDataRecord[sector][tbin][fpga][cscId][lctId].csc_id = (*csc).first.triggerCscId();
00102 meDataRecord[sector][tbin][fpga][cscId][lctId].left_right = lct->getBend();
00103 meDataRecord[sector][tbin][fpga][cscId][lctId].bx0_ = 0;
00104 meDataRecord[sector][tbin][fpga][cscId][lctId].bc0_ = 0;
00105
00106 meDataRecord[sector][tbin][fpga][cscId][lctId].me_bxn = 0;
00107 meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_er1 = 0;
00108 meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_dv1 = 0;
00109 meDataRecord[sector][tbin][fpga][cscId][lctId].aligment_fifo_full = 0;
00110
00111 meDataRecord[sector][tbin][fpga][cscId][lctId].link_id = lct->getMPCLink();
00112 meDataRecord[sector][tbin][fpga][cscId][lctId].mpc_id = 0;
00113 meDataRecord[sector][tbin][fpga][cscId][lctId].err_prop_cnt = 0;
00114 meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_er2 = 0;
00115 meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_dv2 = 0;
00116 meDataRecord[sector][tbin][fpga][cscId][lctId].aligment_fifo_empty = 0;
00117
00118 if( lct->isValid() ){
00119 switch( (meDataHeader[sector][tbin].vp_bits>>(fpga*3)) & 0x7 ){
00120 case 0x0: meDataHeader[sector][tbin].vp_bits |= (0x1 << (fpga*3)); break;
00121 case 0x1: meDataHeader[sector][tbin].vp_bits |= (0x3 << (fpga*3)); break;
00122 case 0x3: meDataHeader[sector][tbin].vp_bits |= (0x7 << (fpga*3)); break;
00123 default :
00124 edm::LogInfo("CSCTFPacker: more than 3 LCTs from a single MPC in one BX!!!");
00125 continue;
00126 break;
00127 }
00128 meDataRecord[sector][tbin][fpga][cscId][lctId].valid_pattern = 1;
00129 }
00130 meDataHeader[sector][tbin].vq_a = 0;
00131 meDataHeader[sector][tbin].vq_b = 0;
00132 meDataHeader[sector][tbin].se_bits = 0;
00133 meDataHeader[sector][tbin].sm_bits = 0;
00134 meDataHeader[sector][tbin].af_bits = 0;
00135 meDataHeader[sector][tbin].bx_bits = 0;
00136
00137 meDataHeader[sector][tbin].spare_1 = 0;
00138 }
00139 }
00140
00141 CSCSP_MBblock mbDataRecord[12][2][7];
00142 bzero(&mbDataRecord,sizeof(mbDataRecord));
00143 edm::Handle< CSCTriggerContainer<csctf::TrackStub> > barrelStubs;
00144 if( mbProducer.label() != "null" ){
00145 e.getByLabel(mbProducer.label(),mbProducer.instance(),barrelStubs);
00146 if( barrelStubs.isValid() ){
00147 std::vector<csctf::TrackStub> stubs = barrelStubs.product()->get();
00148 for(std::vector<csctf::TrackStub>::const_iterator dt=stubs.begin(); dt!=stubs.end(); dt++){
00149 int sector = dt->sector()-1 + ( dt->endcap()==1 ? 0 : 6 );
00150 int subSector = dt->subsector()-1;
00151 int tbin = dt->getBX() - (central_lct_bx-central_sp_bx);
00152 if( tbin<0 || tbin>6 || sector<0 || sector>11 || subSector<0 || subSector>11 ){
00153 edm::LogInfo("CSCTFPacker: CSC DT digi are out of range: ")<<" sector="<<sector<<" subSector="<<subSector<<" tbin="<<tbin;
00154 continue;
00155 }
00156 mbDataRecord[sector][subSector][tbin].quality_ = dt->getQuality();
00157 mbDataRecord[sector][subSector][tbin].phi_bend_ = dt->getBend();
00158 mbDataRecord[sector][subSector][tbin].flag_ = dt->getStrip();
00159 mbDataRecord[sector][subSector][tbin].cal_ = dt->getKeyWG();
00160 mbDataRecord[sector][subSector][tbin].phi_ = dt->phiPacked();
00161 mbDataRecord[sector][subSector][tbin].bxn1_ =(dt->getBX0()>>1)&0x1;
00162 mbDataRecord[sector][subSector][tbin].bxn0_ = dt->getBX0()&0x1;
00163 mbDataRecord[sector][subSector][tbin].bc0_ = dt->getPattern();
00164 mbDataRecord[sector][subSector][tbin].mb_bxn_ = dt->getCSCID();
00165 switch(subSector){
00166 case 0: meDataHeader[sector][tbin].vq_a = 1; break;
00167 case 1: meDataHeader[sector][tbin].vq_b = 1; break;
00168 default: edm::LogInfo("CSCTFPacker: subSector=")<<subSector; break;
00169 }
00170 mbDataRecord[sector][subSector][tbin].id_ = dt->getMPCLink();
00171 }
00172 }
00173 }
00174
00175 CSCSP_SPblock spDataRecord[12][7][3];
00176 bzero(&spDataRecord,sizeof(spDataRecord));
00177 int nTrk[12][7];
00178 bzero(&nTrk,sizeof(nTrk));
00179
00180 edm::Handle<L1CSCTrackCollection> tracks;
00181 if( trackProducer.label() != "null" ){
00182 e.getByLabel(trackProducer.label(),trackProducer.instance(),tracks);
00183
00184 for(L1CSCTrackCollection::const_iterator trk=tracks->begin(); trk!=tracks->end(); trk++){
00185 int sector = 6*(trk->first.endcap()-1)+trk->first.sector()-1;
00186 int tbin = trk->first.BX() + central_sp_bx;
00187
00188 if( tbin>6 || tbin<0 ){
00189 edm::LogError("CSCTFPacker|analyze")<<" Track's BX="<<tbin<<" is out of 0-6 window";
00190 continue;
00191 }
00192 if( sector<0 || sector>11 ){
00193 edm::LogError("CSCTFPacker|analyze")<<" Track's sector="<<sector<<" is out of range";
00194 continue;
00195 }
00196 spDataRecord[sector][tbin][nTrk[sector][tbin]].phi_ = trk->first.localPhi();
00197 spDataRecord[sector][tbin][nTrk[sector][tbin]].sign_ =(trk->first.ptLUTAddress()>>20)&0x1;
00198 spDataRecord[sector][tbin][nTrk[sector][tbin]].front_rear = trk->first.front_rear();
00199 spDataRecord[sector][tbin][nTrk[sector][tbin]].charge_ = trk->first.charge_packed();
00200 spDataRecord[sector][tbin][nTrk[sector][tbin]].eta_ = trk->first.eta_packed();
00201
00202 spDataRecord[sector][tbin][nTrk[sector][tbin]].halo_ = trk->first.finehalo_packed();
00203 spDataRecord[sector][tbin][nTrk[sector][tbin]].se = 0;
00204 spDataRecord[sector][tbin][nTrk[sector][tbin]].deltaPhi12_= trk->first.ptLUTAddress()&0xFF;
00205 spDataRecord[sector][tbin][nTrk[sector][tbin]].deltaPhi23_=(trk->first.ptLUTAddress()>>8)&0xF;
00206 spDataRecord[sector][tbin][nTrk[sector][tbin]].bxn0_ = 0;
00207 spDataRecord[sector][tbin][nTrk[sector][tbin]].bc0_ = 0;
00208
00209 spDataRecord[sector][tbin][nTrk[sector][tbin]].me1_id = trk->first.me1ID();
00210 spDataRecord[sector][tbin][nTrk[sector][tbin]].me2_id = trk->first.me2ID();
00211 spDataRecord[sector][tbin][nTrk[sector][tbin]].me3_id = trk->first.me3ID();
00212 spDataRecord[sector][tbin][nTrk[sector][tbin]].me4_id = trk->first.me4ID();
00213 spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_id = trk->first.mb1ID();
00214 spDataRecord[sector][tbin][nTrk[sector][tbin]].ms_id = 0;
00215
00216
00217 spDataRecord[sector][tbin][nTrk[sector][tbin]].me1_tbin = trk->first.me1Tbin();
00218 spDataRecord[sector][tbin][nTrk[sector][tbin]].me2_tbin = trk->first.me2Tbin();
00219 spDataRecord[sector][tbin][nTrk[sector][tbin]].me3_tbin = trk->first.me3Tbin();
00220 spDataRecord[sector][tbin][nTrk[sector][tbin]].me4_tbin = trk->first.me4Tbin();
00221 spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_tbin = trk->first.mb1Tbin();
00222
00223 if( trk->first.mb1ID() ){
00224 int subSector = (trk->first.mb1ID() - 1)%2;
00225 int MBtbin = tbin - spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_tbin;
00226 if( subSector<0 || subSector>1 || MBtbin<0 || MBtbin>7 || !mbDataRecord[sector][subSector][MBtbin].id_ )
00227 spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_id = ( subSector ? 6 : 5 );
00228 }
00229 spDataRecord[sector][tbin][nTrk[sector][tbin]].id_ = nTrk[sector][tbin]+1;
00230
00231 nTrk[sector][tbin]++;
00232 switch(nTrk[sector][tbin]){
00233 case 1: meDataHeader[sector][tbin].mode1 = (trk->first.ptLUTAddress()>>16)&0xF; break;
00234 case 2: meDataHeader[sector][tbin].mode2 = (trk->first.ptLUTAddress()>>16)&0xF; break;
00235 case 3: meDataHeader[sector][tbin].mode3 = (trk->first.ptLUTAddress()>>16)&0xF; break;
00236 default:
00237 edm::LogInfo("More than 3 tracks from one SP in the BX");
00238 continue;
00239 break;
00240 }
00241 }
00242 }
00243
00244 CSCSPHeader header;
00245 bzero(&header,sizeof(header));
00246
00247 header.header_mark_1 = 0x9;
00248 header.header_mark_2 = 0x9;
00249 header.header_mark_3 = 0x9;
00250 header.header_mark_4 = 0x9;
00251
00252 header.header_mark_5 = 0xA;
00253 header.header_mark_6 = 0xA;
00254 header.header_mark_7 = 0xA;
00255 header.header_mark_8 = 0xA;
00256
00257 header.csr_dfc = nTBINs;
00258 header.csr_dfc |= ( zeroSuppression ? 0x8 : 0x0 );
00259 header.csr_dfc |= 0x7F0;
00260 header.skip = 0;
00261 header.sp_ersv = 2;
00262
00263 CSCSPCounters counters;
00264 bzero(&counters,sizeof(counters));
00265
00266 CSCSPTrailer trailer;
00267 bzero(&trailer,sizeof(trailer));
00268
00269 trailer.trailer_mark_1 = 0xF;
00270 trailer.trailer_mark_2 = 0xF;
00271 trailer.trailer_mark_3 = 0x7;
00272 trailer.trailer_mark_4 = 0xF;
00273 trailer.trailer_mark_5 = 0xF;
00274 trailer.trailer_mark_6 = 0xF;
00275 trailer.trailer_mark_7 = 0xE;
00276 trailer.trailer_mark_8 = 0xE;
00277 trailer.trailer_mark_9 = 0xE;
00278 trailer.trailer_mark_10= 0xE;
00279
00280 unsigned short spDDUrecord[700*12], *pos=spDDUrecord;
00281 bzero(&spDDUrecord,sizeof(spDDUrecord));
00282 int eventNumber = e.id().event();
00283 *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0xFFFF&eventNumber; *pos++ = 0x5000|(eventNumber>>16);
00284 *pos++ = 0x0000; *pos++ = 0x8000; *pos++ = 0x0001; *pos++ = 0x8000;
00285 *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000;
00286
00287 for(int sector=0; sector<12; sector++){
00288 if( !(activeSectors & (1<<sector)) ) continue;
00289 header.sp_trigger_sector = sector+1;
00290 memcpy(pos,&header,16);
00291 pos+=8;
00292 memcpy(pos,&counters,8);
00293 pos+=4;
00294
00295 for(int tbin=0; tbin<nTBINs; tbin++){
00296 memcpy(pos,&meDataHeader[sector][tbin],16);
00297 pos+=8;
00298 for(int fpga=0; fpga<5; fpga++){
00299 int nLCTs=0;
00300 for(int link=0; link<3; link++){
00301 for(int cscId=0; cscId<9; cscId++)
00302 for(int lctId=0; lctId<2; lctId++)
00303
00304 if( meDataRecord[sector][tbin][fpga][cscId][lctId].valid_pattern
00305 && meDataRecord[sector][tbin][fpga][cscId][lctId].link_id==link+1 ){
00306 memcpy(pos,&meDataRecord[sector][tbin][fpga][cscId][lctId],8);
00307 pos+=4;
00308 nLCTs++;
00309 }
00310 }
00311 if( !zeroSuppression ) pos += 4*(3-nLCTs);
00312 }
00313 for(int subSector=0; subSector<2; subSector++)
00314 if( !zeroSuppression || (subSector==0 && meDataHeader[sector][tbin].vq_a) || (subSector==1 && meDataHeader[sector][tbin].vq_b) ){
00315 memcpy(pos,&mbDataRecord[sector][subSector][tbin],8);
00316 pos+=4;
00317 }
00318 for(int trk=0; trk<3; trk++){
00319 if( !zeroSuppression || spDataRecord[sector][tbin][trk].id_ ){
00320 memcpy(pos,&spDataRecord[sector][tbin][trk],8);
00321 pos+=4;
00322 }
00323 }
00324 }
00325 memcpy(pos,&trailer,16);
00326 pos+=8;
00327 }
00328
00329 *pos++ = 0x8000; *pos++ = 0x8000; *pos++ = 0xFFFF; *pos++ = 0x8000;
00330 *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000;
00331 *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000; *pos++ = 0x0000;
00332
00333 if( putBufferToEvent ){
00334 std::auto_ptr<FEDRawDataCollection> data(new FEDRawDataCollection);
00335 FEDRawData& fedRawData = data->FEDData((unsigned int)FEDNumbering::MINCSCTFFEDID);
00336 fedRawData.resize((pos-spDDUrecord)*sizeof(unsigned short));
00337 std::copy((unsigned char*)spDDUrecord,(unsigned char*)pos,fedRawData.data());
00338 FEDHeader csctfFEDHeader (fedRawData.data());
00339 csctfFEDHeader.set(fedRawData.data(), 0, e.id().event(), 0, FEDNumbering::MINCSCTFFEDID);
00340 FEDTrailer csctfFEDTrailer(fedRawData.data()+(fedRawData.size()-8));
00341 csctfFEDTrailer.set(fedRawData.data()+(fedRawData.size()-8), fedRawData.size()/8, evf::compute_crc(fedRawData.data(),fedRawData.size()), 0, 0);
00342 e.put(data,"CSCTFRawData");
00343 }
00344
00345 if(file) fwrite(spDDUrecord,2,pos-spDDUrecord,file);
00346 }