00001
00002 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00003 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBData.h"
00004 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBTimeSlice.h"
00005 #include "EventFilter/CSCRawToDigi/interface/CSCBadCFEBTimeSlice.h"
00006 #include "DataFormats/CSCDigi/interface/CSCStripDigi.h"
00007 #include "DataFormats/CSCDigi/interface/CSCCFEBStatusDigi.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include <cassert>
00010
00011 CSCCFEBData::CSCCFEBData(unsigned number, unsigned short * buf)
00012 : theSize(0), boardNumber_(number), theNumberOfSamples(0) {
00013
00014
00015 unsigned pos = 0;
00016
00017 unsigned maxSamples = 8;
00018 theSliceStarts.reserve(8);
00019 while(theNumberOfSamples < maxSamples) {
00020
00021 CSCBadCFEBTimeSlice * badSlice
00022 = reinterpret_cast<CSCBadCFEBTimeSlice *>(buf+pos);
00023 if(badSlice->check()) {
00024
00025 theSliceStarts.push_back(std::pair<int, bool>(pos, false));
00026 pos += badSlice->sizeInWords();
00027
00028 bWords.push_back(badSlice->word(1).data());
00029 }
00030 else {
00031
00032 CSCCFEBTimeSlice * goodSlice
00033 = reinterpret_cast<CSCCFEBTimeSlice *>(buf+pos);
00034 if(goodSlice->check()) {
00035
00036 theSliceStarts.push_back(std::pair<int, bool>(pos, true));
00037
00038
00039 maxSamples = goodSlice->sixteenSamples() ? 16 : 8;
00040 pos += goodSlice->sizeInWords();
00041 }
00042 else {
00043 LogTrace ("CSCCFEBData|CSCRawToDigi")
00044 << "CORRUPT CFEB DATA slice " << theNumberOfSamples << std::hex << " "
00045 << *(buf+pos+3) << " " << *(buf+pos+2) << " " << *(buf+pos+1) << " "<< *(buf+pos);
00046
00047 theSliceStarts.push_back(std::pair<int, bool>(pos, false));
00048 pos += 100;
00049 }
00050 }
00051 ++theNumberOfSamples;
00052 }
00053 theSize = pos;
00054 memcpy(theData, buf, theSize*2);
00055 }
00056
00057
00058 CSCCFEBData::CSCCFEBData(unsigned number, bool sixteenSamples)
00059 : boardNumber_(number), theNumberOfSamples(sixteenSamples ? 16 : 8)
00060 {
00061 theSliceStarts.reserve(theNumberOfSamples);
00062
00063
00064 CSCCFEBSCAControllerWord scaWord;
00065 scaWord.ts_flag = sixteenSamples;
00066
00067
00068 CSCCFEBTimeSlice slice;
00069 slice.setControllerWord(scaWord);
00070
00071 for(unsigned i = 0; i < theNumberOfSamples; ++i)
00072 {
00073 unsigned short * pos = theData+i*100;
00074 memcpy(pos, &slice, 200);
00075 theSliceStarts.push_back(std::pair<int,bool>(i*100, true));
00076 }
00077 theSize = theNumberOfSamples*100;
00078 }
00079
00080 void CSCCFEBData::add(const CSCStripDigi & digi, int layer)
00081 {
00082 std::vector<int> scaCounts = digi.getADCCounts();
00083 for(unsigned itime = 0; itime < theNumberOfSamples; ++itime)
00084 {
00085 unsigned channel = (digi.getStrip()-1) % 16 + 1;
00086 unsigned value = scaCounts[itime] & 0xFFF;
00087
00088 const CSCCFEBTimeSlice * slice = timeSlice(itime);
00089 assert(slice != 0);
00090 slice->timeSample(layer, channel)->adcCounts = value;
00092 ((CSCCFEBTimeSlice *)slice)->setCRC();
00093 }
00094 }
00095
00096 const CSCCFEBTimeSlice * CSCCFEBData::timeSlice(unsigned i) const
00097 {
00098 const CSCCFEBTimeSlice * result;
00099 assert(i < theNumberOfSamples);
00100 std::pair<int,bool> start = theSliceStarts[i];
00101
00102 if(!start.second)
00103 {
00104 result = 0;
00105 }
00106 else
00107 {
00108 result = reinterpret_cast<const CSCCFEBTimeSlice *>(theData+start.first);
00109 }
00110 return result;
00111 }
00112
00113
00114 unsigned CSCCFEBData::adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const
00115 {
00116 unsigned result = 0;
00117 const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00118
00119 if(slice) result = slice->timeSample(layer, channel)->adcCounts;
00120 return result;
00121 }
00122 unsigned CSCCFEBData::adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const
00123 {
00124 unsigned result = 0;
00125 const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00126
00127 if(slice) result = slice->timeSample(layer, channel)->adcOverflow;
00128 return result;
00129 }
00130
00131 unsigned CSCCFEBData::controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const
00132 {
00133
00134
00135
00136
00137
00138
00139
00140 unsigned result = 0;
00141 const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00142
00143 if(slice) result = slice->timeSample( (ugchan-1)*6+uglay-1 )->controllerData;
00144 return result;
00145 }
00146
00147 unsigned CSCCFEBData::overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const
00148 {
00149 unsigned result = 0;
00150 const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00151
00152 if(slice) result = slice->timeSample(layer, channel)->overlappedSampleFlag;
00153 return result;
00154 }
00155 unsigned CSCCFEBData::errorstat(unsigned layer, unsigned channel, unsigned timeBin) const
00156 {
00157 unsigned result = 0;
00158 const CSCCFEBTimeSlice * slice = timeSlice(timeBin);
00159
00160 if(slice) result = slice->timeSample(layer, channel)->errorstat;
00161 return result;
00162 }
00163
00164
00165 CSCCFEBStatusDigi CSCCFEBData::statusDigi() const
00166 {
00170
00171 std::vector<uint16_t> crcWords(nTimeSamples());
00172 std::vector<uint16_t> contrWords(nTimeSamples());
00173
00174 if (nTimeSamples()==0)
00175 {
00176 LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
00177 }
00178 else
00179 {
00180 for(unsigned itime = 0; itime < nTimeSamples(); ++itime) {
00181 const CSCCFEBTimeSlice * slice = timeSlice(itime);
00182
00183 if (slice) crcWords[itime] = slice->get_crc();
00184 if (slice)
00185 {
00186 int layer=1;
00187 for(unsigned i = 0; i < 16; ++i)
00188 {
00189 contrWords[itime] |= slice->timeSample(i*6+layer-1)->controllerData << i;
00190 }
00191 }
00192
00193 }
00194 }
00195
00196 CSCCFEBStatusDigi result(boardNumber_+1, crcWords, contrWords, bWords);
00197 return result;
00198 }
00199
00200
00201
00202 void CSCCFEBData::digis(uint32_t idlayer, std::vector<CSCStripDigi> & result )
00203 {
00204
00205
00206
00207 LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples in CSCCFEBData::digis = " << nTimeSamples();
00208 if (nTimeSamples()==0) {
00209 LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
00210 return;
00211 }
00212
00213 result.reserve(16);
00214
00215 std::vector<int> sca(nTimeSamples());
00216 std::vector<uint16_t> overflow(nTimeSamples());
00217 std::vector<uint16_t> overlap(nTimeSamples());
00218 std::vector<uint16_t> errorfl(nTimeSamples());
00219
00220 bool me1a = (CSCDetId::station(idlayer)==1) && (CSCDetId::ring(idlayer)==4);
00221 bool zplus = (CSCDetId::endcap(idlayer) == 1);
00222 bool me1b = (CSCDetId::station(idlayer)==1) && (CSCDetId::ring(idlayer)==1);
00223
00224 unsigned layer = CSCDetId::layer(idlayer);
00225
00226 std::vector<uint16_t> l1a_phase(nTimeSamples());
00227 for(unsigned itime = 0; itime < nTimeSamples(); ++itime) {
00228 l1a_phase[itime] = controllerData(layer, 13, itime);
00229 LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " l1a_phase = " << controllerData(layer, 13, itime);
00230 LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " lct_phase = " << controllerData(layer, 14, itime);
00231 LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime+1 << " # samples = " << controllerData(layer, 16, itime);
00232 };
00233
00234 for(unsigned ichannel = 1; ichannel <= 16; ++ichannel)
00235 {
00236
00237
00238
00239
00240
00241
00242
00243 for(unsigned itime = 0; itime < nTimeSamples(); ++itime)
00244 {
00245 const CSCCFEBTimeSlice * slice = timeSlice(itime);
00246 if (slice)
00247 {
00248 CSCCFEBDataWord * word;
00249 word = slice->timeSample(layer, ichannel);
00250 if (word)
00251 {
00252 sca[itime] = word->adcCounts;
00253 overflow[itime] = word->adcOverflow;
00254 overlap[itime] = word->overlappedSampleFlag;
00255 errorfl[itime] = word->errorstat;
00256
00257
00258
00259
00260 overlap[itime] = (( l1a_phase[itime] & 0x1 ) << 8 ) | ( word->overlappedSampleFlag & 0x1 );
00261 }
00262 }
00263 }
00264 if (sca.empty())
00265 {
00266 LogTrace("CSCCFEBData|CSCRawToDigi") << "ADC counts empty - CFEB data corrupt?";
00267 break;
00268 }
00269 int strip = ichannel + 16*boardNumber_;
00270 if ( me1a ) strip = strip%64;
00271 if ( me1a && zplus ) { strip = 17-strip; }
00272 if ( me1b && !zplus) { strip = 65 - strip;}
00273 result.push_back(CSCStripDigi(strip, sca, overflow, overlap, errorfl));
00274 }
00275 }
00276
00277
00278
00279 std::vector<CSCStripDigi> CSCCFEBData::digis(unsigned idlayer)
00280 {
00281
00282 std::vector<CSCStripDigi> result;
00283 uint32_t layer= idlayer;
00284 digis(layer, result);
00285 return result;
00286 }
00287
00288
00289
00290 bool CSCCFEBData::check() const
00291 {
00292 bool result = true;
00293 for(unsigned i = 0; i < theNumberOfSamples; ++i)
00294 {
00295 const CSCCFEBTimeSlice * slice = timeSlice(i);
00296 if(slice==0 || !timeSlice(i)->check()) result = false;
00297 }
00298 return result;
00299 }
00300
00301 std::ostream & operator<<(std::ostream & os, const CSCCFEBData & data)
00302 {
00303 os << "printing CFEB data sample by sample " << std::endl;
00304 for(unsigned ilayer = 1; ilayer <= 6; ++ilayer)
00305 {
00306 for(unsigned channel = 1; channel <= 16; ++channel)
00307 {
00308 unsigned strip = channel + data.boardNumber_*16;
00309 os << "Strip " << strip << " ";
00310 for(unsigned timeBin = 0; timeBin < data.nTimeSamples(); ++timeBin)
00311 {
00312 os << data.adcCounts(ilayer, channel, timeBin) << " " ;
00313 }
00314 os << std::endl;
00315 }
00316 }
00317 return os;
00318 }
00319
00320 std::vector < std::vector<CSCStripDigi> > CSCCFEBData::stripDigis()
00321 {
00322 std::vector < std::vector<CSCStripDigi> > result;
00323 for (int layer = 1; layer <= 6; ++layer)
00324 {
00325 result.push_back(digis(layer));
00326 }
00327 return result;
00328 }
00329