00001
00002
00003
00004
00005
00006
00007 #ifndef HTBDAQ_DATA_STANDALONE
00008 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00009 #else
00010 #include "HcalHTRData.h"
00011 const int HcalHTRData::CHANNELS_PER_SPIGOT = 24;
00012 const int HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL = 20;
00013 #endif
00014 #include <string.h>
00015 #include <stdio.h>
00016
00017 HcalHTRData::HcalHTRData() : m_formatVersion(-2), m_rawLength(0), m_rawConst(0), m_ownData(0) { }
00018 HcalHTRData::HcalHTRData(const unsigned short* data, int length) {
00019 adoptData(data,length);
00020 m_ownData=0;
00021 }
00022 HcalHTRData::HcalHTRData(const HcalHTRData& hd) : m_formatVersion(hd.m_formatVersion), m_rawLength(hd.m_rawLength), m_rawConst(hd.m_rawConst), m_ownData(0) { }
00023
00024 HcalHTRData::HcalHTRData(int version_to_create) : m_formatVersion(version_to_create) {
00025 allocate(version_to_create);
00026 }
00027
00028 void HcalHTRData::allocate(int version_to_create) {
00029 m_formatVersion=version_to_create;
00030
00031 const int needed=0x200;
00032
00033 m_ownData=new unsigned short[needed];
00034
00035 memset(m_ownData,0,sizeof(unsigned short)*needed);
00036 m_rawLength=0;
00037 m_rawConst=m_ownData;
00038 }
00039
00040 HcalHTRData& HcalHTRData::operator=(const HcalHTRData& hd) {
00041 if (m_ownData==0) {
00042 m_formatVersion=hd.m_formatVersion;
00043 m_rawLength=hd.m_rawLength;
00044 m_rawConst=hd.m_rawConst;
00045 }
00046 return (*this);
00047 }
00048
00049 void HcalHTRData::adoptData(const unsigned short* data, int length) {
00050 m_rawLength=length;
00051 m_rawConst=data;
00052 if (m_rawLength<5) {
00053 m_formatVersion=-2;
00054 } else {
00055
00056 if ((m_rawConst[2]&0x8000)==0) m_formatVersion=-1;
00057 else m_formatVersion=(m_rawConst[4]>>12)&0xF;
00058 }
00059 }
00060
00061
00062
00063
00064 bool HcalHTRData::check() const {
00065 if (m_formatVersion==-1) {
00066
00067
00068 if (m_rawLength<6+12) return false;
00069
00070 if (m_rawLength!=m_rawConst[m_rawLength-3]) return false;
00071
00072 if (m_rawConst[2]&0x20) return false;
00073 } else {
00074
00075
00076 if (m_rawLength<8+4) return false;
00077 if (m_formatVersion<=3) {
00078
00079 if (m_rawLength!=m_rawConst[m_rawLength-3]) {
00080 if (isHistogramEvent() && m_rawConst[m_rawLength-3]==786) {
00081
00082 } else
00083 return false;
00084 }
00085 } else {
00086
00087 }
00088
00089 if (m_rawConst[2]&0x4) return false;
00090 }
00091
00092 if (!isHistogramEvent()) {
00093
00094 int tp, daq, header, trailer;
00095 determineSectionLengths(tp,daq,header,trailer);
00096 if (tp+daq+header+trailer>m_rawLength) return false;
00097 }
00098
00099 return true;
00100 }
00101
00102 bool HcalHTRData::isEmptyEvent() const {
00103 if (m_formatVersion==-1) {
00104 return (m_rawConst[2]&0x20)!=0;
00105 } else {
00106 return (m_rawConst[2]&0x4)!=0;
00107 }
00108 }
00109
00110
00111 bool HcalHTRData::isOverflowWarning() const {
00112 if (m_formatVersion==-1) {
00113 return false;
00114 } else {
00115 return (m_rawConst[2]&0x1)!=0;
00116 }
00117 }
00118
00119 bool HcalHTRData::isBusy() const {
00120 if (m_formatVersion==-1) {
00121 return false;
00122 } else {
00123 return (m_rawConst[2]&0x2)!=0;
00124 }
00125 }
00126
00127 void HcalHTRData::determineSectionLengths(int& tpWords, int& daqWords, int& headerWords, int& trailerWords) const {
00128 if (m_formatVersion==-1) {
00129 tpWords=m_rawConst[5]>>8;
00130 daqWords=CHANNELS_PER_SPIGOT*(m_rawConst[m_rawLength-4]>>8);
00131 headerWords=6;
00132 trailerWords=12;
00133 } else {
00134 tpWords=m_rawConst[5]>>8;
00135 if (m_rawLength>4)
00136 daqWords=m_rawConst[m_rawLength-4]&0x7FF;
00137 headerWords=8;
00138 trailerWords=4;
00139 }
00140 }
00141
00142 void HcalHTRData::determineStaticLengths(int& headerWords, int& trailerWords) const {
00143 if (m_formatVersion==-1) {
00144 headerWords=6;
00145 trailerWords=12;
00146 } else if (m_formatVersion<5) {
00147 headerWords=8;
00148 trailerWords=4;
00149 } else {
00150 headerWords=8;
00151 trailerWords=12;
00152 }
00153 }
00154
00155 void HcalHTRData::dataPointers(const unsigned short** daq_first,
00156 const unsigned short** daq_last,
00157 const unsigned short** tp_first,
00158 const unsigned short** tp_last) const {
00159 int tp_words_total, daq_words_total, headerLen, trailerLen;
00160 determineSectionLengths(tp_words_total,daq_words_total,headerLen,trailerLen);
00161
00162 *tp_first=m_rawConst+headerLen;
00163 *tp_last=*tp_first+(tp_words_total-1);
00164 *daq_first=*tp_last+1;
00165 *daq_last=*daq_first+(daq_words_total-1);
00166 }
00167
00168
00169 static const int channelDecoder[32] = { 0, 1, 2, 99, 3, 4, 5, 99,
00170 6, 7, 8, 99, 9,10,11, 99,
00171 12,13,14,99,15,16,17, 99,
00172 18,19,20,99,21,22,23, 99};
00173
00174 void HcalHTRData::unpack(unsigned char* daq_lengths, unsigned short* daq_samples,
00175 unsigned char* tp_lengths, unsigned short* tp_samples) const {
00176
00177 if (daq_lengths!=0) memset(daq_lengths,0,CHANNELS_PER_SPIGOT);
00178 if (tp_lengths!=0) memset(tp_lengths,0,CHANNELS_PER_SPIGOT);
00179
00180
00181
00182
00183
00184 int tp_words_total, daq_words_total, headerLen, trailerLen;
00185 determineSectionLengths(tp_words_total,daq_words_total,headerLen,trailerLen);
00186
00187
00188 int wordPtr;
00189 const unsigned short* tpBase=m_rawConst+headerLen;
00190
00191 if (tp_lengths!=0) {
00192 for (wordPtr=0; wordPtr<tp_words_total; wordPtr++) {
00193 int ichan=channelDecoder[tpBase[wordPtr]>>11];
00194 if (ichan>=24) continue;
00195 tp_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+tp_lengths[ichan]]=tpBase[wordPtr]&0x3ff;
00196 tp_lengths[ichan]++;
00197 }
00198 }
00199
00200 const unsigned short* daqBase=m_rawConst+headerLen+tp_words_total;
00201
00202 int lastChan=-1;
00203 int lastCapid=0;
00204 if (daq_lengths!=0) {
00205 for (wordPtr=0; wordPtr<daq_words_total; wordPtr++) {
00206 int ichan=channelDecoder[daqBase[wordPtr]>>11];
00207 if (ichan>=24) continue;
00208 int capid=(daqBase[wordPtr]&0x180)>>7;
00209 int erdv=(daqBase[wordPtr]&0x600)>>9;
00210 if (erdv!=0x1 ||
00211 (lastChan==ichan && (capid!=((lastCapid+1)%4)))) {
00212 daq_lengths[ichan]|=0x80;
00213 }
00214 lastChan=ichan;
00215 lastCapid=capid;
00216
00217 int useLength=daq_lengths[ichan]&0x1F;
00218
00219 daq_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+useLength]=daqBase[wordPtr]&0x3ff;
00220 daq_lengths[ichan]=(useLength+1)|(daq_lengths[ichan]&0xE0);
00221 }
00222 }
00223
00224 }
00225
00226 void HcalHTRData::pack(unsigned char* daq_lengths, unsigned short* daq_samples,
00227 unsigned char* tp_lengths, unsigned short* tp_samples, bool do_capid) {
00228
00229 int tp_words_total=0, daq_words_total=0, headerLen, trailerLen;
00230 determineStaticLengths(headerLen,trailerLen);
00231
00232 tp_words_total=0;
00233 daq_words_total=0;
00234 int ichan,isample;
00235
00236
00237 unsigned short* ptr=m_ownData+headerLen;
00238 if (tp_samples!=0 && tp_lengths!=0) {
00239 for (ichan=0; ichan<24; ichan++) {
00240 unsigned short chanid=((ichan%3)+((ichan/3)<<2))<<11;
00241 for (isample=0; isample<tp_lengths[ichan] && isample<MAXIMUM_SAMPLES_PER_CHANNEL; isample++) {
00242 ptr[tp_words_total]=chanid|(tp_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+isample]&0x3FF);
00243 tp_words_total++;
00244 }
00245 }
00246 }
00247
00248
00249 ptr=m_ownData+headerLen+tp_words_total;
00250 for (ichan=0; ichan<24; ichan++) {
00251 unsigned short chanid=((ichan%3)+((ichan/3)<<2))<<11;
00252 for (isample=0; isample<daq_lengths[ichan] && isample<MAXIMUM_SAMPLES_PER_CHANNEL; isample++) {
00253 unsigned short basedata=daq_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+isample]&0x3FF;
00254 if (do_capid) basedata=(basedata&0x7F)|(0x200)|((isample%4)<<7);
00255 ptr[daq_words_total]=chanid|basedata;
00256 daq_words_total++;
00257 }
00258 }
00259 unsigned short totalLen;
00260 if (m_formatVersion==-1) {
00261 m_ownData[5]=(tp_words_total<<8)|0x1;
00262 totalLen=headerLen+tp_words_total+daq_words_total+trailerLen;
00263 m_rawLength=totalLen;
00264 m_ownData[totalLen-3]=totalLen;
00265 m_ownData[totalLen-4]=(tp_words_total/CHANNELS_PER_SPIGOT)|((daq_words_total/CHANNELS_PER_SPIGOT)<<8);
00266 } else {
00267 m_ownData[5]=(tp_words_total<<8)|0x1;
00268 totalLen=headerLen+tp_words_total+daq_words_total+trailerLen;
00269 if ((totalLen%2)==1) {
00270 m_ownData[totalLen-4]=0xFFFF;
00271 totalLen++;
00272 }
00273 m_rawLength=totalLen;
00274 m_ownData[totalLen-2]=totalLen/2;
00275 m_ownData[totalLen-3]=totalLen;
00276 m_ownData[totalLen-4]=daq_words_total;
00277 }
00278 if (trailerLen==12) {
00279 for (int i=12; i>4; i--)
00280 m_ownData[totalLen-i]=0;
00281 }
00282
00283 }
00284
00285 void HcalHTRData::packHeaderTrailer(int L1Anumber, int bcn, int submodule, int orbitn, int pipeline, int ndd, int nps, int firmwareRev) {
00286 m_ownData[0]=L1Anumber&0xFF;
00287 m_ownData[1]=(L1Anumber&0xFFFF00)>>8;
00288 if (m_formatVersion==-1) {
00289 m_ownData[2]=((pipeline&0x7F)<<8);
00290 m_ownData[3]=((orbitn&0xFF)<<8)|(submodule&0xFF);
00291 m_ownData[4]=bcn&0xFFF;
00292
00293 } else {
00294 m_ownData[2]=0x8000;
00295 if (m_formatVersion==0)
00296 m_ownData[3]=((orbitn&0x3F)<<10)|(submodule&0x3FF);
00297 else
00298 m_ownData[3]=((orbitn&0x1F)<<11)|(submodule&0x7FF);
00299 m_ownData[4]=((m_formatVersion&0xF)<<12)|(bcn&0xFFF);
00300 m_ownData[5]|=((nps&0x1F)<<3)|0x1;
00301 m_ownData[6]=((firmwareRev&0x70000)>>3)|(firmwareRev&0x1FFF);
00302 m_ownData[7]=pipeline&0xFF;
00303 m_ownData[m_rawLength-4]&=0x7FF;
00304 m_ownData[m_rawLength-4]|=(ndd&0x1F)<<11;
00305 }
00306 m_ownData[m_rawLength-2]=m_rawLength/2;
00307 m_ownData[m_rawLength-1]=(L1Anumber&0xFF)<<8;
00308 }
00309
00310 void HcalHTRData::packUnsuppressed(const bool* mp) {
00311 if (m_formatVersion<4) return;
00312
00313 for (int fiber=1; fiber<=8; fiber++) {
00314 for (int fiberchan=0; fiberchan<=2; fiberchan++) {
00315 int linchan=(fiber-1)*3+fiberchan;
00316
00317 unsigned short& val=m_ownData[m_rawLength-12+(linchan/8)];
00318 if (mp[linchan]) val|=1<<(linchan%8);
00319 }
00320 }
00321
00322
00323 m_ownData[6]|=0x8000;
00324 }
00325
00326 unsigned int HcalHTRData::getOrbitNumber() const {
00327 switch (m_formatVersion) {
00328 case (-1) : return (m_rawConst[3]>>8);
00329 case (0) : return (m_rawConst[3]>>10);
00330 default : return (m_rawConst[3]>>11);
00331 }
00332 }
00333 unsigned int HcalHTRData::getSubmodule() const {
00334 switch (m_formatVersion) {
00335 case (-1) : return (m_rawConst[3]&0xFF);
00336 case (0) : return (m_rawConst[3]&0x3FF);
00337 default : return (m_rawConst[3]&0x7FF);
00338 }
00339 }
00340 unsigned int HcalHTRData::htrSlot() const{
00341 const unsigned int smid = getSubmodule();
00342 return ((smid>>1)&0x1F);
00343 }
00344 unsigned int HcalHTRData::htrTopBottom() const{
00345 const unsigned int smid = getSubmodule();
00346 return (smid&0x01);
00347 }
00348 unsigned int HcalHTRData::readoutVMECrateId() const{
00349 const unsigned int smid = getSubmodule();
00350 return ((smid>>6)&0x1F);
00351 }
00352 bool HcalHTRData::isCalibrationStream() const {
00353 return (m_formatVersion==-1)?(false):(m_rawConst[2]&0x4000);
00354 }
00355 bool HcalHTRData::isUnsuppressed() const {
00356 return (m_formatVersion<4)?(false):(m_rawConst[6]&0x8000);
00357 }
00358 bool HcalHTRData::wasMarkAndPassZS(int fiber, int fiberchan) const {
00359 if (fiber<1 || fiber>8 || fiberchan<0 || fiberchan>2) return false;
00360 if (!isUnsuppressed() || m_formatVersion<5) return false;
00361 int linchan=(fiber-1)*3+fiberchan;
00362
00363 unsigned short val=m_rawConst[m_rawLength-12+(linchan/8)];
00364 return ((val>>(linchan%8))&0x1)!=0;
00365 }
00366 bool HcalHTRData::wasMarkAndPassZSTP(int slb, int slbchan) const {
00367 if (slb<1 || slb>6 || slbchan<0 || slbchan>3) return false;
00368 if (!isUnsuppressed() || m_formatVersion<5) return false;
00369 int linchan=(slb-1)*4+slbchan;
00370
00371 unsigned short val=m_rawConst[m_rawLength-12+(linchan/8)];
00372 return ((val>>(linchan%8))&0x100)!=0;
00373 }
00374
00375 uint32_t HcalHTRData::zsBunchMask() const {
00376 uint32_t mask=0;
00377 if (isUnsuppressed() && m_formatVersion>=5) {
00378 mask=m_rawConst[m_rawLength-5]|
00379 ((m_rawConst[m_rawLength-6]&0xF000)<<4);
00380 }
00381 return mask;
00382 }
00383
00384 bool HcalHTRData::isPatternRAMEvent() const {
00385 return (m_formatVersion==-1)?(false):(m_rawConst[2]&0x1000);
00386 }
00387 bool HcalHTRData::isHistogramEvent() const {
00388 return (m_formatVersion==-1)?(m_rawConst[2]&0x2):(m_rawConst[2]&0x2000);
00389 }
00390 int HcalHTRData::getNDD() const {
00391 return (m_formatVersion==-1)?(m_rawConst[m_rawLength-4]>>8):(m_rawConst[m_rawLength-4]>>11);
00392 }
00393 int HcalHTRData::getNTP() const {
00394 int retval=-1;
00395 if (m_formatVersion==-1) retval=m_rawConst[m_rawLength-4]&0xFF;
00396 else if (m_formatVersion<3) retval=m_rawConst[m_rawLength-4]>>11;
00397 return retval;
00398 }
00399 int HcalHTRData::getNPrecisionWords() const {
00400 return (m_formatVersion==-1)?(m_rawConst[m_rawLength-4]&0xFF):(m_rawConst[m_rawLength-4]&0x7FF);
00401 }
00402 int HcalHTRData::getNPS() const {
00403 return (m_formatVersion==-1)?(0):((m_rawConst[5]>>3)&0x1F);
00404 }
00405 unsigned int HcalHTRData::getPipelineLength() const {
00406 return (m_formatVersion==-1)?(m_rawConst[2]>>8):(m_rawConst[7]&0xFF);
00407 }
00408 unsigned int HcalHTRData::getFirmwareRevision() const {
00409 return (m_formatVersion==-1)?(0):((m_rawConst[6]&0x1FFF)+((m_rawConst[6]&0xE000)<<3));
00410 }
00411 int HcalHTRData::getFirmwareFlavor() const {
00412 return (m_formatVersion<2)?(-1):((m_rawConst[7]>>8)&0xFF);
00413 }
00414
00415 void HcalHTRData::getHistogramFibers(int& a, int& b) const {
00416 a=-1;
00417 b=-1;
00418 if (m_formatVersion==-1) {
00419 a=((m_rawConst[2]&0x0F00)>>8);
00420 b=((m_rawConst[2]&0xF000)>>12);
00421 } else {
00422 a=((m_rawConst[5]&0x0F00)>>8);
00423 b=((m_rawConst[5]&0xF000)>>12);
00424 }
00425 }
00426
00427 bool HcalHTRData::wasHistogramError(int ifiber) const {
00428 bool retval=!isHistogramEvent();
00429 if (!retval) {
00430 retval=((m_rawConst[7])&(1<<ifiber))!=0;
00431 }
00432 return retval;
00433 }
00434
00435 bool HcalHTRData::unpack_per_channel_header(unsigned short header, int& flav, int& error_flags, int& capid0, int& channelid) {
00436 flav=(header>>12)&0x7;
00437 error_flags=(header>>10)&0x3;
00438 capid0=(header>>8)&0x3;
00439 channelid=(header)&0xFF;
00440 return (header&0x8000)!=0;
00441 }
00442
00443 bool HcalHTRData::unpackHistogram(int myfiber, int mysc, int capid, unsigned short* histogram) const {
00444
00445 if (!isHistogramEvent()) return false;
00446
00447 int fiber1, fiber2;
00448 getHistogramFibers(fiber1,fiber2);
00449 if (fiber1!=myfiber && fiber2!=myfiber) return false;
00450
00451 if (m_formatVersion==-1) {
00452 int offset=6+mysc*4*32+capid*32;
00453 if (myfiber==fiber2) offset+=3*4*32;
00454 for (int i=0; i<32; i++)
00455 histogram[i]=m_rawConst[offset+i];
00456 return true;
00457 } else {
00458 int offset=8+mysc*4*32+capid*32;
00459 if (myfiber==fiber2) offset+=3*4*32;
00460 for (int i=0; i<32; i++)
00461 histogram[i]=m_rawConst[offset+i];
00462 return true;
00463 }
00464 }