Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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