00001 #include "EventFilter/CSCRawToDigi/interface/CSCALCTHeader.h"
00002 #include "EventFilter/CSCRawToDigi/interface/CSCDMBHeader.h"
00003 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00004 #include "EventFilter/CSCRawToDigi/src/bitset_append.h"
00005 #include "EventFilter/CSCRawToDigi/src/cscPackerCompare.h"
00006 #include <iomanip>
00007
00008 bool CSCALCTHeader::debug=false;
00009 short unsigned int CSCALCTHeader::firmwareVersion=2007;
00010
00011 CSCALCTHeader::CSCALCTHeader(int chamberType)
00012 : header2006(chamberType),
00013 header2007(chamberType)
00014 {
00015 if (firmwareVersion==2006)
00016 {
00017 memcpy(theOriginalBuffer, &header2006, header2006.sizeInWords()*2);
00018 }
00019 else if(firmwareVersion==2007)
00020 {
00021 memcpy(theOriginalBuffer, &header2007, header2007.sizeInWords()*2);
00022
00023 sizeInWords2007_ = header2007.sizeInWords() + header2007.lctBins*CSCALCT::sizeInWords()*2;
00024 theALCTs.resize(header2007.lctBins*2);
00025 }
00026 else
00027 {
00028 edm::LogError("CSCALCTHeader|CSCRawToDigi")
00029 <<"Cannot construct ALCT header: ALCT firmware version is bad/not defined!" << firmwareVersion;
00030 }
00031
00032 }
00033
00034 CSCALCTHeader::CSCALCTHeader(const unsigned short * buf) {
00039 constexpr unsigned short int collisionMaskWordcount[7] = { 8, 8,12,16,16,24,28};
00040 constexpr unsigned short int hotChannelMaskWordcount[7] = {18,18,24,36,36,48,60};
00041
00043 if (buf[0]==0xDB0A) {
00044 firmwareVersion=2007;
00045 }
00046 else if ( (buf[0]&0xF800)==0x6000 ) {
00047 firmwareVersion=2006;
00048 }
00049 else {
00050 edm::LogError("CSCALCTHeader|CSCRawToDigi") << "failed to determine ALCT firmware version!!";
00051 }
00052
00053 LogTrace("CSCALCTHeader|CSCRawToDigi") << "firmware version - " << firmwareVersion;
00054
00056 switch (firmwareVersion) {
00057 case 2006:
00058 memcpy(&header2006, buf, header2006.sizeInWords()*2);
00059 buf +=header2006.sizeInWords();
00060 memcpy(&alcts2006, buf, alcts2006.sizeInWords()*2);
00061 buf +=alcts2006.sizeInWords();
00062 break;
00063
00064 case 2007:
00065 memcpy(&header2007, buf, header2007.sizeInWords()*2);
00066 buf +=header2007.sizeInWords();
00067 sizeInWords2007_ = header2007.sizeInWords();
00069 if (header2007.configPresent==1) {
00070 memcpy(&virtexID, buf, virtexID.sizeInWords()*2);
00071 buf +=virtexID.sizeInWords();
00072 sizeInWords2007_ = virtexID.sizeInWords();
00073 memcpy(&configRegister, buf, configRegister.sizeInWords()*2);
00074 buf +=configRegister.sizeInWords();
00075 sizeInWords2007_ += configRegister.sizeInWords();
00076
00077 collisionMasks.resize(collisionMaskWordcount[header2007.boardType]);
00078 for (unsigned int i=0; i<collisionMaskWordcount[header2007.boardType]; ++i){
00079 memcpy(&collisionMasks[i], buf, collisionMasks[i].sizeInWords()*2);
00080 buf += collisionMasks[i].sizeInWords();
00081 sizeInWords2007_ += collisionMasks[i].sizeInWords();
00082 }
00083
00084 hotChannelMasks.resize(hotChannelMaskWordcount[header2007.boardType]);
00085 for (unsigned int i=0; i<hotChannelMaskWordcount[header2007.boardType]; ++i) {
00086 memcpy(&hotChannelMasks[i], buf, hotChannelMasks[i].sizeInWords()*2);
00087 buf += hotChannelMasks[i].sizeInWords();
00088 sizeInWords2007_ += hotChannelMasks[i].sizeInWords();
00089 }
00090 }
00091
00092 theALCTs.resize(header2007.lctBins*2);
00093 for (int i=0; i<header2007.lctBins*2; ++i) {
00094 memcpy(&theALCTs[i], buf, theALCTs[i].sizeInWords()*2);
00095 buf += theALCTs[i].sizeInWords();
00096 sizeInWords2007_ += theALCTs[i].sizeInWords();
00097 }
00098
00099 ALCTDigis();
00100 break;
00101
00102 default:
00103 edm::LogError("CSCALCTHeader|CSCRawToDigi")
00104 <<"couldn't construct: ALCT firmware version is bad/not defined!";
00105 break;
00106 }
00107
00109 if ((firmwareVersion==2006)||(firmwareVersion==2007))
00110 memcpy(theOriginalBuffer, buf-sizeInWords(), sizeInWords()*2);
00111
00112 }
00113
00114
00115 CSCALCTHeader::CSCALCTHeader(const CSCALCTStatusDigi & digi){
00116 CSCALCTHeader(digi.header());
00117 }
00118
00119 void CSCALCTHeader::setEventInformation(const CSCDMBHeader & dmb) {
00120 header2006.setEventInformation(dmb);
00121 }
00122
00123
00124 unsigned short CSCALCTHeader::nLCTChipRead() const {
00125 if(firmwareVersion == 2006) {
00126 return header2006.nLCTChipRead();
00127 }
00128 else {
00129
00130
00131
00132
00133 }
00134 return 0;
00135 }
00136
00137
00138 std::vector<CSCALCTDigi> CSCALCTHeader::ALCTDigis() const
00139 {
00140 std::vector<CSCALCTDigi> result;
00141
00142 switch (firmwareVersion) {
00143 case 2006:
00144 {
00145 result = alcts2006.ALCTDigis();
00146 break;
00147 }
00148 case 2007:
00149 {
00150 result.reserve(theALCTs.size());
00151 for (unsigned int i=0; i<theALCTs.size(); ++i) {
00152 CSCALCTDigi digi(theALCTs[i].valid, theALCTs[i].quality, theALCTs[i].accel, theALCTs[i].pattern,
00153 theALCTs[i].keyWire, (int)i/2, i%2+1);
00154 result.push_back(digi);
00155 }
00156 break;
00157 }
00158 default:
00159 edm::LogError("CSCALCTHeader|CSCRawToDigi")
00160 <<"Empty Digis: ALCT firmware version is bad/not defined!" << firmwareVersion;
00161 break;
00162 }
00163 for(unsigned i = 0; i < result.size(); ++i) {result[i].setFullBX(BXNCount());}
00164 return result;
00165
00166 }
00167
00168
00169 void CSCALCTHeader::add(const std::vector<CSCALCTDigi> & digis)
00170 {
00171 if(firmwareVersion == 2006) {
00172 alcts2006.add(digis);
00173 }
00174 else if(firmwareVersion == 2007) {
00175 if(theALCTs.empty())
00176 {
00177 theALCTs.resize(header2007.lctBins*2);
00178 }
00179 for(std::vector<CSCALCTDigi>::const_iterator digi = digis.begin();
00180 digi != digis.end(); ++digi)
00181 {
00182 int bx = digi->getBX();
00183 if(bx < (int)header2007.lctBins)
00184 {
00185
00186 int i = bx*2;
00187 int q1 = theALCTs[i].quality;
00188 int q2 = theALCTs[i+1].quality;
00189
00190 if(!theALCTs[i].valid)
00191 {
00192 theALCTs[i] = CSCALCT(*digi);
00193 }
00194
00195 else if(digi->getQuality() > q1)
00196 {
00197 theALCTs[i+1] = theALCTs[i];
00198 theALCTs[i] = CSCALCT(*digi);
00199 }
00200
00201 else if(!theALCTs[i+1].valid || (digi->getQuality() > q2))
00202 {
00203 theALCTs[i+1] = CSCALCT(*digi);
00204 }
00205 }
00206 }
00207 }
00208 }
00209
00210
00211 boost::dynamic_bitset<> CSCALCTHeader::pack()
00212 {
00213 boost::dynamic_bitset<> result;
00214 if(firmwareVersion == 2006)
00215 {
00216 boost::dynamic_bitset<> header
00217 = bitset_utilities::ushortToBitset(header2006.sizeInWords()*16,
00218 (unsigned short *) &header2006);
00219 boost::dynamic_bitset<> alcts
00220 = bitset_utilities::ushortToBitset(alcts2006.sizeInWords()*16,
00221 (unsigned short *) &alcts2006);
00222 result = bitset_utilities::append(header, alcts);
00223 }
00224
00225 else if(firmwareVersion == 2007)
00226 {
00227 result = bitset_utilities::ushortToBitset(header2007.sizeInWords()*16,
00228 (unsigned short *) &header2007);
00229
00230 for (unsigned i = 0; i < theALCTs.size(); ++i)
00231 {
00232 boost::dynamic_bitset<> alct
00233 = bitset_utilities::ushortToBitset(theALCTs[i].sizeInWords()*16,
00234 (unsigned short *) &theALCTs[i]);
00235 result = bitset_utilities::append(result, alct);
00236 }
00237 }
00238 return result;
00239 }
00240
00241
00242
00243 void CSCALCTHeader::selfTest(int firmware)
00244 {
00245 firmwareVersion = firmware;
00246 CSCALCTDigi alct0(true, 1, 1, 1, 10, 6, 1);
00247 CSCALCTDigi alct1(true, 1, 1, 0, 11, 6, 2);
00248
00249
00250 for(int station = 1; station <= 4; ++station)
00251 {
00252 CSCDetId detId(1, station, 1, 1, 0);
00253
00254 std::vector<CSCALCTDigi> oldAlcts;
00255 oldAlcts.push_back(alct0);
00256 oldAlcts.push_back(alct1);
00257 CSCALCTHeader alctHeader(detId.iChamberType());
00258
00259 alctHeader.add(oldAlcts);
00260
00261 std::vector<CSCALCTDigi> alcts = alctHeader.ALCTDigis();
00262
00263 std::vector<CSCALCTDigi> validALCTs;
00264 for(std::vector<CSCALCTDigi>::const_iterator alctItr = alcts.begin();
00265 alctItr != alcts.end(); ++ alctItr)
00266 {
00267 if(alctItr->isValid())
00268 {
00269 validALCTs.push_back(*alctItr);
00270 }
00271 }
00272 assert(validALCTs[0] == alct0);
00273 assert(validALCTs[1] == alct1);
00274
00275 }
00276 }
00277
00278 std::ostream & operator<<(std::ostream & os, const CSCALCTHeader & header)
00279 {
00280 os << "ALCT HEADER CSCID " << header.CSCID()
00281 << " L1ACC " << header.L1Acc() << std::endl;
00282 os << " time samples " << header.NTBins() << std::endl;
00283 return os;
00284 }
00285
00286