Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:08:50

0001 #include <memory>
0002 
0003 #include <vector>
0004 
0005 #include "FWCore/Utilities/interface/Exception.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 
0008 #include "DataFormats/Common/interface/DetSetVector.h"
0009 #include "DataFormats/Common/interface/DetSet.h"
0010 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
0011 #include "DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h"
0012 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
0013 
0014 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0015 #include "CondFormats/SiStripObjects/interface/FedChannelConnection.h"
0016 
0017 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
0018 #include "EventFilter/SiStripRawToDigi/interface/SiStripDetSetVectorFiller.h"
0019 
0020 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
0021 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyDigiConverter.h"
0022 
0023 namespace sistrip {
0024 
0025   std::unique_ptr<SpyDigiConverter::DSVRawDigis> SpyDigiConverter::extractPayloadDigis(
0026       const DSVRawDigis* inputScopeDigis,
0027       std::vector<uint32_t>* pAPVAddresses,
0028       const bool discardDigisWithAPVAddrErr,
0029       const sistrip::SpyUtilities::FrameQuality& aQuality,
0030       const uint16_t expectedPos) {
0031     // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
0032     std::vector<DetSetRawDigis> outputData;
0033     outputData.reserve(inputScopeDigis->size());
0034 
0035     //APV address vector indexed by fedid, majority value written.
0036     pAPVAddresses->resize(sistrip::FED_ID_MAX + 1, 0);
0037     std::vector<uint16_t> lAddrVec;
0038     lAddrVec.reserve(2 * sistrip::FEDCH_PER_FED);
0039     uint16_t lPreviousFedId = 0;
0040     std::vector<uint16_t> lHeaderBitVec;
0041     lHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);
0042     std::vector<uint16_t> lTrailBitVec;
0043     lTrailBitVec.reserve(sistrip::FEDCH_PER_FED);
0044 
0045     //local DSVRawDigis per FED
0046     std::vector<DSVRawDigis::const_iterator> lFedScopeDigis;
0047     lFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);
0048 
0049     // Loop over channels in input collection
0050     DSVRawDigis::const_iterator inputChannel = inputScopeDigis->begin();
0051     const DSVRawDigis::const_iterator endChannels = inputScopeDigis->end();
0052     bool hasBeenProcessed = false;
0053 
0054     for (; inputChannel != endChannels; ++inputChannel) {
0055       const uint32_t lFedIndex = inputChannel->detId();
0056       const uint16_t fedId = static_cast<uint16_t>((lFedIndex >> 16) & 0xFFFF);
0057 
0058       // Fill frame parameters. Second parameter is to print debug info (if logDebug enabled....)
0059       const sistrip::SpyUtilities::Frame lFrame = sistrip::SpyUtilities::extractFrameInfo(*inputChannel, false);
0060 
0061       if (lPreviousFedId == 0) {
0062         lPreviousFedId = fedId;
0063       }
0064 
0065       //print out warning only for non-empty frames....
0066       if (!sistrip::SpyUtilities::isValid(lFrame, aQuality, expectedPos)) {
0067         if (lFrame.firstHeaderBit < sistrip::SPY_SAMPLES_PER_CHANNEL) {
0068           //  edm::LogWarning("SiStripSpyDigiConverter") << " FED ID: " << fedId << ", channel: " << fedCh << std::endl
0069           //                             << sistrip::SpyUtilities::print(lFrame,
0070           //                                             std::string("  -- Invalid Frame ")
0071           //                                             );
0072         }
0073         continue;
0074       }
0075 
0076       //fill local vectors per FED
0077       if (fedId == lPreviousFedId) {
0078         if (hasBeenProcessed)
0079           hasBeenProcessed = false;
0080       }
0081       if (fedId != lPreviousFedId) {
0082         SpyDigiConverter::processFED(lPreviousFedId,
0083                                      discardDigisWithAPVAddrErr,
0084                                      pAPVAddresses,
0085                                      outputData,
0086                                      lAddrVec,
0087                                      lHeaderBitVec,
0088                                      lTrailBitVec,
0089                                      lFedScopeDigis);
0090         lPreviousFedId = fedId;
0091         hasBeenProcessed = true;
0092       }
0093       // add digis
0094       lFedScopeDigis.push_back(inputChannel);
0095       lAddrVec.push_back(lFrame.apvAddress.first);
0096       lAddrVec.push_back(lFrame.apvAddress.second);
0097       lHeaderBitVec.push_back(lFrame.firstHeaderBit);
0098       lTrailBitVec.push_back(lFrame.firstTrailerBit);
0099 
0100     }  // end of loop over channels.
0101 
0102     //process the last one if not already done.
0103     if (!hasBeenProcessed) {
0104       SpyDigiConverter::processFED(lPreviousFedId,
0105                                    discardDigisWithAPVAddrErr,
0106                                    pAPVAddresses,
0107                                    outputData,
0108                                    lAddrVec,
0109                                    lHeaderBitVec,
0110                                    lTrailBitVec,
0111                                    lFedScopeDigis);
0112     }
0113 
0114     //return DSV of output
0115     return std::make_unique<DSVRawDigis>(outputData, true);
0116 
0117   }  // end of SpyDigiConverter::extractPayloadDigis method
0118 
0119   void SpyDigiConverter::processFED(const uint16_t aPreviousFedId,
0120                                     const bool discardDigisWithAPVAddrErr,
0121                                     std::vector<uint32_t>* pAPVAddresses,
0122                                     std::vector<DetSetRawDigis>& outputData,
0123                                     std::vector<uint16_t>& aAddrVec,
0124                                     std::vector<uint16_t>& aHeaderBitVec,
0125                                     std::vector<uint16_t>& aTrailBitVec,
0126                                     std::vector<DSVRawDigis::const_iterator>& aFedScopeDigis) {
0127     //extract majority address
0128     uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(aAddrVec, aPreviousFedId).first;
0129     if (pAPVAddresses)
0130       (*pAPVAddresses)[aPreviousFedId] = lMaj;
0131 
0132     //loop over iterators and fill payload
0133     std::vector<DSVRawDigis::const_iterator>::iterator lIter;
0134     unsigned int lCh = 0;
0135     for (lIter = aFedScopeDigis.begin(); lIter != aFedScopeDigis.end(); ++lIter, ++lCh) {
0136       //discard if APV address different from majority.
0137       //Keep if only one of them is wrong: the other APV might be alright ??
0138 
0139       if (discardDigisWithAPVAddrErr && aAddrVec[2 * lCh] != lMaj && aAddrVec[2 * lCh + 1] != lMaj) {
0140         continue;
0141       }
0142 
0143       DetSetRawDigis::const_iterator iDigi = (*lIter)->begin();
0144       const DetSetRawDigis::const_iterator endOfChannel = (*lIter)->end();
0145 
0146       if (iDigi == endOfChannel) {
0147         continue;
0148       }
0149 
0150       //header starts in sample firstHeaderBit and is 18+6 samples long
0151       const DetSetRawDigis::const_iterator payloadBegin = iDigi + aHeaderBitVec[lCh] + 24;
0152       const DetSetRawDigis::const_iterator payloadEnd = payloadBegin + STRIPS_PER_FEDCH;
0153 
0154       if (payloadEnd - iDigi >= endOfChannel - iDigi)
0155         continue;  // few-cases where this is possible, i.e. nothing above frame-threhsold
0156 
0157       // Copy data into output collection
0158       // Create new detSet with same key (in this case it is the fedKey, not detId)
0159       outputData.push_back(DetSetRawDigis((*lIter)->detId()));
0160       std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
0161       outputDetSetData.resize(STRIPS_PER_FEDCH);
0162       std::vector<SiStripRawDigi>::iterator outputBegin = outputDetSetData.begin();
0163       std::copy(payloadBegin, payloadEnd, outputBegin);
0164     }
0165 
0166     aFedScopeDigis.clear();
0167     aAddrVec.clear();
0168     aHeaderBitVec.clear();
0169     aTrailBitVec.clear();
0170 
0171     aAddrVec.reserve(2 * sistrip::FEDCH_PER_FED);
0172     aHeaderBitVec.reserve(sistrip::FEDCH_PER_FED);
0173     aTrailBitVec.reserve(sistrip::FEDCH_PER_FED);
0174     aFedScopeDigis.reserve(sistrip::FEDCH_PER_FED);
0175   }
0176 
0177   std::unique_ptr<SpyDigiConverter::DSVRawDigis> SpyDigiConverter::reorderDigis(const DSVRawDigis* inputPayloadDigis) {
0178     // Data is already sorted so push back fast into vector to avoid sorts and create DSV later
0179     std::vector<DetSetRawDigis> outputData;
0180     outputData.reserve(inputPayloadDigis->size());
0181 
0182     // Loop over channels in input collection
0183     for (DSVRawDigis::const_iterator inputChannel = inputPayloadDigis->begin();
0184          inputChannel != inputPayloadDigis->end();
0185          ++inputChannel) {
0186       const std::vector<SiStripRawDigi>& inputDetSetData = inputChannel->data;
0187       outputData.push_back(DetSetRawDigis(inputChannel->detId()));
0188       std::vector<SiStripRawDigi>& outputDetSetData = outputData.back().data;
0189       outputDetSetData.resize(STRIPS_PER_FEDCH);
0190       // Copy the data into the output vector reordering
0191       for (uint16_t readoutOrderStripIndex = 0; readoutOrderStripIndex < inputDetSetData.size();
0192            ++readoutOrderStripIndex) {
0193         const uint16_t physicalOrderStripIndex =
0194             FEDStripOrdering::physicalOrderForStripInChannel(readoutOrderStripIndex);
0195         outputDetSetData.at(physicalOrderStripIndex) = inputDetSetData.at(readoutOrderStripIndex);
0196       }
0197     }
0198 
0199     //return DSV of output
0200     return std::make_unique<DSVRawDigis>(outputData, true);
0201   }  // end of SpyDigiConverter::reorderDigis method.
0202 
0203   std::unique_ptr<SpyDigiConverter::DSVRawDigis> SpyDigiConverter::mergeModuleChannels(
0204       const DSVRawDigis* inputPhysicalOrderChannelDigis, const SiStripFedCabling& cabling) {
0205     // Create filler for detSetVector to create output (with maximum number of DetSets and digis)
0206     uint16_t nFeds = static_cast<uint16_t>(FED_ID_MAX - FED_ID_MIN + 1);
0207 
0208     RawDigiDetSetVectorFiller dsvFiller(nFeds * FEDCH_PER_FED / 2, nFeds * FEDCH_PER_FED * STRIPS_PER_FEDCH);
0209     // Loop over FEDs in cabling
0210     auto iFed = cabling.fedIds().begin();
0211     auto endFeds = cabling.fedIds().end();
0212     for (; iFed != endFeds; ++iFed) {
0213       // Loop over cabled channels
0214       auto conns = cabling.fedConnections(*iFed);
0215       auto iConn = conns.begin();
0216       auto endConns = conns.end();
0217       for (; iConn != endConns; ++iConn) {
0218         // Skip channels not connected to a detector.
0219         if (!iConn->isConnected())
0220           continue;
0221         if (iConn->detId() == sistrip::invalid32_)
0222           continue;
0223 
0224         // Find the data from the input collection
0225         const uint32_t fedIndex = ((iConn->fedId() & sistrip::invalid_) << 16) | (iConn->fedCh() & sistrip::invalid_);
0226         const DSVRawDigis::const_iterator iDetSet = inputPhysicalOrderChannelDigis->find(fedIndex);
0227         if (iDetSet == inputPhysicalOrderChannelDigis->end()) {
0228           // NOTE: It will display this warning if channel hasn't been unpacked...
0229           // Will comment out for now.
0230           //edm::LogWarning("SiStripSpyDigiConverter") << "No data found for FED ID: " << iConn->fedId() << " channel: " << iConn->fedCh();
0231           continue;
0232         }
0233 
0234         // Start a new channel indexed by the detId in the filler
0235         dsvFiller.newChannel(iConn->detId(), iConn->apvPairNumber() * STRIPS_PER_FEDCH);
0236 
0237         // Add the data
0238         DetSetRawDigis::const_iterator iDigi = iDetSet->begin();
0239         const DetSetRawDigis::const_iterator endDetSetDigis = iDetSet->end();
0240         for (; iDigi != endDetSetDigis; ++iDigi) {
0241           dsvFiller.addItem(*iDigi);
0242         }  // end of loop over the digis.
0243       }    // end of loop over channels.
0244     }      // end of loop over FEDs
0245 
0246     return dsvFiller.createDetSetVector();
0247   }  // end of SpyDigiConverter::mergeModuleChannels method.
0248 
0249 }  // namespace sistrip