Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:21

0001 #include "EventFilter/CastorRawToDigi/interface/CastorCtdcPacker.h"
0002 #include "EventFilter/CastorRawToDigi/interface/CastorCORData.h"
0003 #include "EventFilter/CastorRawToDigi/interface/CastorMergerData.h"
0004 #include "EventFilter/CastorRawToDigi/interface/CastorCTDCHeader.h"
0005 #include "DataFormats/HcalDetId/interface/HcalGenericDetId.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0008 #include "FWCore/Utilities/interface/CRC16.h"
0009 #include "EventFilter/CastorRawToDigi/interface/CastorCollections.h"
0010 #include <iostream>
0011 
0012 using namespace std;
0013 
0014 namespace {
0015   template <class Coll, class DetIdClass>
0016   int process(const Coll* pt, const DetId& did, unsigned short* buffer, int& presamples) {
0017     if (pt == nullptr)
0018       return 0;
0019     int size = 0;
0020     typename Coll::const_iterator i = pt->find(DetIdClass(did));
0021     if (i != pt->end()) {
0022       presamples = i->presamples();
0023       size = i->size();
0024       for (int j = 0; j < size; j++)
0025         buffer[j] = (*i)[j].raw();
0026     }
0027     return size;
0028   }
0029 }  // namespace
0030 
0031 int CastorCtdcPacker::findSamples(const DetId& did,
0032                                   const CastorCollections& inputs,
0033                                   unsigned short* buffer,
0034                                   int& presamples) {
0035   if (did.det() != DetId::Calo)
0036     return 0;
0037   int size = 0;
0038   HcalCastorDetId genId(did);
0039 
0040   size = process<CastorDigiCollection, HcalCastorDetId>(inputs.castorCont, did, buffer, presamples);
0041 
0042   return size;
0043 }
0044 
0045 void CastorCtdcPacker::pack(int fedid,
0046                             int dccnumber,
0047                             int nl1a,
0048                             int orbitn,
0049                             int bcn,
0050                             const CastorCollections& inputs,
0051                             const CastorElectronicsMap& emap,
0052                             FEDRawData& output) {
0053   std::vector<unsigned short> precdata(CastorCORData::CHANNELS_PER_SPIGOT * CastorCORData::MAXIMUM_SAMPLES_PER_CHANNEL);
0054   std::vector<unsigned short> trigdata(CastorCORData::CHANNELS_PER_SPIGOT * CastorCORData::MAXIMUM_SAMPLES_PER_CHANNEL);
0055   std::vector<unsigned char> preclen(CastorCORData::CHANNELS_PER_SPIGOT);
0056   std::vector<unsigned char> triglen(CastorCORData::CHANNELS_PER_SPIGOT);
0057   constexpr int CORFormatVersion = 1;
0058 
0059   //  CastorCORData spigots[CastorCTDCHeader::SPIGOT_COUNT];
0060   CastorCORData spigots[2];
0061   // loop over all valid channels in the given ctdc, spigot by spigot.
0062   for (int spigot = 0; spigot < CastorCTDCHeader::SPIGOT_COUNT; spigot++) {
0063     spigots[spigot].allocate(CORFormatVersion);
0064     CastorElectronicsId exampleEId;
0065     int npresent = 0;
0066     int presamples = -1, samples = -1;
0067     for (int fiber = 1; fiber <= 12; fiber++)
0068       for (int fiberchan = 0; fiberchan < 3; fiberchan++) {
0069         int linear = (fiber - 1) * 3 + fiberchan;
0070         //  HcalQIESample chanSample(0,0,fiber,fiberchan,false,false);
0071         //  unsigned short chanid=chanSample.raw()&0xF800;
0072         preclen[linear] = 0;
0073         CastorElectronicsId partialEid(fiberchan, fiber, spigot, dccnumber);
0074         // does this partial id exist?
0075         CastorElectronicsId fullEid;
0076         HcalGenericDetId genId;
0077         if (!emap.lookup(partialEid, fullEid, genId))
0078           continue;
0079 
0080         // next, see if there is a digi with this id
0081         unsigned short* database = &(precdata[linear * CastorCORData::MAXIMUM_SAMPLES_PER_CHANNEL]);
0082         int mypresamples;
0083         int mysamples = findSamples(genId, inputs, database, mypresamples);
0084         if (mysamples > 0) {
0085           if (samples < 0)
0086             samples = mysamples;
0087           else if (samples != mysamples) {
0088             edm::LogError("CASTOR") << "Mismatch of samples in a single COR (unsupported) " << mysamples
0089                                     << " != " << samples;
0090             continue;
0091           }
0092           if (presamples < 0) {
0093             presamples = mypresamples;
0094             exampleEId = fullEid;
0095           } else if (mypresamples != presamples) {
0096             edm::LogError("CASTOR") << "Mismatch of presamples in a single COR (unsupported) " << mypresamples
0097                                     << " != " << presamples;
0098             continue;
0099           }
0100           preclen[linear] = (unsigned char)(samples);
0101           npresent++;
0102         }
0103       }
0104     /// pack into CastorCORData
0105     if (npresent > 0) {
0106       spigots[spigot].pack(&(preclen[0]), &(precdata[0]), &(triglen[0]), &(trigdata[0]), true);
0107       constexpr int pipeline = 0x22;
0108       constexpr int firmwareRev = 0;
0109       int submodule = exampleEId.htrTopBottom() & 0x1;
0110       submodule |= (exampleEId.htrSlot() & 0x1F) << 1;
0111       submodule |= (exampleEId.readoutVMECrateId() & 0x1f) << 6;
0112       spigots[spigot].packHeaderTrailer(nl1a, bcn, submodule, orbitn, pipeline, samples, presamples, firmwareRev);
0113     }
0114   }
0115   // calculate the total length, and resize the FEDRawData
0116   int theSize = 0;
0117   for (int spigot = 0; spigot < 2; spigot++) {
0118     theSize += spigots[spigot].getRawLength() * sizeof(unsigned short);
0119   }
0120   // the merger payload - not yet defined
0121   CastorMergerData mergerdata;
0122   // would need to fill mergdata here
0123   theSize += mergerdata.getRawLength() * sizeof(unsigned short);
0124 
0125   theSize += sizeof(CastorCTDCHeader) + 8;  // 8 for trailer
0126   theSize += (8 - (theSize % 8)) % 8;       // even number of 64-bit words.
0127   output.resize(theSize);
0128 
0129   // construct the bare CTDC Header
0130   CastorCTDCHeader* dcc = (CastorCTDCHeader*)(output.data());
0131   dcc->clear();
0132   dcc->setHeader(fedid, bcn, nl1a, orbitn);
0133 
0134   // pack the HTR data into the FEDRawData block using CastorCTDCHeader
0135   for (int spigot = 0; spigot < 2; spigot++) {
0136     if (spigots[spigot].getRawLength() > 0)
0137       dcc->copySpigotData(spigot, spigots[spigot], true, 0);
0138   }
0139   if (mergerdata.getRawLength() > 0)
0140     dcc->copyMergerData(mergerdata, true);
0141   // trailer
0142   FEDTrailer fedTrailer(output.data() + (output.size() - 8));
0143   fedTrailer.set(
0144       output.data() + (output.size() - 8), output.size() / 8, evf::compute_crc(output.data(), output.size()), 0, 0);
0145 }