CMS 3D CMS Logo

Public Types | Public Member Functions | Private Attributes

sistrip::SpyUnpacker Class Reference

Unpacks spy channel data into scope mode-like digis. More...

#include <SiStripSpyUnpacker.h>

List of all members.

Public Types

typedef std::vector< uint32_t > Counters
typedef edm::DetSetVector
< SiStripRawDigi
RawDigis

Public Member Functions

void createDigis (const SiStripFedCabling &, const FEDRawDataCollection &, RawDigis *pDigis, const std::vector< uint32_t > &ids, Counters *pTotalEventCounts, Counters *pL1ACounts, uint32_t *aRunRef)
 Creates the scope mode digis for the supplied FED IDs or detIds and stores event counters.
 SpyUnpacker (const bool allowIncompleteEvents)
 Constructor.
 ~SpyUnpacker ()
 Destructor.

Private Attributes

const bool allowIncompleteEvents_

Detailed Description

Unpacks spy channel data into scope mode-like digis.

Author:
Nick Cripps
Date:
Autumn 2009

TODO: Implement unpacking by detID.

--- Modifications: ------ A.-M. Magnan, 11/03/10: change Counters map to vectors: ------ save space and provide faster access to elements. ------ A.-M. Magnan, 25/02/10: add run number to the event ------ A.-M. Magnan, 13/01/10: change Counters map to be keyed by fedid

Definition at line 31 of file SiStripSpyUnpacker.h.


Member Typedef Documentation

typedef std::vector<uint32_t> sistrip::SpyUnpacker::Counters

Definition at line 35 of file SiStripSpyUnpacker.h.

Definition at line 34 of file SiStripSpyUnpacker.h.


Constructor & Destructor Documentation

sistrip::SpyUnpacker::SpyUnpacker ( const bool  allowIncompleteEvents)

Constructor.

Definition at line 29 of file SiStripSpyUnpacker.cc.

References edm::isDebugEnabled(), and LogTrace.

                                                           :
    allowIncompleteEvents_(allowIncompleteEvents)
  {
    if ( edm::isDebugEnabled() ) {
      LogTrace("SiStripSpyUnpacker")
        << "[sistrip::SpyUnpacker::"<<__func__<<"]"
        <<" Constructing object...";
    }
  } // end of SpyUnpacker constructor.
sistrip::SpyUnpacker::~SpyUnpacker ( )

Destructor.

Definition at line 39 of file SiStripSpyUnpacker.cc.

References edm::isDebugEnabled(), and LogTrace.

                            {
    if ( edm::isDebugEnabled() ) {
      LogTrace("SiStripSpyUnpacker")
        << "[sistrip::SpyUnpacker::"<<__func__<<"]"
        << " Destructing object...";
    }
  } // end of SpyUnpacker destructor.

Member Function Documentation

void sistrip::SpyUnpacker::createDigis ( const SiStripFedCabling cabling,
const FEDRawDataCollection buffers,
RawDigis pDigis,
const std::vector< uint32_t > &  ids,
Counters pTotalEventCounts,
Counters pL1ACounts,
uint32_t *  aRunRef 
)

Creates the scope mode digis for the supplied FED IDs or detIds and stores event counters.

If FED IDs are supplied (useFedId=true), unpacks all channels found in the cabling with data. If an empty vector of IDs is supplied, it unpacks all it can find in the FEDRawDataCollection.

Definition at line 47 of file SiStripSpyUnpacker.cc.

References sistrip::FEDSpyChannelUnpacker::adc(), sistrip::DetSetVectorFiller< T, dsvIsSparse >::addItem(), allowIncompleteEvents_, SiStripFedCabling::connections(), sistrip::DetSetVectorFiller< T, dsvIsSparse >::createDetSetVector(), FEDRawData::data(), Exception, sistrip::FED_ID_MAX, sistrip::FED_ID_MIN, sistrip::FEDCH_PER_FED, FEDRawDataCollection::FEDData(), SiStripFedKey::fedIndex(), SiStripFedCabling::feds(), sistrip::FEDSpyChannelUnpacker::hasData(), collect_tpl::input, edm::isDebugEnabled(), combine::key, sistrip::DetSetVectorFiller< T, dsvIsSparse >::newChannel(), FEDRawData::size(), sistrip::SPY_SAMPLES_PER_CHANNEL, edm::DetSetVector< T >::swap(), and cms::Exception::what().

