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