CMS 3D CMS Logo

Public Types | Public Member Functions | Static Public Member Functions | Private Types | Static Private Member Functions

sistrip::SpyDigiConverter Class Reference

Converts scope mode like digis into virgin raw like digis by: -extracting the frame payload, -reordering to physical order and -merging the DetSets indexed by FedKey to DetSets indexed by DetId. More...

#include <SiStripSpyDigiConverter.h>

List of all members.

Public Types

typedef edm::DetSetVector
< SiStripRawDigi
DSVRawDigis

Public Member Functions

 SpyDigiConverter ()
 ~SpyDigiConverter ()

Static Public Member Functions

static std::auto_ptr< DSVRawDigisextractPayloadDigis (const DSVRawDigis *inputScopeDigis, std::vector< uint32_t > *pAPVAddresses, const bool discardDigisWithAPVAddrErr, const sistrip::SpyUtilities::FrameQuality &aQuality, const uint16_t expectedPos)
 Extract frames from the scope digis.
static std::auto_ptr< DSVRawDigismergeModuleChannels (const DSVRawDigis *inputPhysicalOrderChannelDigis, const SiStripFedCabling &cabling)
static std::auto_ptr< DSVRawDigisreorderDigis (const DSVRawDigis *inputPayloadDigis)

Private Types

typedef DSVRawDigis::detset DetSetRawDigis

Static Private Member Functions

static void processFED (const uint16_t aPreviousFedId, const bool discardDigisWithAPVAddrErr, std::vector< uint32_t > *pAPVAddresses, std::vector< DetSetRawDigis > &outputData, std::vector< uint16_t > &aAddrVec, std::vector< uint16_t > &aHeaderBitVec, std::vector< DSVRawDigis::const_iterator > &aFedScopeDigis)

Detailed Description

Converts scope mode like digis into virgin raw like digis by: -extracting the frame payload, -reordering to physical order and -merging the DetSets indexed by FedKey to DetSets indexed by DetId.

Definition at line 25 of file SiStripSpyDigiConverter.h.


Member Typedef Documentation

Definition at line 53 of file SiStripSpyDigiConverter.h.

Definition at line 28 of file SiStripSpyDigiConverter.h.


Constructor & Destructor Documentation

sistrip::SpyDigiConverter::SpyDigiConverter ( ) [inline]

Definition at line 31 of file SiStripSpyDigiConverter.h.

{}
sistrip::SpyDigiConverter::~SpyDigiConverter ( ) [inline]

Definition at line 32 of file SiStripSpyDigiConverter.h.

{}

Member Function Documentation

std::auto_ptr< SpyDigiConverter::DSVRawDigis > sistrip::SpyDigiConverter::extractPayloadDigis ( const DSVRawDigis inputScopeDigis,
std::vector< uint32_t > *  pAPVAddresses,
const bool  discardDigisWithAPVAddrErr,
const sistrip::SpyUtilities::FrameQuality aQuality,
const uint16_t  expectedPos 
) [static]

Extract frames from the scope digis.

If pAPVAddress is set, the map is filled with a map from FedKey to APVAddress. minAllowedRange is the min allowed range of digis when determine the threshold.

Definition at line 24 of file SiStripSpyDigiConverter.cc.

