CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/DQM/SiStripMonitorHardware/src/SiStripSpyUnpacker.cc

Go to the documentation of this file.
00001 /* \file SiStripSpyUnpacker.cc
00002  * \brief Source code for the SpyChannel unpacking factory.
00003  */
00004 #include "FWCore/Utilities/interface/Exception.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 
00007 #include "DataFormats/Common/interface/DetSetVector.h"
00008 #include "DataFormats/Common/interface/DetSet.h"
00009 
00010 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
00011 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00012 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00013 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00014 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
00015 
00016 #include "EventFilter/SiStripRawToDigi/interface/SiStripDetSetVectorFiller.h"
00017 
00018 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
00019 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyUnpacker.h"
00020 
00021 #include <algorithm>
00022 #include <vector>
00023 #include <ext/algorithm>
00024 
00025 using namespace std;
00026 
00027 namespace sistrip {
00028 
00029   SpyUnpacker::SpyUnpacker(const bool allowIncompleteEvents) :
00030     allowIncompleteEvents_(allowIncompleteEvents)
00031   {
00032     if ( edm::isDebugEnabled() ) {
00033       LogTrace("SiStripSpyUnpacker")
00034         << "[sistrip::SpyUnpacker::"<<__func__<<"]"
00035         <<" Constructing object...";
00036     }
00037   } // end of SpyUnpacker constructor.
00038 
00039   SpyUnpacker::~SpyUnpacker() {
00040     if ( edm::isDebugEnabled() ) {
00041       LogTrace("SiStripSpyUnpacker")
00042         << "[sistrip::SpyUnpacker::"<<__func__<<"]"
00043         << " Destructing object...";
00044     }
00045   } // end of SpyUnpacker destructor.
00046 
00047   void SpyUnpacker::createDigis(const SiStripFedCabling& cabling,
00048                                 const FEDRawDataCollection& buffers,
00049                                 RawDigis* pDigis,
00050                                 const std::vector<uint32_t> & ids,
00051                                 Counters* pTotalEventCounts,
00052                                 Counters* pL1ACounts,
00053                                 uint32_t* aRunRef)
00054   {
00055     //create DSV filler to fill output
00056 
00057     //As of Feb 2010, bug in DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h: 
00058     //number of feds=max-min+1 (440...). Corrected in head of DataFormats/SiStripCommon package.
00059 
00060     uint16_t nFeds = static_cast<uint16_t>( FED_ID_MAX - FED_ID_MIN + 1);
00061     
00062     RawDigiDetSetVectorFiller dsvFiller(nFeds*FEDCH_PER_FED,nFeds*FEDCH_PER_FED*SPY_SAMPLES_PER_CHANNEL);
00063         
00064     //check if FEDs found in cabling map and event data
00065     if ( edm::isDebugEnabled() ) {
00066       if ( cabling.feds().empty() ) {
00067         edm::LogWarning("SiStripSpyUnpacker")
00068           << "[sistrip::SpyUnpacker::" << __func__ << "]"
00069           << " No FEDs found in cabling map!";
00070       }
00071     }
00072  
00073     //retrieve FED ids from cabling map and iterate through 
00074     std::vector<uint32_t>::const_iterator     ifed = ids.begin();
00075     std::vector<uint32_t>::const_iterator   endfed = ids.end();
00076 
00077     //reference value for run number
00078     //encoded per fed but should be the same for all feds
00079     uint32_t lRef = 0;
00080 
00081     //initialise counter vectors to FED_ID_MAX+1
00082     pTotalEventCounts->resize(FED_ID_MAX+1,0);
00083     pL1ACounts->resize(FED_ID_MAX+1,0);
00084     
00085     for ( ; ifed != endfed; ++ifed ) {
00086 
00087       uint32_t lFedId = (*ifed);
00088 
00089       //check the fedid is valid:
00090       if (lFedId < FED_ID_MIN || lFedId > FED_ID_MAX) {
00091         if ( edm::isDebugEnabled() ) {
00092           edm::LogWarning("SiStripSpyUnpacker")
00093             << "[sistrip::SpyUnpacker::" << __func__ << "]"
00094             << " Invalid FED id provided: " 
00095             << lFedId;
00096         }
00097         continue;
00098       }
00099 
00100       //retrieve FED raw data for given FED 
00101       const FEDRawData& input = buffers.FEDData( static_cast<int>(lFedId) );
00102       //check on FEDRawData pointer
00103       if ( !input.data() ) {
00104         if ( edm::isDebugEnabled() ) {
00105           edm::LogWarning("SiStripSpyUnpacker")
00106             << "[sistrip::SpyUnpacker::" << __func__ << "]"
00107             << " NULL pointer to FEDRawData for FED id " 
00108             << lFedId;
00109         }
00110         continue;
00111       }
00112       //check on FEDRawData size
00113       if ( !input.size() ) {
00114         if ( edm::isDebugEnabled() ) {
00115           edm::LogWarning("SiStripSpyUnpacker")
00116             << "[sistrip::SpyUnpacker::" << __func__ << "]"
00117             << " FEDRawData has zero size for FED id " 
00118             << lFedId;
00119         }
00120         continue;
00121       }
00122           
00123       //get the cabling connections for this FED
00124       const std::vector<FedChannelConnection>& conns = cabling.connections(lFedId);
00125           
00126       //construct FEDBuffer
00127       std::auto_ptr<sistrip::FEDSpyBuffer> buffer;
00128       try {
00129         buffer.reset(new sistrip::FEDSpyBuffer(input.data(),input.size()));
00130         if (!buffer->doChecks() && !allowIncompleteEvents_) {
00131           throw cms::Exception("FEDSpyBuffer") << "FED Buffer check fails for FED ID " << lFedId << ".";
00132         }
00133       } catch (const cms::Exception& e) { 
00134         if ( edm::isDebugEnabled() ) {
00135           edm::LogWarning("SiStripSpyUnpacker")
00136             << "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": " << e.what();
00137         }
00138         continue;
00139       } // end of buffer reset try.
00140         
00141       // Get the event counter values
00142       uint32_t totalEvCount = buffer->spyHeaderTotalEventCount();
00143       uint32_t l1ID         = buffer->spyHeaderL1ID(); 
00144 
00145       uint32_t lGRun = buffer->globalRunNumber();
00146 
00147       //for the first fed, put it as reference value for others
00148       if (lRef == 0) lRef = lGRun;
00149       if (lGRun != lRef){
00150         edm::LogError("SiStripSpyUnpacker")
00151           << " -- Global run encoded in buffer for FED " << lFedId << ": " 
00152           << lGRun << " is different from reference value " << lRef 
00153           << std::endl;
00154       }
00155 
00156       // Add event counters
00157       (*pL1ACounts)[lFedId] = l1ID;
00158       (*pTotalEventCounts)[lFedId] = totalEvCount;
00159 
00160       //iterate through FED channels, extract payload and create Digis
00161       std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
00162       std::vector<FedChannelConnection>::const_iterator endconn = conns.end();
00163       for ( ; iconn != endconn; ++iconn ) {
00164 
00165         //check if fed connection is valid
00166         if ( !iconn->isConnected()) { continue; }
00167 
00168         //FED channel
00169         uint16_t chan = iconn->fedCh();
00170 
00171         //check values are valid:
00172         if (chan > FEDCH_PER_FED || iconn->fedId() != lFedId){
00173           if (edm::isDebugEnabled()) {
00174             std::ostringstream ss;
00175             ss << "Channel connection values invalid: iconn->fedId() = " << iconn->fedId() << " for FED " << lFedId << ", iconn->fedCh() = " << chan << std::endl;
00176             edm::LogWarning("SiStripSpyUnpacker") << ss.str();
00177           }
00178           continue;
00179         }
00180 
00181         //check FED channel
00182         if (!buffer->channelGood(chan)) {
00183           if (edm::isDebugEnabled()) {
00184             std::ostringstream ss;
00185             ss << "Channel check failed for FED " << lFedId << " channel " << chan << std::endl;
00186             edm::LogWarning("SiStripSpyUnpacker") << ss.str();
00187           }
00188           continue;
00189         }
00190         //determine key from cabling
00191         const uint32_t key = SiStripFedKey::fedIndex(lFedId,chan);
00192 
00193         // Start a new channel in the filler
00194         dsvFiller.newChannel(key);
00195         // Create the unpacker object
00196         sistrip::FEDSpyChannelUnpacker unpacker = sistrip::FEDSpyChannelUnpacker(buffer->channel(chan));
00197 
00198         // Unpack the data into dsv filler
00199         while (unpacker.hasData()) {
00200           dsvFiller.addItem(unpacker.adc());
00201           unpacker++;
00202         }
00203       } // end of channel loop
00204 
00205     } //fed loop
00206     
00207     //set the run number
00208     *aRunRef = lRef;
00209 
00210     //create DSV to return
00211     std::auto_ptr<RawDigis> pResult = dsvFiller.createDetSetVector();
00212     pDigis->swap(*pResult);
00213 
00214   } // end of SpyUnpacker::createDigis method.
00215 
00216 } // end of sistrip namespace.