CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/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) && lFrame.firstHeaderBit < sistrip::SPY_SAMPLES_PER_CHANNEL) {
00067         edm::LogWarning("SiStripSpyDigiConverter") << " FED ID: " << fedId << ", channel: " << fedCh << std::endl
00068                                                    << sistrip::SpyUtilities::print(lFrame,
00069                                                                                    std::string("  -- Invalid Frame ")
00070                                                                                    );
00071 
00072         continue;
00073       }
00074 
00075       //fill local vectors per FED
00076       if (fedId == lPreviousFedId) {
00077         if (hasBeenProcessed) hasBeenProcessed = false;
00078       }
00079       if (fedId != lPreviousFedId) {
00080         SpyDigiConverter::processFED(lPreviousFedId,
00081                                      discardDigisWithAPVAddrErr,
00082                                      pAPVAddresses,
00083                                      outputData,
00084                                      lAddrVec,
00085                                      lHeaderBitVec,
00086                                      lFedScopeDigis
00087                                      );
00088         lPreviousFedId = fedId;
00089         hasBeenProcessed = true;
00090       }
00091       lFedScopeDigis.push_back(inputChannel);
00092       lAddrVec.push_back(lFrame.apvAddress.first);
00093       lAddrVec.push_back(lFrame.apvAddress.second);
00094       lHeaderBitVec.push_back(lFrame.firstHeaderBit);
00095 
00096 
00097     } // end of loop over channels.
00098 
00099     //process the last one if not already done.
00100     if (!hasBeenProcessed) {
00101       SpyDigiConverter::processFED(lPreviousFedId,
00102                                    discardDigisWithAPVAddrErr,
00103                                    pAPVAddresses,
00104                                    outputData,
00105                                    lAddrVec,
00106                                    lHeaderBitVec,
00107                                    lFedScopeDigis
00108                                    );
00109     }
00110 
00111     //return DSV of output
00112     return std::auto_ptr<DSVRawDigis>( new DSVRawDigis(outputData, true) );
00113     
00114   } // end of SpyDigiConverter::extractPayloadDigis method
00115 
00116 
00117   void SpyDigiConverter::processFED(const uint16_t aPreviousFedId,
00118                                     const bool discardDigisWithAPVAddrErr,
00119                                     std::vector<uint32_t> * pAPVAddresses,
00120                                     std::vector<DetSetRawDigis> & outputData,
00121                                     std::vector<uint16_t> & aAddrVec,
00122                                     std::vector<uint16_t> & aHeaderBitVec,
00123                                     std::vector<DSVRawDigis::const_iterator> & aFedScopeDigis
00124                                     )
00125   {
00126 
00127     //extract majority address
00128     uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(aAddrVec,aPreviousFedId).first;
00129     if (pAPVAddresses) (*pAPVAddresses)[aPreviousFedId] = lMaj;
00130 
00131     //loop over iterators and fill payload
00132     std::vector<DSVRawDigis::const_iterator>::iterator lIter;
00133     unsigned int lCh = 0;
00134     for (lIter = aFedScopeDigis.begin(); lIter != aFedScopeDigis.end(); ++lIter,++lCh) {
00135 
00136       //discard if APV address different from majority. 
00137       //Keep if only one of them is wrong: the other APV might be alright ??
00138 
00139       if ( discardDigisWithAPVAddrErr && 
00140            aAddrVec[2*lCh] != lMaj && 
00141            aAddrVec[2*lCh+1] != lMaj ) {
00142         continue;
00143       }
00144 
00145       DetSetRawDigis::const_iterator iDigi = (*lIter)->begin();
00146       const DetSetRawDigis::const_iterator endOfChannel = (*lIter)->end();
00147 
00148       if (iDigi == endOfChannel) {
00149         continue;
00150       }
00151 
00152       //header starts in sample firstHeaderBit and is 18+6 samples long
00153       const DetSetRawDigis::const_iterator payloadBegin = iDigi+aHeaderBitVec[lCh]+24;
00154       const DetSetRawDigis::const_iterator payloadEnd = payloadBegin + STRIPS_PER_FEDCH;
00155               
00156               
00157       // Copy data into output collection
00158       // Create new detSet with same key (in this case it is the fedKey, not detId)
00159       outputData.push_back( DetSetRawDigis((*lIter)->detId()) );
00160       std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
00161       outputDetSetData.resize(STRIPS_PER_FEDCH);
00162       std::vector<SiStripRawDigi>::iterator outputBegin = outputDetSetData.begin();
00163       std::copy(payloadBegin, payloadEnd, outputBegin);
00164 
00165     }
00166 
00167     aFedScopeDigis.clear();
00168     aAddrVec.clear();
00169     aHeaderBitVec.clear();
00170 
00171     aAddrVec.reserve(2*sistrip::FEDCH_PER_FED);
00172     aHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);
00173     aFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);
00174 
00175 
00176   }
00177 
00178 
00179 
00180 
00181   std::auto_ptr<SpyDigiConverter::DSVRawDigis> SpyDigiConverter::reorderDigis(const DSVRawDigis* inputPayloadDigis)
00182   {
00183     // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
00184     std::vector<DetSetRawDigis> outputData;
00185     outputData.reserve(inputPayloadDigis->size());
00186     
00187     // Loop over channels in input collection
00188     for (DSVRawDigis::const_iterator inputChannel = inputPayloadDigis->begin(); inputChannel != inputPayloadDigis->end(); ++inputChannel) {
00189       const std::vector<SiStripRawDigi>& inputDetSetData = inputChannel->data;
00190       // Create new detSet with same key (in this case it is the fedKey, not detId)
00191       outputData.push_back( DetSetRawDigis(inputChannel->detId()) );
00192       std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
00193       outputDetSetData.resize(STRIPS_PER_FEDCH);
00194       // Copy the data into the output vector reordering
00195       for (uint16_t readoutOrderStripIndex = 0; readoutOrderStripIndex < inputDetSetData.size(); ++readoutOrderStripIndex) {
00196         const uint16_t physicalOrderStripIndex = FEDStripOrdering::physicalOrderForStripInChannel(readoutOrderStripIndex);
00197         outputDetSetData.at(physicalOrderStripIndex) = inputDetSetData.at(readoutOrderStripIndex);
00198       }
00199     }
00200     
00201     //return DSV of output
00202     return std::auto_ptr<DSVRawDigis>( new DSVRawDigis(outputData,true) );
00203   } // end of SpyDigiConverter::reorderDigis method.
00204 
00205   std::auto_ptr<SpyDigiConverter::DSVRawDigis>
00206   SpyDigiConverter::mergeModuleChannels(const DSVRawDigis* inputPhysicalOrderChannelDigis, 
00207                                         const SiStripFedCabling& cabling)
00208   {
00209     // Create filler for detSetVector to create output (with maximum number of DetSets and digis)
00210     uint16_t nFeds = static_cast<uint16_t>( FED_ID_MAX - FED_ID_MIN + 1);
00211 
00212     RawDigiDetSetVectorFiller dsvFiller(nFeds*FEDCH_PER_FED/2, nFeds*FEDCH_PER_FED*STRIPS_PER_FEDCH);
00213     // Loop over FEDs in cabling
00214     std::vector<uint16_t>::const_iterator iFed = cabling.feds().begin();
00215     const std::vector<uint16_t>::const_iterator endFeds = cabling.feds().end();
00216     for (; iFed != endFeds; ++iFed) {
00217       // Loop over cabled channels
00218       const std::vector<FedChannelConnection>& conns = cabling.connections(*iFed);
00219       std::vector<FedChannelConnection>::const_iterator iConn = conns.begin();
00220       const std::vector<FedChannelConnection>::const_iterator endConns = conns.end();
00221       for (; iConn != endConns; ++iConn) {
00222         // Skip channels not connected to a detector.
00223         if (!iConn->isConnected()) continue;
00224         if (iConn->detId() == sistrip::invalid32_) continue;
00225                 
00226         // Find the data from the input collection
00227         const uint32_t fedIndex = SiStripFedKey::fedIndex(iConn->fedId(),iConn->fedCh());
00228         const DSVRawDigis::const_iterator iDetSet = inputPhysicalOrderChannelDigis->find(fedIndex);
00229         if (iDetSet == inputPhysicalOrderChannelDigis->end()) {
00230           // NOTE: It will display this warning if channel hasn't been unpacked...
00231           // Will comment out for now.
00232           //edm::LogWarning("SiStripSpyDigiConverter") << "No data found for FED ID: " << iConn->fedId() << " channel: " << iConn->fedCh();
00233           continue;
00234         }
00235                 
00236         // Start a new channel indexed by the detId in the filler
00237         dsvFiller.newChannel(iConn->detId(),iConn->apvPairNumber()*STRIPS_PER_FEDCH);
00238                 
00239         // Add the data
00240         DetSetRawDigis::const_iterator iDigi = iDetSet->begin();
00241         const DetSetRawDigis::const_iterator endDetSetDigis = iDetSet->end();
00242         for (; iDigi != endDetSetDigis; ++iDigi) {
00243           dsvFiller.addItem(*iDigi);
00244         } // end of loop over the digis.
00245       } // end of loop over channels.
00246     } // end of loop over FEDs
00247         
00248     return dsvFiller.createDetSetVector();
00249   } // end of SpyDigiConverter::mergeModuleChannels method.
00250 
00251 
00252 
00253 } // end of sistrip namespace.