CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/EventFilter/CSCTFRawToDigi/plugins/CSCTFPacker.cc

Go to the documentation of this file.
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         // "Readout" configuration
00029         zeroSuppression = conf.getParameter<bool>("zeroSuppression");
00030         nTBINs          = conf.getParameter<int> ("nTBINs");
00031         activeSectors   = conf.getParameter<int> ("activeSectors");
00032 
00033         // Configuration that controls CMSSW specific stuff
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         // Swap: if(swapME1strips && me1b && !zplus) strip = 65 - strip; // 1-64 -> 64-1 :
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         // BX window bounds in CMSSW:
00048         m_minBX = conf.getParameter<int>("MinBX"); //3
00049         m_maxBX = conf.getParameter<int>("MaxBX"); //9
00050 
00051         // Finds central LCT BX
00052         // assumes window is odd number of bins
00053         central_lct_bx = (m_maxBX + m_minBX)/2;
00054         // Find central SP BX
00055         // assumes window is odd number of bins
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]; // LCT in sector X, tbin Y, station Z, csc W, and lct I
00070         bzero(&meDataRecord,sizeof(meDataRecord));
00071         CSCSPRecord meDataHeader[12][7]; // Data Block Header for sector X and tbin Y
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); // Shift back to hardware BX window definition
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                         // If Det Id is within range
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; // dummy
00108                         meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_dv1 = 0; // dummy
00109                         meDataRecord[sector][tbin][fpga][cscId][lctId].aligment_fifo_full  = 0; // dummy
00110 
00111                         meDataRecord[sector][tbin][fpga][cscId][lctId].link_id             = lct->getMPCLink();
00112                         meDataRecord[sector][tbin][fpga][cscId][lctId].mpc_id              = 0; // Join with above?
00113                         meDataRecord[sector][tbin][fpga][cscId][lctId].err_prop_cnt        = 0; // dummy
00114                         meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_er2 = 0; // dummy
00115                         meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_dv2 = 0; // dummy
00116                         meDataRecord[sector][tbin][fpga][cscId][lctId].aligment_fifo_empty = 0; // dummy
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; // for later use
00129                         }
00130                         meDataHeader[sector][tbin].vq_a = 0; // no digi yet?
00131                         meDataHeader[sector][tbin].vq_b = 0; // no digi yet?
00132                         meDataHeader[sector][tbin].se_bits = 0; // dummy
00133                         meDataHeader[sector][tbin].sm_bits = 0; // dummy
00134                         meDataHeader[sector][tbin].af_bits = 0; // dummy
00135                         meDataHeader[sector][tbin].bx_bits = 0;//(lct->getBX()&??<< (fpga*3));
00136 
00137                         meDataHeader[sector][tbin].spare_1 = 0; // for later use
00138                 }
00139         }
00140 
00141         CSCSP_MBblock mbDataRecord[12][2][7]; // LCT in sector X, subsector Z, tbin Y
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); // Shift back to hardware BX window definition
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(); // for later use
00171                         }
00172                 }
00173         }
00174 
00175         CSCSP_SPblock spDataRecord[12][7][3]; // Up to 3 tracks in sector X and tbin Y
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; // Shift back to hardware BX window definition
00187 //std::cout<<"Track["<<nTrk[sector][tbin]<<"]  sector: "<<sector<<" tbin: "<<tbin<<std::endl;
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; // dummy
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; //dummy
00207                         spDataRecord[sector][tbin][nTrk[sector][tbin]].bc0_       = 0; //dummy
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; // don't care winner()
00215 
00216                         // Warning, digi copying was broken for <= CMSSW_3_8_x! The 5 lines of code below will give problems there:
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                         // As the MB stubs are not saved in simulation, we want to introduce an artificial ids
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; // for later use
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; // All FPGAs are active
00260         header.skip     = 0;
00261         header.sp_ersv  = 2; // Format version with block of counters
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; // max length
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                                                                 // Only 3 LCT per BX from the same fpga are allowed (to be valid):
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 }