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