References sistrip::SpyUtilities::Frame::apvAddress, edm::DetSetVector< T >::begin(), edm::DetSetVector< T >::end(), sistrip::SpyUtilities::extractFrameInfo(), sistrip::FED_ID_MAX, sistrip::FEDCH_PER_FED, sistrip::SpyUtilities::Frame::firstHeaderBit, sistrip::SpyUtilities::isValid(), reco::print(), processFED(), edm::DetSetVector< T >::size(), and sistrip::SPY_SAMPLES_PER_CHANNEL.

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

  {
    // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
    std::vector<DetSetRawDigis> outputData;
    outputData.reserve(inputScopeDigis->size());

    //APV address vector indexed by fedid, majority value written.
    pAPVAddresses->resize(sistrip::FED_ID_MAX+1,0);
    std::vector<uint16_t> lAddrVec;
    lAddrVec.reserve(2*sistrip::FEDCH_PER_FED);
    uint16_t lPreviousFedId = 0;
    std::vector<uint16_t> lHeaderBitVec;
    lHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);


    //local DSVRawDigis per FED
    std::vector<DSVRawDigis::const_iterator> lFedScopeDigis;
    lFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);

    // Loop over channels in input collection
    DSVRawDigis::const_iterator inputChannel = inputScopeDigis->begin();
    const DSVRawDigis::const_iterator endChannels = inputScopeDigis->end();
    bool hasBeenProcessed = false;

    for (; inputChannel != endChannels; ++inputChannel) {
            
      // Fill frame parameters. Second parameter is to print debug info (if logDebug enabled....)
      const sistrip::SpyUtilities::Frame lFrame = sistrip::SpyUtilities::extractFrameInfo(*inputChannel,true);

      const uint32_t lFedIndex = inputChannel->detId();
      const uint16_t fedId = static_cast<uint16_t>(lFedIndex/sistrip::FEDCH_PER_FED);
      const uint16_t fedCh = static_cast<uint16_t>(lFedIndex%sistrip::FEDCH_PER_FED);

      if (lPreviousFedId == 0) {
        lPreviousFedId = fedId;
      }

      //print out warning only for non-empty frames....
      if (!sistrip::SpyUtilities::isValid(lFrame,aQuality,expectedPos) && lFrame.firstHeaderBit < sistrip::SPY_SAMPLES_PER_CHANNEL) {
        edm::LogWarning("SiStripSpyDigiConverter") << " FED ID: " << fedId << ", channel: " << fedCh << std::endl
                                                   << sistrip::SpyUtilities::print(lFrame,
                                                                                   std::string("  -- Invalid Frame ")
                                                                                   );

        continue;
      }

      //fill local vectors per FED
      if (fedId == lPreviousFedId) {
        if (hasBeenProcessed) hasBeenProcessed = false;
      }
      if (fedId != lPreviousFedId) {
        SpyDigiConverter::processFED(lPreviousFedId,
                                     discardDigisWithAPVAddrErr,
                                     pAPVAddresses,
                                     outputData,
                                     lAddrVec,
                                     lHeaderBitVec,
                                     lFedScopeDigis
                                     );
        lPreviousFedId = fedId;
        hasBeenProcessed = true;
      }
      lFedScopeDigis.push_back(inputChannel);
      lAddrVec.push_back(lFrame.apvAddress.first);
      lAddrVec.push_back(lFrame.apvAddress.second);
      lHeaderBitVec.push_back(lFrame.firstHeaderBit);


    } // end of loop over channels.

    //process the last one if not already done.
    if (!hasBeenProcessed) {
      SpyDigiConverter::processFED(lPreviousFedId,
                                   discardDigisWithAPVAddrErr,
                                   pAPVAddresses,
                                   outputData,
                                   lAddrVec,
                                   lHeaderBitVec,
                                   lFedScopeDigis
                                   );
    }

    //return DSV of output
    return std::auto_ptr<DSVRawDigis>( new DSVRawDigis(outputData, true) );
    
  } // end of SpyDigiConverter::extractPayloadDigis method
std::auto_ptr< SpyDigiConverter::DSVRawDigis > sistrip::SpyDigiConverter::mergeModuleChannels ( const DSVRawDigis inputPhysicalOrderChannelDigis,
const SiStripFedCabling cabling 
) [static]

Definition at line 206 of file SiStripSpyDigiConverter.cc.

References sistrip::DetSetVectorFiller< T, dsvIsSparse >::addItem(), SiStripFedCabling::connections(), sistrip::DetSetVectorFiller< T, dsvIsSparse >::createDetSetVector(), edm::DetSetVector< T >::end(), sistrip::FED_ID_MAX, sistrip::FED_ID_MIN, sistrip::FEDCH_PER_FED, SiStripFedKey::fedIndex(), SiStripFedCabling::feds(), edm::DetSetVector< T >::find(), sistrip::invalid32_, sistrip::DetSetVectorFiller< T, dsvIsSparse >::newChannel(), and sistrip::STRIPS_PER_FEDCH.

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

  {
    // Create filler for detSetVector to create output (with maximum number of DetSets and digis)
    uint16_t nFeds = static_cast<uint16_t>( FED_ID_MAX - FED_ID_MIN + 1);

    RawDigiDetSetVectorFiller dsvFiller(nFeds*FEDCH_PER_FED/2, nFeds*FEDCH_PER_FED*STRIPS_PER_FEDCH);
    // Loop over FEDs in cabling
    std::vector<uint16_t>::const_iterator iFed = cabling.feds().begin();
    const std::vector<uint16_t>::const_iterator endFeds = cabling.feds().end();
    for (; iFed != endFeds; ++iFed) {
      // Loop over cabled channels
      const std::vector<FedChannelConnection>& conns = cabling.connections(*iFed);
      std::vector<FedChannelConnection>::const_iterator iConn = conns.begin();
      const std::vector<FedChannelConnection>::const_iterator endConns = conns.end();
      for (; iConn != endConns; ++iConn) {
        // Skip channels not connected to a detector.
        if (!iConn->isConnected()) continue;
        if (iConn->detId() == sistrip::invalid32_) continue;
                
        // Find the data from the input collection
        const uint32_t fedIndex = SiStripFedKey::fedIndex(iConn->fedId(),iConn->fedCh());
        const DSVRawDigis::const_iterator iDetSet = inputPhysicalOrderChannelDigis->find(fedIndex);
        if (iDetSet == inputPhysicalOrderChannelDigis->end()) {
          // NOTE: It will display this warning if channel hasn't been unpacked...
          // Will comment out for now.
          //edm::LogWarning("SiStripSpyDigiConverter") << "No data found for FED ID: " << iConn->fedId() << " channel: " << iConn->fedCh();
          continue;
        }
                
        // Start a new channel indexed by the detId in the filler
        dsvFiller.newChannel(iConn->detId(),iConn->apvPairNumber()*STRIPS_PER_FEDCH);
                
        // Add the data
        DetSetRawDigis::const_iterator iDigi = iDetSet->begin();
        const DetSetRawDigis::const_iterator endDetSetDigis = iDetSet->end();
        for (; iDigi != endDetSetDigis; ++iDigi) {
          dsvFiller.addItem(*iDigi);
        } // end of loop over the digis.
      } // end of loop over channels.
    } // end of loop over FEDs
        
    return dsvFiller.createDetSetVector();
  } // end of SpyDigiConverter::mergeModuleChannels method.
