CMS 3D CMS Logo

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 
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         // "Readout" configuration
00026         zeroSuppression = conf.getParameter<bool>("zeroSuppression");
00027         nTBINs          = conf.getParameter<int> ("nTBINs");
00028         activeSectors   = conf.getParameter<int> ("activeSectors");
00029 
00030         // Configuration that controls CMSSW specific stuff
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         // Swap: if(swapME1strips && me1b && !zplus) strip = 65 - strip; // 1-64 -> 64-1 :
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         // BX window bounds in CMSSW:
00044         m_minBX = conf.getParameter<int>("MinBX"); //3
00045         m_maxBX = conf.getParameter<int>("MaxBX"); //9
00046 
00047         // Finds central LCT BX
00048         // assumes window is odd number of bins
00049         central_lct_bx = (m_maxBX + m_minBX)/2;
00050         // Find central SP BX
00051         // assumes window is odd number of bins
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]; // LCT in sector X, tbin Y, station Z, csc W, and lct I
00066         bzero(&meDataRecord,sizeof(meDataRecord));
00067         CSCSPRecord meDataHeader[12][7]; // Data Block Header for sector X and tbin Y
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); // Shift back to hardware BX window definition
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                         // If Det Id is within range
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; // dummy
00105                         meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_dv1 = 0; // dummy
00106                         meDataRecord[sector][tbin][fpga][cscId][lctId].aligment_fifo_full  = 0; // dummy
00107 
00108                         meDataRecord[sector][tbin][fpga][cscId][lctId].link_id             = lct->getMPCLink();
00109                         meDataRecord[sector][tbin][fpga][cscId][lctId].mpc_id              = 0; // Join with above?
00110                         meDataRecord[sector][tbin][fpga][cscId][lctId].err_prop_cnt        = 0; // dummy
00111                         meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_er2 = 0; // dummy
00112                         meDataRecord[sector][tbin][fpga][cscId][lctId].receiver_status_dv2 = 0; // dummy
00113                         meDataRecord[sector][tbin][fpga][cscId][lctId].aligment_fifo_empty = 0; // dummy
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; // for later use
00126                         }
00127                         meDataHeader[sector][tbin].vq_a = 0; // no digi yet?
00128                         meDataHeader[sector][tbin].vq_b = 0; // no digi yet?
00129                         meDataHeader[sector][tbin].se_bits = 0; // dummy
00130                         meDataHeader[sector][tbin].sm_bits = 0; // dummy
00131                         meDataHeader[sector][tbin].af_bits = 0; // dummy
00132                         meDataHeader[sector][tbin].bx_bits = 0;//(lct->getBX()&??<< (fpga*3));
00133 
00134                         meDataHeader[sector][tbin].spare_1 = 1; // for later use
00135                 }
00136         }
00137 
00138         CSCSP_SPblock spDataRecord[12][7][3]; // Up to 3 tracks in sector X and tbin Y
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; // Shift back to hardware BX window definition
00150 //std::cout<<"Track["<<nTrk[sector][tbin]<<"]  sector: "<<sector<<" tbin: "<<tbin<<std::endl;
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; // not necessary
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; // dummy
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; //dummy
00170                         spDataRecord[sector][tbin][nTrk[sector][tbin]].bc0_       = 0; //dummy
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; // don't care
00178 
00179                         spDataRecord[sector][tbin][nTrk[sector][tbin]].me1_tbin   = 0; // Unknown !
00180                         spDataRecord[sector][tbin][nTrk[sector][tbin]].me2_tbin   = 0; // Unknown !
00181                         spDataRecord[sector][tbin][nTrk[sector][tbin]].me3_tbin   = 0; // Unknown !
00182                         spDataRecord[sector][tbin][nTrk[sector][tbin]].me4_tbin   = 0; // Unknown !
00183                         spDataRecord[sector][tbin][nTrk[sector][tbin]].mb_tbin    = 0; // Unknown !
00184 
00185                         spDataRecord[sector][tbin][nTrk[sector][tbin]].id_ = nTrk[sector][tbin]+1; // for later use
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; // All FPGAs are active
00216         header.skip     = 0;
00217         header.sp_ersv  = 2; // Format version with block of counters
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; // max length
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                                                         // Only 3 LCT per BX from the same fpga are allowed (to be valid):
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 }

Generated on Tue Jun 9 17:34:27 2009 for CMSSW by  doxygen 1.5.4