00001 #include "EventFilter/CastorRawToDigi/interface/CastorPacker.h"
00002 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00003 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
00004 #include "DataFormats/HcalDetId/interface/HcalGenericDetId.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00007 #include "EventFilter/Utilities/interface/Crc.h"
00008
00009 CastorPacker::Collections::Collections() {
00010 castorCont=0;
00011 tpCont=0;
00012 calibCont=0;
00013 }
00014
00015 template <class Coll, class DetIdClass>
00016 int process(const Coll* pt, const DetId& did, unsigned short* buffer, int& presamples) {
00017 if (pt==0) return 0;
00018 int size=0;
00019 typename Coll::const_iterator i=pt->find(DetIdClass(did));
00020 if (i!=pt->end()) {
00021 presamples=i->presamples();
00022 size=i->size();
00023 for (int j=0; j<size; j++)
00024 buffer[j]=(*i)[j].raw();
00025 }
00026 return size;
00027 }
00028
00029 int CastorPacker::findSamples(const DetId& did, const Collections& inputs,
00030 unsigned short* buffer, int &presamples) {
00031
00032 if (did.det()!=DetId::Calo) return 0;
00033 int size=0;
00034 HcalCastorDetId genId(did);
00035
00036 size=process<CastorDigiCollection,HcalCastorDetId>(inputs.castorCont,did,buffer,presamples);
00037
00038 return size;
00039 }
00040
00041 void CastorPacker::pack(int fedid, int dccnumber,
00042 int nl1a, int orbitn, int bcn,
00043 const Collections& inputs,
00044 const CastorElectronicsMap& emap,
00045 FEDRawData& output) {
00046 std::vector<unsigned short> precdata(HcalHTRData::CHANNELS_PER_SPIGOT*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
00047 std::vector<unsigned short> trigdata(HcalHTRData::CHANNELS_PER_SPIGOT*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
00048 std::vector<unsigned char> preclen(HcalHTRData::CHANNELS_PER_SPIGOT);
00049 std::vector<unsigned char> triglen(HcalHTRData::CHANNELS_PER_SPIGOT);
00050 static const int HTRFormatVersion=3;
00051
00052 HcalHTRData spigots[15];
00053
00054 for (int spigot=0; spigot<15; spigot++) {
00055 spigots[spigot].allocate(HTRFormatVersion);
00056 CastorElectronicsId exampleEId;
00057 int npresent=0;
00058 int presamples=-1, samples=-1;
00059 for (int fiber=1; fiber<=8; fiber++)
00060 for (int fiberchan=0; fiberchan<3; fiberchan++) {
00061 int linear=(fiber-1)*3+fiberchan;
00062 HcalQIESample chanSample(0,0,fiber,fiberchan,false,false);
00063 unsigned short chanid=chanSample.raw()&0xF800;
00064 preclen[linear]=0;
00065
00066 CastorElectronicsId partialEid(fiberchan,fiber,spigot,dccnumber);
00067
00068 CastorElectronicsId fullEid;
00069 HcalGenericDetId genId;
00070 if (!emap.lookup(partialEid,fullEid,genId)) continue;
00071
00072
00073 unsigned short* database=&(precdata[linear*HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL]);
00074 int mypresamples;
00075 int mysamples=findSamples(genId,inputs,database,mypresamples);
00076
00077 if (mysamples>0) {
00078 if (samples<0) samples=mysamples;
00079 else if (samples!=mysamples) {
00080 edm::LogError("CASTOR") << "Mismatch of samples in a single HTR (unsupported) " << mysamples << " != " << samples;
00081 continue;
00082 }
00083 if (presamples<0) {
00084 presamples=mypresamples;
00085 exampleEId=fullEid;
00086 } else if (mypresamples!=presamples) {
00087 edm::LogError("CASTOR") << "Mismatch of presamples in a single HTR (unsupported) " << mypresamples << " != " << presamples;
00088 continue;
00089 }
00090 for (int ii=0; ii<samples; ii++)
00091 database[ii]=(database[ii]&0x7FF)|chanid;
00092 preclen[linear]=(unsigned char)(samples);
00093 npresent++;
00094 }
00095 }
00097 if (npresent>0) {
00098 spigots[spigot].pack(&(preclen[0]),&(precdata[0]),
00099 &(triglen[0]),&(trigdata[0]),
00100 false);
00101 static const int pipeline=0x22;
00102 static const int firmwareRev=0;
00103 int submodule=exampleEId.htrTopBottom()&0x1;
00104 submodule|=(exampleEId.htrSlot()&0x1F)<<1;
00105 submodule|=(exampleEId.readoutVMECrateId()&0x1f)<<6;
00106 spigots[spigot].packHeaderTrailer(nl1a,
00107 bcn,
00108 submodule,
00109 orbitn,
00110 pipeline,
00111 samples,
00112 presamples,
00113 firmwareRev);
00114
00115 }
00116 }
00117
00118 int theSize=0;
00119 for (int spigot=0; spigot<15; spigot++) {
00120 theSize+=spigots[spigot].getRawLength()*sizeof(unsigned short);
00121 }
00122 theSize+=sizeof(HcalDCCHeader)+8;
00123 theSize+=(8-(theSize%8))%8;
00124 output.resize(theSize);
00125
00126
00127 HcalDCCHeader* dcc=(HcalDCCHeader*)(output.data());
00128 dcc->clear();
00129 dcc->setHeader(fedid,bcn,nl1a,orbitn);
00130
00131
00132 for (int spigot=0; spigot<15; spigot++) {
00133 if (spigots[spigot].getRawLength()>0)
00134 dcc->copySpigotData(spigot,spigots[spigot],true,0);
00135 }
00136
00137 FEDTrailer fedTrailer(output.data()+(output.size()-8));
00138 fedTrailer.set(output.data()+(output.size()-8),
00139 output.size()/8,
00140 evf::compute_crc(output.data(),output.size()), 0, 0);
00141
00142 }