void sistrip::SpyDigiConverter::processFED ( const uint16_t  aPreviousFedId,
const bool  discardDigisWithAPVAddrErr,
std::vector< uint32_t > *  pAPVAddresses,
std::vector< DetSetRawDigis > &  outputData,
std::vector< uint16_t > &  aAddrVec,
std::vector< uint16_t > &  aHeaderBitVec,
std::vector< DSVRawDigis::const_iterator > &  aFedScopeDigis 
) [static, private]

Definition at line 117 of file SiStripSpyDigiConverter.cc.

References filterCSVwithJSON::copy, sistrip::FEDCH_PER_FED, sistrip::SpyUtilities::findMajorityValue(), and sistrip::STRIPS_PER_FEDCH.

Referenced by extractPayloadDigis().

  {

    //extract majority address
    uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(aAddrVec,aPreviousFedId).first;
    if (pAPVAddresses) (*pAPVAddresses)[aPreviousFedId] = lMaj;

    //loop over iterators and fill payload
    std::vector<DSVRawDigis::const_iterator>::iterator lIter;
    unsigned int lCh = 0;
    for (lIter = aFedScopeDigis.begin(); lIter != aFedScopeDigis.end(); ++lIter,++lCh) {

      //discard if APV address different from majority. 
      //Keep if only one of them is wrong: the other APV might be alright ??

      if ( discardDigisWithAPVAddrErr && 
           aAddrVec[2*lCh] != lMaj && 
           aAddrVec[2*lCh+1] != lMaj ) {
        continue;
      }

      DetSetRawDigis::const_iterator iDigi = (*lIter)->begin();
      const DetSetRawDigis::const_iterator endOfChannel = (*lIter)->end();

      if (iDigi == endOfChannel) {
        continue;
      }

      //header starts in sample firstHeaderBit and is 18+6 samples long
      const DetSetRawDigis::const_iterator payloadBegin = iDigi+aHeaderBitVec[lCh]+24;
      const DetSetRawDigis::const_iterator payloadEnd = payloadBegin + STRIPS_PER_FEDCH;
              
              
      // Copy data into output collection
      // Create new detSet with same key (in this case it is the fedKey, not detId)
      outputData.push_back( DetSetRawDigis((*lIter)->detId()) );
      std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
      outputDetSetData.resize(STRIPS_PER_FEDCH);
      std::vector<SiStripRawDigi>::iterator outputBegin = outputDetSetData.begin();
      std::copy(payloadBegin, payloadEnd, outputBegin);

    }

    aFedScopeDigis.clear();
    aAddrVec.clear();
    aHeaderBitVec.clear();

    aAddrVec.reserve(2*sistrip::FEDCH_PER_FED);
    aHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);
    aFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);


  }
std::auto_ptr< SpyDigiConverter::DSVRawDigis > sistrip::SpyDigiConverter::reorderDigis ( const DSVRawDigis inputPayloadDigis) [static]

Definition at line 181 of file SiStripSpyDigiConverter.cc.

References edm::DetSetVector< T >::begin(), edm::DetSetVector< T >::end(), sistrip::FEDStripOrdering::physicalOrderForStripInChannel(), edm::DetSetVector< T >::size(), and sistrip::STRIPS_PER_FEDCH.

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

  {
    // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
    std::vector<DetSetRawDigis> outputData;
    outputData.reserve(inputPayloadDigis->size());
    
    // Loop over channels in input collection
    for (DSVRawDigis::const_iterator inputChannel = inputPayloadDigis->begin(); inputChannel != inputPayloadDigis->end(); ++inputChannel) {
      const std::vector<SiStripRawDigi>& inputDetSetData = inputChannel->data;
      // Create new detSet with same key (in this case it is the fedKey, not detId)
      outputData.push_back( DetSetRawDigis(inputChannel->detId()) );
      std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
      outputDetSetData.resize(STRIPS_PER_FEDCH);
      // Copy the data into the output vector reordering
      for (uint16_t readoutOrderStripIndex = 0; readoutOrderStripIndex < inputDetSetData.size(); ++readoutOrderStripIndex) {
        const uint16_t physicalOrderStripIndex = FEDStripOrdering::physicalOrderForStripInChannel(readoutOrderStripIndex);
        outputDetSetData.at(physicalOrderStripIndex) = inputDetSetData.at(readoutOrderStripIndex);
      }
    }
    
    //return DSV of output
    return std::auto_ptr<DSVRawDigis>( new DSVRawDigis(outputData,true) );
  } // end of SpyDigiConverter::reorderDigis method.