Referenced by sistrip::SpyUnpackerModule::produce().

  {
    //create DSV filler to fill output

    //As of Feb 2010, bug in DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h: 
    //number of feds=max-min+1 (440...). Corrected in head of DataFormats/SiStripCommon package.

    uint16_t nFeds = static_cast<uint16_t>( FED_ID_MAX - FED_ID_MIN + 1);
    
    RawDigiDetSetVectorFiller dsvFiller(nFeds*FEDCH_PER_FED,nFeds*FEDCH_PER_FED*SPY_SAMPLES_PER_CHANNEL);
        
    //check if FEDs found in cabling map and event data
    if ( edm::isDebugEnabled() ) {
      if ( cabling.feds().empty() ) {
        edm::LogWarning("SiStripSpyUnpacker")
          << "[sistrip::SpyUnpacker::" << __func__ << "]"
          << " No FEDs found in cabling map!";
      }
    }
 
    //retrieve FED ids from cabling map and iterate through 
    std::vector<uint32_t>::const_iterator     ifed = ids.begin();
    std::vector<uint32_t>::const_iterator   endfed = ids.end();

    //reference value for run number
    //encoded per fed but should be the same for all feds
    uint32_t lRef = 0;

    //initialise counter vectors to FED_ID_MAX+1
    pTotalEventCounts->resize(FED_ID_MAX+1,0);
    pL1ACounts->resize(FED_ID_MAX+1,0);
    
    for ( ; ifed != endfed; ++ifed ) {

      uint32_t lFedId = (*ifed);

      //check the fedid is valid:
      if (lFedId < FED_ID_MIN || lFedId > FED_ID_MAX) {
        if ( edm::isDebugEnabled() ) {
          edm::LogWarning("SiStripSpyUnpacker")
            << "[sistrip::SpyUnpacker::" << __func__ << "]"
            << " Invalid FED id provided: " 
            << lFedId;
        }
        continue;
      }

      //retrieve FED raw data for given FED 
      const FEDRawData& input = buffers.FEDData( static_cast<int>(lFedId) );
      //check on FEDRawData pointer
      if ( !input.data() ) {
        if ( edm::isDebugEnabled() ) {
          edm::LogWarning("SiStripSpyUnpacker")
            << "[sistrip::SpyUnpacker::" << __func__ << "]"
            << " NULL pointer to FEDRawData for FED id " 
            << lFedId;
        }
        continue;
      }
      //check on FEDRawData size
      if ( !input.size() ) {
        if ( edm::isDebugEnabled() ) {
          edm::LogWarning("SiStripSpyUnpacker")
            << "[sistrip::SpyUnpacker::" << __func__ << "]"
            << " FEDRawData has zero size for FED id " 
            << lFedId;
        }
        continue;
      }
          
      //get the cabling connections for this FED
      const std::vector<FedChannelConnection>& conns = cabling.connections(lFedId);
          
      //construct FEDBuffer
      std::auto_ptr<sistrip::FEDSpyBuffer> buffer;
      try {
        buffer.reset(new sistrip::FEDSpyBuffer(input.data(),input.size()));
        if (!buffer->doChecks() && !allowIncompleteEvents_) {
          throw cms::Exception("FEDSpyBuffer") << "FED Buffer check fails for FED ID " << lFedId << ".";
        }
      } catch (const cms::Exception& e) { 
        if ( edm::isDebugEnabled() ) {
          edm::LogWarning("SiStripSpyUnpacker")
            << "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": " << e.what();
        }
        continue;
      } // end of buffer reset try.
        
      // Get the event counter values
      uint32_t totalEvCount = buffer->spyHeaderTotalEventCount();
      uint32_t l1ID         = buffer->spyHeaderL1ID(); 

      uint32_t lGRun = buffer->globalRunNumber();

      //for the first fed, put it as reference value for others
      if (lRef == 0) lRef = lGRun;
      if (lGRun != lRef){
        edm::LogError("SiStripSpyUnpacker")
          << " -- Global run encoded in buffer for FED " << lFedId << ": " 
          << lGRun << " is different from reference value " << lRef 
          << std::endl;
      }

      // Add event counters
      (*pL1ACounts)[lFedId] = l1ID;
      (*pTotalEventCounts)[lFedId] = totalEvCount;

      //iterate through FED channels, extract payload and create Digis
      std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
      std::vector<FedChannelConnection>::const_iterator endconn = conns.end();
      for ( ; iconn != endconn; ++iconn ) {

        //check if fed connection is valid
        if ( !iconn->isConnected()) { continue; }

        //FED channel
        uint16_t chan = iconn->fedCh();

        //check values are valid:
        if (chan > FEDCH_PER_FED || iconn->fedId() != lFedId){
          if (edm::isDebugEnabled()) {
            std::ostringstream ss;
            ss << "Channel connection values invalid: iconn->fedId() = " << iconn->fedId() << " for FED " << lFedId << ", iconn->fedCh() = " << chan << std::endl;
            edm::LogWarning("SiStripSpyUnpacker") << ss.str();
          }
          continue;
        }

        //check FED channel
        if (!buffer->channelGood(chan)) {
          if (edm::isDebugEnabled()) {
            std::ostringstream ss;
            ss << "Channel check failed for FED " << lFedId << " channel " << chan << std::endl;
            edm::LogWarning("SiStripSpyUnpacker") << ss.str();
          }
          continue;
        }
        //determine key from cabling
        const uint32_t key = SiStripFedKey::fedIndex(lFedId,chan);

        // Start a new channel in the filler
        dsvFiller.newChannel(key);
        // Create the unpacker object
        sistrip::FEDSpyChannelUnpacker unpacker = sistrip::FEDSpyChannelUnpacker(buffer->channel(chan));

        // Unpack the data into dsv filler
        while (unpacker.hasData()) {
          dsvFiller.addItem(unpacker.adc());
          unpacker++;
        }
      } // end of channel loop

    } //fed loop
    
    //set the run number
    *aRunRef = lRef;

    //create DSV to return
    std::auto_ptr<RawDigis> pResult = dsvFiller.createDetSetVector();
    pDigis->swap(*pResult);

  } // end of SpyUnpacker::createDigis method.

Member Data Documentation

Definition at line 53 of file SiStripSpyUnpacker.h.

Referenced by createDigis().