CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DQM/SiStripMonitorHardware/src/SiStripSpyDigiConverter.cc

Go to the documentation of this file.
00001 #include <vector>
00002 
00003 #include "FWCore/Utilities/interface/Exception.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 
00006 #include "DataFormats/Common/interface/DetSetVector.h"
00007 #include "DataFormats/Common/interface/DetSet.h"
00008 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
00009 #include "DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h"
00010 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00011 
00012 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
00013 #include "CondFormats/SiStripObjects/interface/FedChannelConnection.h"
00014 
00015 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
00016 #include "EventFilter/SiStripRawToDigi/interface/SiStripDetSetVectorFiller.h"
00017 
00018 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
00019 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyDigiConverter.h"
00020 
00021 namespace sistrip {
00022 
00023   std::auto_ptr<SpyDigiConverter::DSVRawDigis> 
00024   SpyDigiConverter::extractPayloadDigis(const DSVRawDigis* inputScopeDigis,
00025                                         std::vector<uint32_t> * pAPVAddresses,
00026                                         const bool discardDigisWithAPVAddrErr,
00027                                         const sistrip::SpyUtilities::FrameQuality & aQuality,
00028                                         const uint16_t expectedPos)
00029   {
00030     // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
00031     std::vector<DetSetRawDigis> outputData;
00032     outputData.reserve(inputScopeDigis->size());
00033 
00034     //APV address vector indexed by fedid, majority value written.
00035     pAPVAddresses->resize(sistrip::FED_ID_MAX+1,0);
00036     std::vector<uint16_t> lAddrVec;
00037     lAddrVec.reserve(2*sistrip::FEDCH_PER_FED);
00038     uint16_t lPreviousFedId = 0;
00039     std::vector<uint16_t> lHeaderBitVec;
00040     lHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);
00041 
00042 
00043     //local DSVRawDigis per FED
00044     std::vector<DSVRawDigis::const_iterator> lFedScopeDigis;
00045     lFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);
00046 
00047     // Loop over channels in input collection
00048     DSVRawDigis::const_iterator inputChannel = inputScopeDigis->begin();
00049     const DSVRawDigis::const_iterator endChannels = inputScopeDigis->end();
00050     bool hasBeenProcessed = false;
00051 
00052     for (; inputChannel != endChannels; ++inputChannel) {
00053             
00054       // Fill frame parameters. Second parameter is to print debug info (if logDebug enabled....)
00055       const sistrip::SpyUtilities::Frame lFrame = sistrip::SpyUtilities::extractFrameInfo(*inputChannel,true);
00056 
00057       const uint32_t lFedIndex = inputChannel->detId();
00058       const uint16_t fedId = static_cast<uint16_t>(lFedIndex/sistrip::FEDCH_PER_FED);
00059       const uint16_t fedCh = static_cast<uint16_t>(lFedIndex%sistrip::FEDCH_PER_FED);
00060 
00061       if (lPreviousFedId == 0) {
00062         lPreviousFedId = fedId;
00063       }
00064 
00065       //print out warning only for non-empty frames....
00066       if (!sistrip::SpyUtilities::isValid(lFrame,aQuality,expectedPos)){
00067         //print out only for non-empty frames, else too many prints...
00068         if (lFrame.firstHeaderBit < sistrip::SPY_SAMPLES_PER_CHANNEL) {
00069         edm::LogWarning("SiStripSpyDigiConverter") << " FED ID: " << fedId << ", channel: " << fedCh << std::endl
00070                                                    << sistrip::SpyUtilities::print(lFrame,
00071                                                                                    std::string("  -- Invalid Frame ")
00072                                                                                    );
00073         }
00074 
00075         continue;
00076       }
00077 
00078       //fill local vectors per FED
00079       if (fedId == lPreviousFedId) {
00080         if (hasBeenProcessed) hasBeenProcessed = false;
00081       }
00082       if (fedId != lPreviousFedId) {
00083         SpyDigiConverter::processFED(lPreviousFedId,
00084                                      discardDigisWithAPVAddrErr,
00085                                      pAPVAddresses,
00086                                      outputData,
00087                                      lAddrVec,
00088                                      lHeaderBitVec,
00089                                      lFedScopeDigis
00090                                      );
00091         lPreviousFedId = fedId;
00092         hasBeenProcessed = true;
00093       }
00094       lFedScopeDigis.push_back(inputChannel);
00095       lAddrVec.push_back(lFrame.apvAddress.first);
00096       lAddrVec.push_back(lFrame.apvAddress.second);
00097       lHeaderBitVec.push_back(lFrame.firstHeaderBit);
00098 
00099 
00100     } // end of loop over channels.
00101 
00102     //process the last one if not already done.
00103     if (!hasBeenProcessed) {
00104       SpyDigiConverter::processFED(lPreviousFedId,
00105                                    discardDigisWithAPVAddrErr,
00106                                    pAPVAddresses,
00107                                    outputData,
00108                                    lAddrVec,
00109                                    lHeaderBitVec,
00110                                    lFedScopeDigis
00111                                    );
00112     }
00113 
00114     //return DSV of output
00115     return std::auto_ptr<DSVRawDigis>( new DSVRawDigis(outputData, true) );
00116     
00117   } // end of SpyDigiConverter::extractPayloadDigis method
00118 
00119 
00120   void SpyDigiConverter::processFED(const uint16_t aPreviousFedId,
00121                                     const bool discardDigisWithAPVAddrErr,
00122                                     std::vector<uint32_t> * pAPVAddresses,
00123                                     std::vector<DetSetRawDigis> & outputData,
00124                                     std::vector<uint16_t> & aAddrVec,
00125                                     std::vector<uint16_t> & aHeaderBitVec,
00126                                     std::vector<DSVRawDigis::const_iterator> & aFedScopeDigis
00127                                     )
00128   {
00129 
00130     //extract majority address
00131     uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(aAddrVec,aPreviousFedId).first;
00132     if (pAPVAddresses) (*pAPVAddresses)[aPreviousFedId] = lMaj;
00133 
00134     //loop over iterators and fill payload
00135     std::vector<DSVRawDigis::const_iterator>::iterator lIter;
00136     unsigned int lCh = 0;
00137     for (lIter = aFedScopeDigis.begin(); lIter != aFedScopeDigis.end(); ++lIter,++lCh) {
00138 
00139       //discard if APV address different from majority. 
00140       //Keep if only one of them is wrong: the other APV might be alright ??
00141 
00142       if ( discardDigisWithAPVAddrErr && 
00143            aAddrVec[2*lCh] != lMaj && 
00144            aAddrVec[2*lCh+1] != lMaj ) {
00145         continue;
00146       }
00147 
00148       DetSetRawDigis::const_iterator iDigi = (*lIter)->begin();
00149       const DetSetRawDigis::const_iterator endOfChannel = (*lIter)->end();
00150 
00151       if (iDigi == endOfChannel) {
00152         continue;
00153       }
00154 
00155       //header starts in sample firstHeaderBit and is 18+6 samples long
00156       const DetSetRawDigis::const_iterator payloadBegin = iDigi+aHeaderBitVec[lCh]+24;
00157       const DetSetRawDigis::const_iterator payloadEnd = payloadBegin + STRIPS_PER_FEDCH;
00158               
00159               
00160       // Copy data into output collection
00161       // Create new detSet with same key (in this case it is the fedKey, not detId)
00162       outputData.push_back( DetSetRawDigis((*lIter)->detId()) );
00163       std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
00164       outputDetSetData.resize(STRIPS_PER_FEDCH);
00165       std::vector<SiStripRawDigi>::iterator outputBegin = outputDetSetData.begin();
00166       std::copy(payloadBegin, payloadEnd, outputBegin);
00167 
00168     }
00169 
00170     aFedScopeDigis.clear();
00171     aAddrVec.clear();
00172     aHeaderBitVec.clear();
00173 
00174     aAddrVec.reserve(2*sistrip::FEDCH_PER_FED);
00175     aHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);
00176     aFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);
00177 
00178 
00179   }
00180 
00181 
00182 
00183 
00184   std::auto_ptr<SpyDigiConverter::DSVRawDigis> SpyDigiConverter::reorderDigis(const DSVRawDigis* inputPayloadDigis)
00185   {
00186     // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
00187     std::vector<DetSetRawDigis> outputData;
00188     outputData.reserve(inputPayloadDigis->size());
00189     
00190     // Loop over channels in input collection
00191     for (DSVRawDigis::const_iterator inputChannel = inputPayloadDigis->begin(); inputChannel != inputPayloadDigis->end(); ++inputChannel) {
00192       const std::vector<SiStripRawDigi>& inputDetSetData = inputChannel->data;
00193       // Create new detSet with same key (in this case it is the fedKey, not detId)
00194       outputData.push_back( DetSetRawDigis(inputChannel->detId()) );
00195       std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
00196       outputDetSetData.resize(STRIPS_PER_FEDCH);
00197       // Copy the data into the output vector reordering
00198       for (uint16_t readoutOrderStripIndex = 0; readoutOrderStripIndex < inputDetSetData.size(); ++readoutOrderStripIndex) {
00199         const uint16_t physicalOrderStripIndex = FEDStripOrdering::physicalOrderForStripInChannel(readoutOrderStripIndex);
00200         outputDetSetData.at(physicalOrderStripIndex) = inputDetSetData.at(readoutOrderStripIndex);
00201       }
00202     }
00203     
00204     //return DSV of output
00205     return std::auto_ptr<DSVRawDigis>( new DSVRawDigis(outputData,true) );
00206   } // end of SpyDigiConverter::reorderDigis method.
00207 
00208   std::auto_ptr<SpyDigiConverter::DSVRawDigis>
00209   SpyDigiConverter::mergeModuleChannels(const DSVRawDigis* inputPhysicalOrderChannelDigis, 
00210                                         const SiStripFedCabling& cabling)
00211   {
00212     // Create filler for detSetVector to create output (with maximum number of DetSets and digis)
00213     uint16_t nFeds = static_cast<uint16_t>( FED_ID_MAX - FED_ID_MIN + 1);
00214 
00215     RawDigiDetSetVectorFiller dsvFiller(nFeds*FEDCH_PER_FED/2, nFeds*FEDCH_PER_FED*STRIPS_PER_FEDCH);
00216     // Loop over FEDs in cabling
00217     std::vector<uint16_t>::const_iterator iFed = cabling.feds().begin();
00218     const std::vector<uint16_t>::const_iterator endFeds = cabling.feds().end();
00219     for (; iFed != endFeds; ++iFed) {
00220       // Loop over cabled channels
00221       const std::vector<FedChannelConnection>& conns = cabling.connections(*iFed);
00222       std::vector<FedChannelConnection>::const_iterator iConn = conns.begin();
00223       const std::vector<FedChannelConnection>::const_iterator endConns = conns.end();
00224       for (; iConn != endConns; ++iConn) {
00225         // Skip channels not connected to a detector.
00226         if (!iConn->isConnected()) continue;
00227         if (iConn->detId() == sistrip::invalid32_) continue;
00228                 
00229         // Find the data from the input collection
00230         const uint32_t fedIndex = SiStripFedKey::fedIndex(iConn->fedId(),iConn->fedCh());
00231         const DSVRawDigis::const_iterator iDetSet = inputPhysicalOrderChannelDigis->find(fedIndex);
00232         if (iDetSet == inputPhysicalOrderChannelDigis->end()) {
00233           // NOTE: It will display this warning if channel hasn't been unpacked...
00234           // Will comment out for now.
00235           //edm::LogWarning("SiStripSpyDigiConverter") << "No data found for FED ID: " << iConn->fedId() << " channel: " << iConn->fedCh();
00236           continue;
00237         }
00238                 
00239         // Start a new channel indexed by the detId in the filler
00240         dsvFiller.newChannel(iConn->detId(),iConn->apvPairNumber()*STRIPS_PER_FEDCH);
00241                 
00242         // Add the data
00243         DetSetRawDigis::const_iterator iDigi = iDetSet->begin();
00244         const DetSetRawDigis::const_iterator endDetSetDigis = iDetSet->end();
00245         for (; iDigi != endDetSetDigis; ++iDigi) {
00246           dsvFiller.addItem(*iDigi);
00247         } // end of loop over the digis.
00248       } // end of loop over channels.
00249     } // end of loop over FEDs
00250         
00251     return dsvFiller.createDetSetVector();
00252   } // end of SpyDigiConverter::mergeModuleChannels method.
00253 
00254 
00255 
00256 } // end of sistrip namespace.