CMS 3D CMS Logo

HcalHTRData.cc

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

Generated on Tue Jun 9 17:34:41 2009 for CMSSW by  doxygen 1.5.4