CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/EventFilter/HcalRawToDigi/src/HcalHTRData.cc

Go to the documentation of this file.
00001 //#include "Utilities/Configuration/interface/Architecture.h"
00002 /*  
00003  *  $Date: 2011/08/04 01:10:50 $
00004  *  $Revision: 1.18 $
00005  *  \author J. Mans -- UMD
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   // the needed space is for the biggest possible event...
00031   const int needed=0x200;
00032   // create a buffer big enough...
00033   m_ownData=new unsigned short[needed];
00034   // clear isn't really necessary, but it makes valgrind happy
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; // invalid!
00054   } else {
00055     // determine format version
00056     if ((m_rawConst[2]&0x8000)==0) m_formatVersion=-1; // original format before versions
00057     else m_formatVersion=(m_rawConst[4]>>12)&0xF;
00058   }
00059 }
00060 
00061 // check :: not EE, length is reasonable, length matches wordcount
00062 //          length required for tp+daq is correct
00063 
00064 bool HcalHTRData::check() const {
00065   if (m_formatVersion==-1) {
00066     // length checks
00067     //  minimum length
00068     if (m_rawLength<6+12) return false;
00069     //  matches wordcount
00070     if (m_rawLength!=m_rawConst[m_rawLength-3]) return false;
00071     // empty event check
00072     if (m_rawConst[2]&0x20) return false;
00073   } else {
00074     // length checks
00075     //  minimum length
00076     if (m_rawLength<8+4) return false;
00077     if (m_formatVersion<=3) {
00078       //  matches wordcount
00079       if (m_rawLength!=m_rawConst[m_rawLength-3]) {
00080         if (isHistogramEvent() && m_rawConst[m_rawLength-3]==786) {
00081           // known bug!
00082         } else
00083           return false;
00084       }
00085     } else { 
00086       // eventually add CRC check
00087     }
00088     // empty event check (redundant...)
00089     if (m_rawConst[2]&0x4) return false;
00090   }
00091 
00092   if (!isHistogramEvent()) {
00093     // daq/tp length check
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 void HcalHTRData::determineSectionLengths(int& tpWords, int& daqWords, int& headerWords, int& trailerWords) const {
00103   if (m_formatVersion==-1) {
00104     tpWords=m_rawConst[5]>>8;
00105     daqWords=CHANNELS_PER_SPIGOT*(m_rawConst[m_rawLength-4]>>8); // always 24 channels, no zero suppresion
00106     headerWords=6;
00107     trailerWords=12;
00108   } else {
00109     tpWords=m_rawConst[5]>>8;
00110     if (m_rawLength>4) 
00111       daqWords=m_rawConst[m_rawLength-4]&0x7FF; // zero suppression supported
00112     headerWords=8;
00113     trailerWords=4; // minimum, may be more...
00114   }
00115 }
00116 
00117 void HcalHTRData::determineStaticLengths(int& headerWords, int& trailerWords) const {
00118   if (m_formatVersion==-1) {
00119     headerWords=6;
00120     trailerWords=12;
00121   } else if (m_formatVersion<5) {
00122     headerWords=8;
00123     trailerWords=4; // minimum, may be more...
00124   } else {
00125     headerWords=8;
00126     trailerWords=12; // minimum, may be more...
00127   }
00128 }
00129 
00130 void HcalHTRData::dataPointers(const unsigned short** daq_first, 
00131                                const unsigned short** daq_last, 
00132                                const unsigned short** tp_first, 
00133                                const unsigned short** tp_last) const {
00134   int tp_words_total, daq_words_total, headerLen, trailerLen;
00135   determineSectionLengths(tp_words_total,daq_words_total,headerLen,trailerLen);
00136 
00137   *tp_first=m_rawConst+headerLen;
00138   *tp_last=*tp_first+(tp_words_total-1);
00139   *daq_first=*tp_last+1;
00140   *daq_last=*daq_first+(daq_words_total-1);
00141 }
00142 
00143 /* using FiberAd[2:0] ChanId[1:0] */
00144 static const int channelDecoder[32] = { 0, 1, 2, 99, 3, 4, 5, 99, 
00145                                         6, 7, 8, 99, 9,10,11, 99,
00146                                         12,13,14,99,15,16,17, 99,
00147                                         18,19,20,99,21,22,23, 99};
00148 
00149 void HcalHTRData::unpack(unsigned char* daq_lengths, unsigned short* daq_samples,
00150                          unsigned char* tp_lengths, unsigned short* tp_samples) const {
00151 
00152   if (daq_lengths!=0) memset(daq_lengths,0,CHANNELS_PER_SPIGOT);
00153   if (tp_lengths!=0) memset(tp_lengths,0,CHANNELS_PER_SPIGOT);
00154 
00155   // currently, the major differences between the versions are
00156   //  -1 : 6 word header, no zero suppression, trailer setup
00157   //   0 : 8 word header, zero suppression, 
00158 
00159   int tp_words_total, daq_words_total, headerLen, trailerLen;
00160   determineSectionLengths(tp_words_total,daq_words_total,headerLen,trailerLen);
00161 
00162   //  printf("%d %d %d %d\n",tp_words_total,daq_words_total,headerLen,trailerLen);
00163   int wordPtr;
00164   const unsigned short* tpBase=m_rawConst+headerLen;
00165   // process the trigger primitive words
00166   if (tp_lengths!=0) {
00167     for (wordPtr=0; wordPtr<tp_words_total; wordPtr++) {
00168       int ichan=channelDecoder[tpBase[wordPtr]>>11];
00169       if (ichan>=24) continue;
00170       tp_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+tp_lengths[ichan]]=tpBase[wordPtr]&0x3ff;
00171       tp_lengths[ichan]++;
00172     }
00173   }
00174  
00175   const unsigned short* daqBase=m_rawConst+headerLen+tp_words_total;
00176   // process the DAQ words [ assumes that data from one channel will always be together ]
00177   int lastChan=-1;
00178   int lastCapid=0;
00179   if (daq_lengths!=0) {
00180     for (wordPtr=0; wordPtr<daq_words_total; wordPtr++) {
00181       int ichan=channelDecoder[daqBase[wordPtr]>>11];
00182       if (ichan>=24) continue;
00183       int capid=(daqBase[wordPtr]&0x180)>>7;
00184       int erdv=(daqBase[wordPtr]&0x600)>>9;
00185       if (erdv!=0x1 || 
00186           (lastChan==ichan && (capid!=((lastCapid+1)%4)))) {
00187         daq_lengths[ichan]|=0x80;
00188       } 
00189       lastChan=ichan;
00190       lastCapid=capid;
00191 
00192       int useLength=daq_lengths[ichan]&0x1F;
00193       //     printf("%d %d\n",ichan,useLength);
00194       daq_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+useLength]=daqBase[wordPtr]&0x3ff;
00195       daq_lengths[ichan]=(useLength+1)|(daq_lengths[ichan]&0xE0); // keep the error bits
00196     }
00197   }
00198 
00199 }
00200 
00201 void HcalHTRData::pack(unsigned char* daq_lengths, unsigned short* daq_samples,
00202                        unsigned char* tp_lengths, unsigned short* tp_samples, bool do_capid) {
00203   
00204   int tp_words_total=0, daq_words_total=0, headerLen, trailerLen;
00205   determineStaticLengths(headerLen,trailerLen);
00206 
00207   tp_words_total=0;
00208   daq_words_total=0;
00209   int ichan,isample;
00210 
00211   // trigger primitive words
00212   unsigned short* ptr=m_ownData+headerLen;
00213   if (tp_samples!=0 && tp_lengths!=0) {
00214     for (ichan=0; ichan<24; ichan++) {
00215       unsigned short chanid=((ichan%3)+((ichan/3)<<2))<<11;
00216       for (isample=0; isample<tp_lengths[ichan] && isample<MAXIMUM_SAMPLES_PER_CHANNEL; isample++) {
00217         ptr[tp_words_total]=chanid|(tp_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+isample]&0x3FF);
00218         tp_words_total++;
00219       }
00220     }
00221   }
00222 
00223   // daq words
00224   ptr=m_ownData+headerLen+tp_words_total;
00225   for (ichan=0; ichan<24; ichan++) {
00226     unsigned short chanid=((ichan%3)+((ichan/3)<<2))<<11;
00227     for (isample=0; isample<daq_lengths[ichan] && isample<MAXIMUM_SAMPLES_PER_CHANNEL; isample++) {
00228       unsigned short basedata=daq_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+isample]&0x3FF;
00229       if (do_capid) basedata=(basedata&0x7F)|(0x200)|((isample%4)<<7);
00230       ptr[daq_words_total]=chanid|basedata;
00231       daq_words_total++;
00232     }
00233   }
00234   unsigned short totalLen;
00235   if (m_formatVersion==-1) {
00236     m_ownData[5]=(tp_words_total<<8)|0x1;
00237     totalLen=headerLen+tp_words_total+daq_words_total+trailerLen;
00238     m_rawLength=totalLen;
00239     m_ownData[totalLen-3]=totalLen;
00240     m_ownData[totalLen-4]=(tp_words_total/CHANNELS_PER_SPIGOT)|((daq_words_total/CHANNELS_PER_SPIGOT)<<8);
00241   } else {
00242     m_ownData[5]=(tp_words_total<<8)|0x1;
00243     totalLen=headerLen+tp_words_total+daq_words_total+trailerLen;
00244     if ((totalLen%2)==1) {
00245       m_ownData[totalLen-4]=0xFFFF; // parity word
00246       totalLen++; // round to even number of 16-bit words
00247     }
00248     m_rawLength=totalLen;
00249     m_ownData[totalLen-2]=totalLen/2; // 32-bit words
00250     m_ownData[totalLen-3]=totalLen;
00251     m_ownData[totalLen-4]=daq_words_total;
00252   }
00253   if (trailerLen==12) { // initialize extra trailer words if present
00254     for (int i=12; i>4; i--)
00255       m_ownData[totalLen-i]=0;
00256   }
00257 
00258 }
00259 
00260 void HcalHTRData::packHeaderTrailer(int L1Anumber, int bcn, int submodule, int orbitn, int pipeline, int ndd, int nps, int firmwareRev) {
00261   m_ownData[0]=L1Anumber&0xFF;
00262   m_ownData[1]=(L1Anumber&0xFFFF00)>>8;
00263   if (m_formatVersion==-1) {
00264     m_ownData[2]=((pipeline&0x7F)<<8); // no error bits
00265     m_ownData[3]=((orbitn&0xFF)<<8)|(submodule&0xFF);
00266     m_ownData[4]=bcn&0xFFF;
00267     //    m_ownData[5]&=0xFF01;
00268   } else {
00269     m_ownData[2]=0x8000; // Version is valid, no error bits
00270     if (m_formatVersion==0) 
00271       m_ownData[3]=((orbitn&0x3F)<<10)|(submodule&0x3FF);
00272     else 
00273       m_ownData[3]=((orbitn&0x1F)<<11)|(submodule&0x7FF);
00274     m_ownData[4]=((m_formatVersion&0xF)<<12)|(bcn&0xFFF);
00275     m_ownData[5]|=((nps&0x1F)<<3)|0x1;
00276     m_ownData[6]=((firmwareRev&0x70000)>>3)|(firmwareRev&0x1FFF);
00277     m_ownData[7]=pipeline&0xFF;
00278     m_ownData[m_rawLength-4]&=0x7FF;
00279     m_ownData[m_rawLength-4]|=(ndd&0x1F)<<11;
00280   }
00281   m_ownData[m_rawLength-2]=m_rawLength/2; // 32-bit words
00282   m_ownData[m_rawLength-1]=(L1Anumber&0xFF)<<8;
00283 }
00284 
00285 void HcalHTRData::packUnsuppressed(const bool* mp) {
00286   if (m_formatVersion<4) return;
00287 
00288   for (int fiber=1; fiber<=8; fiber++) {
00289     for (int fiberchan=0; fiberchan<=2; fiberchan++) {
00290       int linchan=(fiber-1)*3+fiberchan;
00291 
00292       unsigned short& val=m_ownData[m_rawLength-12+(linchan/8)];
00293       if (mp[linchan]) val|=1<<(linchan%8);
00294     }
00295   }
00296   
00297   // set the unsupressed bit
00298   m_ownData[6]|=0x8000;
00299 }
00300 
00301 unsigned int HcalHTRData::getOrbitNumber() const { 
00302   switch (m_formatVersion) {
00303   case (-1) : return (m_rawConst[3]>>8);
00304   case (0) : return (m_rawConst[3]>>10);
00305   default : return (m_rawConst[3]>>11);
00306   }
00307 }
00308 unsigned int HcalHTRData::getSubmodule() const {
00309   switch (m_formatVersion) {
00310   case (-1) : return (m_rawConst[3]&0xFF);
00311   case (0) : return (m_rawConst[3]&0x3FF);
00312   default : return (m_rawConst[3]&0x7FF);
00313   }
00314 }
00315 unsigned int HcalHTRData::htrSlot() const{
00316   const unsigned int smid = getSubmodule();
00317   return ((smid>>1)&0x1F);
00318 } 
00319 unsigned int HcalHTRData::htrTopBottom() const{
00320   const unsigned int smid = getSubmodule();
00321   return (smid&0x01);
00322 } 
00323 unsigned int HcalHTRData::readoutVMECrateId() const{
00324   const unsigned int smid = getSubmodule();
00325   return ((smid>>6)&0x1F);
00326 } 
00327 bool HcalHTRData::isCalibrationStream() const {
00328   return (m_formatVersion==-1)?(false):(m_rawConst[2]&0x4000);
00329 }
00330 bool HcalHTRData::isUnsuppressed() const {
00331   return (m_formatVersion<4)?(false):(m_rawConst[6]&0x8000);
00332 }
00333 bool HcalHTRData::wasMarkAndPassZS(int fiber, int fiberchan) const {
00334   if (fiber<1 || fiber>8 || fiberchan<0 || fiberchan>2) return false;
00335   if (!isUnsuppressed() || m_formatVersion<5) return false;
00336   int linchan=(fiber-1)*3+fiberchan;
00337 
00338   unsigned short val=m_rawConst[m_rawLength-12+(linchan/8)];
00339   return ((val>>(linchan%8))&0x1)!=0;
00340 } 
00341 bool HcalHTRData::wasMarkAndPassZSTP(int slb, int slbchan) const {
00342   if (slb<1 || slb>6 || slbchan<0 || slbchan>3) return false;
00343   if (!isUnsuppressed() || m_formatVersion<5) return false;
00344   int linchan=(slb-1)*4+slbchan;
00345 
00346   unsigned short val=m_rawConst[m_rawLength-12+(linchan/8)];
00347   return ((val>>(linchan%8))&0x100)!=0;
00348 } 
00349 
00350 uint32_t HcalHTRData::zsBunchMask() const {
00351   uint32_t mask=0;
00352   if (isUnsuppressed() && m_formatVersion>=5) {
00353     mask=m_rawConst[m_rawLength-5]|
00354       ((m_rawConst[m_rawLength-6]&0xF000)<<4);
00355   }
00356   return mask;
00357 }
00358 
00359 bool HcalHTRData::isPatternRAMEvent() const {
00360   return (m_formatVersion==-1)?(false):(m_rawConst[2]&0x1000);
00361 }
00362 bool HcalHTRData::isHistogramEvent() const {
00363   return (m_formatVersion==-1)?(m_rawConst[2]&0x2):(m_rawConst[2]&0x2000);
00364 }
00365 int HcalHTRData::getNDD() const {
00366   return (m_formatVersion==-1)?(m_rawConst[m_rawLength-4]>>8):(m_rawConst[m_rawLength-4]>>11);
00367 }
00368 int HcalHTRData::getNTP() const {
00369   int retval=-1;
00370   if (m_formatVersion==-1) retval=m_rawConst[m_rawLength-4]&0xFF;
00371   else if (m_formatVersion<3) retval=m_rawConst[m_rawLength-4]>>11;
00372   return retval;
00373 }
00374 int HcalHTRData::getNPrecisionWords() const {
00375   return (m_formatVersion==-1)?(m_rawConst[m_rawLength-4]&0xFF):(m_rawConst[m_rawLength-4]&0x7FF);
00376 }
00377 int HcalHTRData::getNPS() const {
00378   return (m_formatVersion==-1)?(0):((m_rawConst[5]>>3)&0x1F);
00379 }
00380 unsigned int HcalHTRData::getPipelineLength() const {
00381   return (m_formatVersion==-1)?(m_rawConst[2]>>8):(m_rawConst[7]&0xFF);
00382 }
00383 unsigned int HcalHTRData::getFirmwareRevision() const {
00384   return (m_formatVersion==-1)?(0):((m_rawConst[6]&0x1FFF)+((m_rawConst[6]&0xE000)<<3));
00385 }
00386 int HcalHTRData::getFirmwareFlavor() const {
00387   return (m_formatVersion<2)?(-1):((m_rawConst[7]>>8)&0xFF);
00388 }
00389 
00390 void HcalHTRData::getHistogramFibers(int& a, int& b) const {
00391   a=-1;
00392   b=-1;
00393   if (m_formatVersion==-1) {
00394     a=((m_rawConst[2]&0x0F00)>>8);
00395     b=((m_rawConst[2]&0xF000)>>12);
00396   } else {
00397     a=((m_rawConst[5]&0x0F00)>>8);
00398     b=((m_rawConst[5]&0xF000)>>12);
00399   }
00400 }
00401 
00402 bool HcalHTRData::wasHistogramError(int ifiber) const {
00403   bool retval=!isHistogramEvent();
00404   if (!retval) {
00405     retval=((m_rawConst[7])&(1<<ifiber))!=0;
00406   }
00407   return retval;
00408 }
00409 
00410 bool HcalHTRData::unpackHistogram(int myfiber, int mysc, int capid, unsigned short* histogram) const {
00411   // check for histogram mode
00412   if (!isHistogramEvent()) return false;
00413 
00414   int fiber1, fiber2;
00415   getHistogramFibers(fiber1,fiber2);
00416   if (fiber1!=myfiber && fiber2!=myfiber) return false;
00417 
00418   if (m_formatVersion==-1) {
00419     int offset=6+mysc*4*32+capid*32;
00420     if (myfiber==fiber2) offset+=3*4*32; // skip to the second half...
00421     for (int i=0; i<32; i++)
00422       histogram[i]=m_rawConst[offset+i];
00423     return true;
00424   } else {
00425     int offset=8+mysc*4*32+capid*32;
00426     if (myfiber==fiber2) offset+=3*4*32; // skip to the second half...
00427     for (int i=0; i<32; i++)
00428       histogram[i]=m_rawConst[offset+i];
00429     return true;
00430   }
00431 }