Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
/** \file
 *
 *  \author  M. Zanetti - INFN Padova
 * FRC 060906
 */

#include "DataFormats/FEDRawData/interface/FEDHeader.h"
#include "DataFormats/FEDRawData/interface/FEDTrailer.h"
#include "DataFormats/DTDigi/interface/DTDDUWords.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "EventFilter/DTRawToDigi/plugins/DTDDUUnpacker.h"

#include <iostream>

using namespace std;
using namespace edm;

DTDDUUnpacker::DTDDUUnpacker(const edm::ParameterSet& ps) : dduPSet(ps) {
  // the ROS unpacker
  ros25Unpacker = new DTROS25Unpacker(dduPSet.getParameter<edm::ParameterSet>("rosParameters"));

  // parameters
  localDAQ = dduPSet.getUntrackedParameter<bool>("localDAQ", false);
  debug = dduPSet.getUntrackedParameter<bool>("debug", false);
}

DTDDUUnpacker::~DTDDUUnpacker() { delete ros25Unpacker; }

void DTDDUUnpacker::interpretRawData(const unsigned int* index32,
                                     int datasize,
                                     int dduID,
                                     edm::ESHandle<DTReadOutMapping>& mapping,
                                     std::unique_ptr<DTDigiCollection>& detectorProduct,
                                     std::unique_ptr<DTLocalTriggerCollection>& triggerProduct,
                                     uint16_t rosList) {
  // Definitions
  const int wordSize_32 = 4;
  const int wordSize_64 = 8;

  int numberOf32Words = datasize / wordSize_32;

  const unsigned char* index8 = reinterpret_cast<const unsigned char*>(index32);

  //////////////////////
  /*  D D U   d a t a */
  //////////////////////

  // DDU header
  FEDHeader dduHeader(index8);
  if (dduHeader.check()) {
    if (debug)
      cout << "[DTDDUUnpacker] FED Header. BXID: " << dduHeader.bxID() << " L1ID: " << dduHeader.lvl1ID() << endl;
  } else {
    LogWarning("DTRawToDigi|DTDDUUnpacker")
        << "[DTDDUUnpacker] WARNING!, this is not a DDU Header, FED ID: " << dduID << endl;
  }

  // DDU trailer
  // [BITS] stop before FED trailer := 8 bytes
  FEDTrailer dduTrailer(index8 + datasize - 1 * wordSize_64);

  if (dduTrailer.check()) {
    if (debug)
      cout << "[DTDDUUnpacker] FED Trailer. Length of the DT event: " << dduTrailer.fragmentLength() << endl;
  } else {
    LogWarning("DTRawToDigi|DTDDUUnpacker")
        << "[DTDDUUnpacker] WARNING!, this is not a DDU Trailer, FED ID: " << dduID << endl;
  }

  // Initialize control data
  controlData.clean();
  controlData.addDDUHeader(dduHeader);
  controlData.addDDUTrailer(dduTrailer);
  // check the CRC set in the FED trailer (FCRC errors)
  controlData.checkCRCBit(index8 + datasize - 1 * wordSize_64);

  // Check Status Words
  vector<DTDDUFirstStatusWord> rosStatusWords;
  // [BITS] 3 words of 8 bytes + "rosId" bytes
  // In the case we are reading from DMA, the status word are swapped as the ROS data
  if (localDAQ) {
    // DDU channels from 1 to 4
    for (int rosId = 0; rosId < 4; rosId++) {
      int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + wordSize_32 + rosId;
      controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
    }
    // DDU channels from 5 to 8
    for (int rosId = 0; rosId < 4; rosId++) {
      int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + rosId;
      controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
    }
    // DDU channels from 9 to 12
    for (int rosId = 0; rosId < 4; rosId++) {
      int wordIndex8 = numberOf32Words * wordSize_32 - 2 * wordSize_64 + wordSize_32 + rosId;
      controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
    }
  } else {
    for (int rosId = 0; rosId < 12; rosId++) {
      int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + rosId;
      controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
    }
  }

  int theROSList;
  // [BITS] 2 words of 8 bytes + 4 bytes (half 64 bit word)
  // In the case we are reading from DMA, the status word are swapped as the ROS data
  if (localDAQ) {
    DTDDUSecondStatusWord dduStatusWord(index32[numberOf32Words - 2 * wordSize_64 / wordSize_32]);
    controlData.addDDUStatusWord(dduStatusWord);
    theROSList = dduStatusWord.rosList();
  } else {
    DTDDUSecondStatusWord dduStatusWord(index32[numberOf32Words - 2 * wordSize_64 / wordSize_32 + 1]);
    controlData.addDDUStatusWord(dduStatusWord);
    theROSList = dduStatusWord.rosList();
  }

  //////////////////////
  /*  R O S   d a t a */
  //////////////////////

  // Set the index to start looping on ROS data
  // [BITS] one 8 bytes word
  index32 += (wordSize_64) / wordSize_32;

  // Set the datasize to look only at ROS data
  // [BITS] header, trailer, 2 status words
  datasize -= 4 * wordSize_64;

  // unpacking the ROS payload
  ros25Unpacker->interpretRawData(index32, datasize, dduID, mapping, detectorProduct, triggerProduct, theROSList);
}