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