00001 #include "EventFilter/CastorRawToDigi/interface/CastorUnpacker.h"
00002 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
00003 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00004 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
00005 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
00006 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
00007 #include "DataFormats/HcalDigi/interface/CastorDataFrame.h"
00008 #include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveSample.h"
00009 #include <iostream>
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011
00012 namespace CastorUnpacker_impl {
00013 template <class DigiClass>
00014 const HcalQIESample* unpack(const HcalQIESample* startPoint, const HcalQIESample* limit, DigiClass& digi, int presamples, const CastorElectronicsId& eid, int startSample, int endSample, int expectedTime, const HcalHTRData& hhd) {
00015
00016 digi.setPresamples(presamples);
00017 int fiber=startPoint->fiber();
00018 int fiberchan=startPoint->fiberChan();
00019 uint32_t zsmask=hhd.zsBunchMask()>>startSample;
00020 digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
00021
00022
00023
00024 if (expectedTime>=0 && !hhd.isUnsuppressed()) {
00025
00026 digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber)-expectedTime);
00027 }
00028
00029 int myFiberChan=startPoint->fiberAndChan();
00030 int ncurr=0,ntaken=0;
00031 const HcalQIESample* qie_work=startPoint;
00032 while (qie_work!=limit && qie_work->fiberAndChan()==myFiberChan) {
00033 if (ncurr>=startSample && ncurr<=endSample) {
00034 digi.setSample(ntaken,*qie_work);
00035 ++ntaken;
00036 }
00037 ncurr++;
00038 qie_work++;
00039 }
00040 digi.setSize(ntaken);
00041 return qie_work;
00042 }
00043 }
00044
00045 namespace { inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) {
00046 return (s.raw()&0x200)!=0;
00047 }
00048 }
00049
00050
00051 CastorUnpacker::CastorUnpacker(int sourceIdOffset, int beg, int end) : sourceIdOffset_(sourceIdOffset) , expectedOrbitMessageTime_(-1)
00052 {
00053 if ( beg >= 0 && beg <= CastorDataFrame::MAXSAMPLES -1 ) {
00054 startSample_ = beg;
00055 } else {
00056 startSample_ = 0;
00057 }
00058 if ( end >= 0 && end <= CastorDataFrame::MAXSAMPLES -1 && end >= beg ) {
00059 endSample_ = end;
00060 } else {
00061 endSample_ = CastorDataFrame::MAXSAMPLES -1;
00062 }
00063 }
00064
00065
00066 void CastorUnpacker::unpack(const FEDRawData& raw, const CastorElectronicsMap& emap,
00067 CastorRawCollections& colls, HcalUnpackerReport& report, bool silent) {
00068
00069 if (raw.size()<16) {
00070 if (!silent) edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
00071 return;
00072 }
00073
00074
00075 const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00076 int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00077
00078
00079
00080
00081 HcalHTRData htr;
00082 const unsigned short* daq_first, *daq_last, *tp_first, *tp_last;
00083 const HcalQIESample* qie_begin, *qie_end, *qie_work;
00084 const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work;
00085 for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00086 if (!dccHeader->getSpigotPresent(spigot)) continue;
00087
00088 int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00089 if (retval!=0) {
00090 if (retval==-1) {
00091 if (!silent) edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00092 report.countSpigotFormatError();
00093 }
00094 continue;
00095 }
00096
00097 if (dccHeader->getSpigotCRCError(spigot)) {
00098 if (!silent)
00099 edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00100 report.countSpigotFormatError();
00101 continue;
00102 }
00103 if (!htr.check()) {
00104 if (!silent)
00105 edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00106 report.countSpigotFormatError();
00107 continue;
00108 }
00109 if (htr.isHistogramEvent()) {
00110 if (!silent)
00111 edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00112 continue;
00113
00114 }
00115 if ((htr.getFirmwareFlavor()&0xE0)==0x80) {
00116 if (colls.ttp!=0) {
00117 HcalTTPUnpacker ttpUnpack;
00118 colls.ttp->push_back(HcalTTPDigi());
00119 ttpUnpack.unpack(htr,colls.ttp->back());
00120 } else {
00121 LogDebug("CastorUnpackerHcalTechTrigProcessor") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is from the TechTrigProcessor (use separate unpacker!)";
00122 }
00123 continue;
00124 }
00125 if (htr.getFirmwareFlavor()>=0x80) {
00126 if (!silent) edm::LogWarning("CastorUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is of unknown flavor " << htr.getFirmwareFlavor();
00127 continue;
00128 }
00129
00130 int nps=htr.getNPS()-startSample_;
00131
00132
00133 htr.dataPointers(&daq_first,&daq_last,&tp_first,&tp_last);
00134 unsigned int smid=htr.getSubmodule();
00135 int htr_tb=smid&0x1;
00136 int htr_slot=(smid>>1)&0x1F;
00137 int htr_cr=(smid>>6)&0x1F;
00138
00139 tp_begin=(HcalTriggerPrimitiveSample*)tp_first;
00140 tp_end=(HcalTriggerPrimitiveSample*)(tp_last+1);
00141
00143 int currFiberChan=0x3F;
00144 int ncurr=0;
00145 bool valid=false;
00147 bool tpgSOIbitInUse=htr.getFormatVersion()>=3;
00148
00149 int npre=0;
00150
00151
00152
00153
00154 bool dotp = true;
00155 CastorElectronicsId eid(0,1,spigot,dccid);
00156 eid.setHTR(htr_cr,htr_slot,htr_tb);
00157 DetId did=emap.lookup(eid);
00158 if ( did.null() ) dotp = false;
00159 HcalCastorDetId id1(did);
00160 HcalCastorDetId id((id1.zside()==0),id1.sector(),1);
00161 if ( id1.module() > 12 ) dotp = false;
00162 if ( dotp ) {
00163
00164
00165 for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00166
00167 if (tp_work->raw()==0xFFFF) continue;
00168 if (tp_work->slbAndChan()!=currFiberChan) {
00169 npre=0;
00170 currFiberChan=tp_work->slbAndChan();
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00186
00187
00188
00189
00190 colls.tpCont->push_back(CastorTriggerPrimitiveDigi(id));
00191
00192 if (!tpgSOIbitInUse) colls.tpCont->back().setPresamples(nps);
00193 colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),htr.wasMarkAndPassZSTP(tp_work->slb(),tp_work->slbChan()));
00194
00195
00196 ncurr=0;
00197 valid=true;
00198 }
00199
00200 if (valid && ((tpgSOIbitInUse && ncurr<10) || (ncurr>=startSample_ && ncurr<=endSample_))) {
00201 colls.tpCont->back().setSample(colls.tpCont->back().size(),*tp_work);
00202 colls.tpCont->back().setSize(colls.tpCont->back().size()+1);
00203 }
00204
00205 if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
00206 colls.tpCont->back().setPresamples(ncurr);
00207 }
00208 ncurr++;
00209 npre++;
00210 }
00211 }
00212
00214 qie_begin=(HcalQIESample*)daq_first;
00215 qie_end=(HcalQIESample*)(daq_last+1);
00216
00218 currFiberChan=0x3F;
00219 ncurr=0;
00220 valid=false;
00221
00222 for (qie_work=qie_begin; qie_work!=qie_end; ) {
00223 if (qie_work->raw()==0xFFFF) {
00224 qie_work++;
00225 continue;
00226 }
00227
00228 currFiberChan=qie_work->fiberAndChan();
00229
00230
00231 CastorElectronicsId eid(qie_work->fiberChan(),qie_work->fiber(),spigot,dccid);
00232 eid.setHTR(htr_cr,htr_slot,htr_tb);
00233 DetId did=emap.lookup(eid);
00234
00235 if (!did.null()) {
00236 colls.castorCont->push_back(CastorDataFrame(HcalCastorDetId(did)));
00237 qie_work=CastorUnpacker_impl::unpack<CastorDataFrame>(qie_work, qie_end, colls.castorCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00238 } else {
00239 report.countUnmappedDigi();
00240 if (unknownIds_.find(eid)==unknownIds_.end()) {
00241 if (!silent)
00242 edm::LogWarning("CASTOR") << "CastorUnpacker: No match found for electronics id :" << eid;
00243 unknownIds_.insert(eid);
00244 }
00245 for (int fiberC=qie_work->fiberAndChan();
00246 qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00247 qie_work++);
00248 }
00249 }
00250 }
00251 }
00252