00001
00002
00003
00004
00005
00006
00007 #ifndef HTBDAQ_DATA_STANDALONE
00008 #include "EventFilter/CastorRawToDigi/interface/CastorCORData.h"
00009 #else
00010 #include "CastorCORData.h"
00011 #endif
00012 #include <string.h>
00013 #include <iostream>
00014 #include <algorithm>
00015 #include <iomanip>
00016
00017 using namespace std;
00018
00019 const int CastorCORData::CHANNELS_PER_SPIGOT = 36;
00020 const int CastorCORData::MAXIMUM_SAMPLES_PER_CHANNEL = 20;
00021
00022 CastorCORData::CastorCORData() : m_formatVersion(-2), m_rawLength(0), m_rawConst(0), m_ownData(0) { }
00023 CastorCORData::CastorCORData(const unsigned short* data, int length) {
00024 adoptData(data,length);
00025 m_ownData=0;
00026 }
00027 CastorCORData::CastorCORData(const CastorCORData& hd) : m_formatVersion(hd.m_formatVersion), m_rawLength(hd.m_rawLength), m_rawConst(hd.m_rawConst), m_ownData(0) { }
00028
00029 CastorCORData::CastorCORData(int version_to_create) : m_formatVersion(version_to_create) {
00030 allocate(version_to_create);
00031 }
00032
00033 void CastorCORData::allocate(int version_to_create) {
00034 m_formatVersion=version_to_create;
00035
00036 const int needed=0x200;
00037
00038 m_ownData=new unsigned short[needed];
00039 m_rawLength=0;
00040 m_rawConst=m_ownData;
00041 }
00042
00043 CastorCORData& CastorCORData::operator=(const CastorCORData& hd) {
00044 if (m_ownData==0) {
00045 m_formatVersion=hd.m_formatVersion;
00046 m_rawLength=hd.m_rawLength;
00047 m_rawConst=hd.m_rawConst;
00048 }
00049 return (*this);
00050 }
00051
00052 void CastorCORData::adoptData(const unsigned short* data, int length) {
00053 m_rawLength=length;
00054 m_rawConst=data;
00055 if (m_rawLength<5) {
00056 m_formatVersion=-2;
00057 } else {
00058 m_formatVersion=(m_rawConst[4]>>12)&0xF;
00059 }
00060 }
00061
00062
00063
00064
00065 bool CastorCORData::check() const {
00066
00067
00068 if (m_rawLength<6+12) return false;
00069
00070 if (m_rawLength!=m_rawConst[m_rawLength-3]) return false;
00071
00072
00073 int tp, daq, header, trailer, trigger;
00074 determineSectionLengths(tp,daq,header,trailer,trigger);
00075 if (trigger+daq+header+trailer>m_rawLength) return false;
00076
00077 return true;
00078 }
00079
00080 void CastorCORData::determineSectionLengths(int& tpWords, int& daqWords, int& headerWords, int& trailerWords, int& triggerLen) const {
00081
00082 tpWords=m_rawConst[5]>>8;
00083 if (m_rawLength>4)
00084 daqWords=m_rawConst[m_rawLength-4]&0x7FF;
00085
00086
00087
00088
00089 headerWords=8;
00090 triggerLen=12;
00091 trailerWords=12;
00092 }
00093
00094 void CastorCORData::determineStaticLengths(int& headerWords, int& trailerWords, int& triggerLen) const {
00095 headerWords=8;
00096 triggerLen=12;
00097 trailerWords=12;
00098
00099 }
00100
00101
00102 void CastorCORData::unpack(unsigned char* daq_lengths, unsigned short* daq_samples,
00103 unsigned char* tp_lengths, unsigned short* tp_samples) const {
00104
00105 if (daq_lengths!=0) memset(daq_lengths,0,CHANNELS_PER_SPIGOT);
00106 if (tp_lengths!=0) memset(tp_lengths,0,1);
00107
00108 int tp_words_total, daq_words_total, headerLen, trailerLen, triggerLen;
00109 determineSectionLengths(tp_words_total,daq_words_total,headerLen,trailerLen,triggerLen);
00110
00111 int wordPtr;
00112 const unsigned short* tpBase=m_rawConst+headerLen;
00113
00114 if (tp_lengths!=0) {
00115 for (wordPtr=0; wordPtr<tp_words_total; wordPtr++) {
00116 tp_samples[tp_lengths[0]]=tpBase[wordPtr];
00117 tp_lengths[0]++;
00118 }
00119 }
00120
00121 const unsigned short* daqBase=m_rawConst+headerLen+triggerLen;
00122 unsigned long dat;
00123
00124 int lastCapid=0;
00125 int ts,dv;
00126 int tsamples = daq_words_total/24;
00127 if (daq_lengths!=0) {
00128 for ( ts = 0; ts < tsamples; ts++ ) {
00129 for (int j=0; j<12 ; j++) {
00130 dat = daqBase[(ts*12+j)*2]<<16 | daqBase[(ts*12+j)*2+1];
00131 dv = ( dat & 0x80000000 ) >> 31;
00132 daq_samples[(j*3) *MAXIMUM_SAMPLES_PER_CHANNEL+ts]= (( dat & 0x40000000 ) >> 20 ) | (( dat & 0x3fe00000 ) >> 21 ) | ( dv << 9 );
00133 daq_samples[(j*3+1)*MAXIMUM_SAMPLES_PER_CHANNEL+ts]= (( dat & 0x00100000 ) >> 10 ) | (( dat & 0x000ff800 ) >> 11 ) | ( dv << 9 );
00134 daq_samples[(j*3+2)*MAXIMUM_SAMPLES_PER_CHANNEL+ts]= (( dat & 0x00000400 ) ) | (( dat & 0x000003fe ) >> 1 ) | ( dv << 9 );
00135 }
00136 }
00137
00138 int ichan;
00139 for ( ichan = 0; ichan<CHANNELS_PER_SPIGOT; ichan++) {
00140 daq_lengths[ichan]=tsamples;
00141 for ( ts = 0; ts < tsamples; ts++ ) {
00142 int erdv =(daq_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+ts] & 0x600 ) >> 9;
00143 int capid=(daq_samples[ichan*MAXIMUM_SAMPLES_PER_CHANNEL+ts] & 0x180 ) >> 7;
00144 if ( erdv!=1 || ( ts!=0 && (capid!=((lastCapid+1)%4)))) {
00145 daq_lengths[ichan]|=0x80;
00146 }
00147 lastCapid=capid;
00148 }
00149 }
00150 }
00151 }
00152
00153 void CastorCORData::pack(unsigned char* daq_lengths, unsigned short* daq_samples,
00154 unsigned char* tp_lengths, unsigned short* tp_samples, bool do_capid) {
00155
00156 int tp_words_total=0, daq_words_total=0, headerLen, trailerLen, triggerLen;
00157 determineStaticLengths(headerLen,trailerLen,triggerLen);
00158
00159 tp_words_total=0;
00160 daq_words_total=0;
00161 int isample;
00162
00163
00164 unsigned short* ptr=m_ownData+headerLen;
00165 if (tp_samples!=0 && tp_lengths!=0) {
00166 for (isample=0; isample<tp_lengths[0] && isample<12; isample++) {
00167 ptr[tp_words_total]=tp_samples[isample];
00168 tp_words_total++;
00169 }
00170 }
00171
00172
00173 ptr=m_ownData+headerLen+triggerLen;
00174 int timesamples = std::min (daq_lengths[0]&0x3f,MAXIMUM_SAMPLES_PER_CHANNEL) ;
00175 int ts, capid, j;
00176 unsigned long dat;
00177 unsigned short s1,s2,s3;
00178 bool somevalid;
00179
00180 for (ts=0; ts<timesamples; ts++){
00181 capid = ts%4;
00182 for (j=0; j<12 ; j++) {
00183 somevalid = false;
00184 if ( daq_lengths[j*3] == 0 || ( daq_lengths[j*3] & 0xc0 ) ) {
00185 s1 = 0x400;
00186 } else {
00187 s1 = daq_samples[(j*3 )*MAXIMUM_SAMPLES_PER_CHANNEL+ts];
00188 somevalid = true;
00189 }
00190 if ( daq_lengths[j*3+1] == 0 || ( daq_lengths[j*3+1] & 0xc0 ) ) {
00191 s2 = 0x400;
00192 } else {
00193 s2 = daq_samples[(j*3+1)*MAXIMUM_SAMPLES_PER_CHANNEL+ts];
00194 somevalid = true;
00195 }
00196 if ( daq_lengths[j*3+2] == 0 || ( daq_lengths[j*3+2] & 0xc0 ) ) {
00197 s3 = 0x400;
00198 } else {
00199 s3 = daq_samples[(j*3+2)*MAXIMUM_SAMPLES_PER_CHANNEL+ts];
00200 somevalid = true;
00201 }
00202
00206
00207
00208
00209
00210
00211
00212 dat = 0x00000001
00213
00214
00215
00216 | ( s1 & 0x1ff ) << 21
00217 | ( s2 & 0x1ff ) << 11
00218 | ( s3 & 0x1ff ) << 1
00219 | ( s1 & 0x400 ) << 20
00220 | ( s2 & 0x400 ) << 10
00221 | ( s3 & 0x400 ) ;
00222 if ( somevalid ) dat |= 0x80000000;
00223
00224 if (do_capid) dat = ( dat & 0xcff3fcff ) | capid << 28 | capid << 18 | capid << 8;
00225 ptr[daq_words_total++] = dat >> 16;
00226 ptr[daq_words_total++] = dat & 0xffff;
00227
00228 }
00229 }
00230
00231 m_ownData[5]=(tp_words_total<<8)|0x1;
00232 unsigned short totalLen=headerLen+12+daq_words_total+trailerLen;
00233
00234 m_rawLength=totalLen;
00235 m_ownData[totalLen-2]=totalLen/2;
00236 m_ownData[totalLen-3]=totalLen;
00237 m_ownData[totalLen-4]=daq_words_total;
00238
00239 }
00240
00241 void CastorCORData::packHeaderTrailer(int L1Anumber, int bcn, int submodule, int orbitn, int pipeline, int ndd, int nps, int firmwareRev) {
00242 m_ownData[0]=L1Anumber&0xFF;
00243 m_ownData[1]=(L1Anumber&0xFFFF00)>>8;
00244
00245 m_ownData[2]=0x8000;
00246 m_ownData[3]=((orbitn&0x1F)<<11)|(submodule&0x7FF);
00247 m_ownData[4]=((m_formatVersion&0xF)<<12)|(bcn&0xFFF);
00248 m_ownData[5]|=((nps&0xF)<<4)|0x1;
00249 m_ownData[6]=((firmwareRev&0x70000)>>3)|(firmwareRev&0x1FFF);
00250 m_ownData[7]=(pipeline&0xFF) | ((ndd&0x1F)<<8);
00251 m_ownData[m_rawLength-4]&=0x7FF;
00252 m_ownData[m_rawLength-4]|=(ndd&0x1F)<<11;
00253
00254 m_ownData[m_rawLength-2]=m_rawLength/2;
00255 m_ownData[m_rawLength-1]=(L1Anumber&0xFF)<<8;
00256 }
00257
00258 unsigned int CastorCORData::getOrbitNumber() const {
00259 return (m_rawConst[3]>>11);
00260 }
00261 unsigned int CastorCORData::getSubmodule() const {
00262 return (m_rawConst[3]&0x7FF);
00263 }
00264 unsigned int CastorCORData::htrSlot() const{
00265 const unsigned int smid = getSubmodule();
00266 return ((smid>>1)&0x1F);
00267 }
00268 unsigned int CastorCORData::htrTopBottom() const{
00269 const unsigned int smid = getSubmodule();
00270 return (smid&0x01);
00271 }
00272 unsigned int CastorCORData::readoutVMECrateId() const{
00273 const unsigned int smid = getSubmodule();
00274 return ((smid>>6)&0x1F);
00275 }
00276 bool CastorCORData::isCalibrationStream() const {
00277 return (m_formatVersion==-1)?(false):(m_rawConst[2]&0x4000);
00278 }
00279 bool CastorCORData::isUnsuppressed() const {
00280 return (m_formatVersion<4)?(false):(m_rawConst[6]&0x8000);
00281 }
00282 bool CastorCORData::wasMarkAndPassZS(int fiber, int fiberchan) const {
00283 if (fiber<1 || fiber>8 || fiberchan<0 || fiberchan>2) return false;
00284 if (!isUnsuppressed() || m_formatVersion<5) return false;
00285 unsigned short val=(fiber<5)?(m_rawConst[m_rawLength-12]):(m_rawConst[m_rawLength-11]);
00286 int shift=(((fiber-1)%4)*3)+fiberchan;
00287 return ((val>>shift)&0x1)!=0;
00288 }
00289
00290 bool CastorCORData::isPatternRAMEvent() const {
00291 return (m_formatVersion==-1)?(false):(m_rawConst[2]&0x1000);
00292 }
00293 bool CastorCORData::isHistogramEvent() const {
00294 return (m_formatVersion==-1)?(m_rawConst[2]&0x2):(m_rawConst[2]&0x2000);
00295 }
00296 int CastorCORData::getNDD() const {
00297 return (m_formatVersion==-1)?(m_rawConst[m_rawLength-4]>>8):(m_rawConst[m_rawLength-4]>>11);
00298 }
00299 int CastorCORData::getNTP() const {
00300 int retval=-1;
00301 if (m_formatVersion==-1) retval=m_rawConst[m_rawLength-4]&0xFF;
00302 else if (m_formatVersion<3) retval=m_rawConst[m_rawLength-4]>>11;
00303 return retval;
00304 }
00305 int CastorCORData::getNPrecisionWords() const {
00306 return (m_formatVersion==-1)?(m_rawConst[m_rawLength-4]&0xFF):(m_rawConst[m_rawLength-4]&0x7FF);
00307 }
00308 int CastorCORData::getNPS() const {
00309 return (m_formatVersion==-1)?(0):((m_rawConst[5]>>4)&0xF);
00310 }
00311 unsigned int CastorCORData::getPipelineLength() const {
00312 return (m_rawConst[7]&0xFF);
00313 }
00314 unsigned int CastorCORData::getFirmwareRevision() const {
00315 return (m_rawConst[6]);
00316 }
00317
00318 void CastorCORData::getHistogramFibers(int& a, int& b) const {
00319 a=-1;
00320 b=-1;
00321 if (m_formatVersion==-1) {
00322 a=((m_rawConst[2]&0x0F00)>>8);
00323 b=((m_rawConst[2]&0xF000)>>12);
00324 } else {
00325 a=((m_rawConst[5]&0x0F00)>>8);
00326 b=((m_rawConst[5]&0xF000)>>12);
00327 }
00328 }
00329
00330 bool CastorCORData::unpackHistogram(int myfiber, int mysc, int capid, unsigned short* histogram) const {
00331
00332 if (!isHistogramEvent()) return false;
00333
00334 int fiber1, fiber2;
00335 getHistogramFibers(fiber1,fiber2);
00336 if (fiber1!=myfiber && fiber2!=myfiber) return false;
00337
00338 if (m_formatVersion==-1) {
00339 int offset=6+mysc*4*32+capid*32;
00340 if (myfiber==fiber2) offset+=3*4*32;
00341 for (int i=0; i<32; i++)
00342 histogram[i]=m_rawConst[offset+i];
00343 return true;
00344 } else {
00345 int offset=8+mysc*4*32+capid*32;
00346 if (myfiber==fiber2) offset+=3*4*32;
00347 for (int i=0; i<32; i++)
00348 histogram[i]=m_rawConst[offset+i];
00349 return true;
00350 }
00351 }
00352