/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
IORawData/CSCCommissioning/src/CSCFileReader.cc
450 строк
17 KB
Victor
Changes for legacy CSCFileReader FirstReadBug to correct number of events in converted data file
20 май 2021, 09:36
20 май 2021, 09:36
49497dd
Код
Авторство
О чём код?
#include "CSCFileReader.h" #include <cerrno> #include <cstdlib> #include <cstring> #include <IORawData/CSCCommissioning/src/CSCFileReader.h> #include <DataFormats/FEDRawData/interface/FEDHeader.h> #include <DataFormats/FEDRawData/interface/FEDTrailer.h> #include <DataFormats/FEDRawData/interface/FEDNumbering.h> #include <DataFormats/Provenance/interface/EventID.h> #include <DataFormats/Provenance/interface/Timestamp.h> #include <DataFormats/FEDRawData/interface/FEDRawData.h> #include <DataFormats/FEDRawData/interface/FEDRawDataCollection.h> #include <FWCore/ParameterSet/interface/ParameterSet.h> #include <FWCore/Utilities/interface/Exception.h> #include "FWCore/MessageLogger/interface/MessageLogger.h" #include <vector> #include <string> #include <iosfwd> #include <sstream> #include <iostream> #include <algorithm> #define nRUIs 40 #define nFUs 4 CSCFileReader::CSCFileReader(const edm::ParameterSet &pset) { runNumber = pset.getUntrackedParameter<unsigned int>("runNumber", 1); LogDebug("CSCFileReader|ctor") << "Started ..."; // Below some data members are recycled for both cases: RUIs and FUs // this is ok as long as eighter of RUI or FU are are provided in .cfg (not both) nActiveRUIs = 0; nActiveFUs = 0; /// Legacy first read EDM EvendID bug (fixed?). /// Currently disabled to fix number of events with data /// Added as configurable parameter // fFirstReadBug = true; fFirstReadBug = pset.getUntrackedParameter<bool>("FirstReadBug", false); for (int unit = 0; unit < nRUIs; unit++) { std::ostringstream ruiName, fuName; ruiName << "RUI" << (unit < 10 ? "0" : "") << unit << std::ends; fuName << "FU" << unit << std::ends; std::vector<std::string> ruiFiles = pset.getUntrackedParameter<std::vector<std::string> >(ruiName.str().c_str(), std::vector<std::string>(0)); std::vector<std::string> fuFiles = pset.getUntrackedParameter<std::vector<std::string> >(fuName.str().c_str(), std::vector<std::string>(0)); if (ruiFiles.begin() != ruiFiles.end()) nActiveRUIs++; if (fuFiles.begin() != fuFiles.end()) nActiveFUs++; } if (nActiveFUs && nActiveRUIs) throw cms::Exception("CSCFileReader|configuration") << "RUIs and FUs in conflict: either RUI or FU may be defined at a time, not both"; if (!nActiveFUs && !nActiveRUIs) throw cms::Exception("CSCFileReader|configuration") << "Module lacks configuration"; // Get list of RUI input files from cfg file for (int rui = 0; rui < nRUIs && !nActiveFUs; rui++) { std::ostringstream name; name << "RUI" << (rui < 10 ? "0" : "") << rui << std::ends; // Obtain list of files associated with current RUI fileNames[rui] = pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0)); currentFile[rui] = fileNames[rui].begin(); // If list of files is not empty, open first file if (currentFile[rui] != fileNames[rui].end()) { try { RUI[rui].open(currentFile[rui]->c_str()); } catch (std::runtime_error &err) { throw cms::Exception("CSCFileReader") << "InputFileMissing: " << err.what() << " (errno=" << errno << ")"; } nActiveRUIs++; } // Filter out possible corruptions RUI[rui].reject(FileReaderDDU::DDUoversize | FileReaderDDU::FFFF | FileReaderDDU::Unknown); // Do not select anything in particular RUI[rui].select(0); currentL1A[rui] = -1; } // Get list of FU input files from .cfg file for (int fu = 0; fu < nFUs && !nActiveRUIs; fu++) { std::ostringstream name; name << "FU" << fu << std::ends; // Obtain list of files associated with current FU fileNames[fu] = pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0)); currentFile[fu] = fileNames[fu].begin(); // If list of files is not empty, open first file if (currentFile[fu] != fileNames[fu].end()) { try { FU[fu].open(currentFile[fu]->c_str()); } catch (std::runtime_error &err) { throw cms::Exception("CSCFileReader") << "InputFileMissing: " << err.what() << " (errno=" << errno << ")"; } nActiveFUs++; } // Filter out possible corruptions FU[fu].reject(FileReaderDCC::DCCoversize | FileReaderDCC::FFFF | FileReaderDCC::Unknown); // Do not select anything in particular FU[fu].select(0); currentL1A[fu] = -1; } if (nActiveRUIs && !nActiveFUs) { // Assign RUIs to FEDs for (int fed = FEDNumbering::MINCSCFEDID; fed <= FEDNumbering::MAXCSCFEDID; fed++) { std::ostringstream name; name << "FED" << fed << std::ends; std::vector<std::string> rui_list = pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0)); for (std::vector<std::string>::const_iterator rui = rui_list.begin(); rui != rui_list.end(); rui++) FED[fed].push_back((unsigned int)atoi(rui->c_str() + rui->length() - 2)); } for (int fed = FEDNumbering::MINCSCDDUFEDID; fed <= FEDNumbering::MAXCSCDDUFEDID; fed++) { std::ostringstream name; name << "FED" << fed << std::ends; std::vector<std::string> rui_list = pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0)); for (std::vector<std::string>::const_iterator rui = rui_list.begin(); rui != rui_list.end(); rui++) FED[fed].push_back((unsigned int)atoi(rui->c_str() + rui->length() - 2)); } // Do the same for Track-Finder FED for (int fed = FEDNumbering::MINCSCTFFEDID; fed <= FEDNumbering::MAXCSCTFFEDID; fed++) { std::ostringstream name; name << "FED" << fed << std::ends; std::vector<std::string> rui_list = pset.getUntrackedParameter<std::vector<std::string> >(name.str().c_str(), std::vector<std::string>(0)); for (std::vector<std::string>::const_iterator rui = rui_list.begin(); rui != rui_list.end(); rui++) FED[fed].push_back((unsigned int)atoi(rui->c_str() + rui->length() - 2)); } } // Starting point firstEvent = pset.getUntrackedParameter<int>("firstEvent", 0); nEvents = 0; expectedNextL1A = -1; // If Track-Finder was in readout specify its position in the record or set -1 otherwise // Current agriment is that if there is a TF event it is first DDU record tfDDUnumber = pset.getUntrackedParameter<int>("tfDDUnumber", -1); // For efficiency reasons create this big chunk of data only once tmpBuf = new unsigned short[200000 * nRUIs + 4 * 4]; // Event buffer and its length for every FU fuEvent[0] = nullptr; fuEventSize[0] = 0; fuEvent[1] = nullptr; fuEventSize[1] = 0; fuEvent[2] = nullptr; fuEventSize[2] = 0; fuEvent[3] = nullptr; fuEventSize[3] = 0; // Event buffer and its length for every RU for (int rui = 0; rui < nRUIs; rui++) { ruBuf[rui] = nullptr; ruBufSize[rui] = 0; } LogDebug("CSCFileReader|ctor") << "... and finished"; produces<FEDRawDataCollection>(); } CSCFileReader::~CSCFileReader(void) { if (tmpBuf) delete[] tmpBuf; } int CSCFileReader::readRUI(int rui, const unsigned short *&buf, size_t &length) { if (currentFile[rui] == fileNames[rui].end()) return -1; do { try { length = RUI[rui].next(buf); } catch (std::runtime_error &err) { throw cms::Exception("CSCFileReader|reading") << "EndOfStream: " << err.what() << " (errno=" << errno << ")"; } if (length == 0) // end of file, try next one { if (++currentFile[rui] != fileNames[rui].end()) { try { RUI[rui].open(currentFile[rui]->c_str()); } catch (std::runtime_error &err) { throw cms::Exception("CSCFileReader|reading") << "InputFileMissing: " << err.what() << " (errno=" << errno << ")"; } } else return -1; } } while (length == 0); return buf[2] | ((buf[3] & 0xFF) << 16); } int CSCFileReader::readFU(int fu, const unsigned short *&buf, size_t &length) { if (currentFile[fu] == fileNames[fu].end()) return -1; do { try { length = FU[fu].next(buf); } catch (std::runtime_error &err) { throw cms::Exception("CSCFileReader|reading") << "EndOfStream: " << err.what() << " (errno=" << errno << ")"; } if (length == 0) // end of file, try next one { if (++currentFile[fu] != fileNames[fu].end()) { try { FU[fu].open(currentFile[fu]->c_str()); } catch (std::runtime_error &err) { throw cms::Exception("CSCFileReader|reading") << "InputFileMissing: " << err.what() << " (errno=" << errno << ")"; } } else return -1; } } while (length == 0); // Take L1A from first DDU header in the DCC record (shift=8) return buf[2 + 8] | ((buf[3 + 8] & 0xFF) << 16); } int CSCFileReader::buildEventFromRUIs(FEDRawDataCollection *data) { int eventNumber = -1; // Will determine below do { // Read next event from RUIs for (int rui = 0; rui < nRUIs; rui++) { // read event from the RUI only in two cases: // 1) it is readable (currentL1A>0) and we expect next event from the RUI // 2) it is first time (expectedNextL1A<0) if ((currentL1A[rui] > 0 && currentL1A[rui] < expectedNextL1A) || expectedNextL1A < 0) { currentL1A[rui] = readRUI(rui, ruBuf[rui], ruBufSize[rui]); // std::cout << "read rui" << rui << " l1a: " << currentL1A[rui] << " size: " << ruBufSize[rui] << std::endl; } } eventNumber = -1; // Select lowest L1A from all RUIs and don't expect next event from RUIs that currently hold higher L1A for (int rui = 0; rui < nRUIs; rui++) if (currentL1A[rui] >= 0 && (eventNumber > currentL1A[rui] || eventNumber == -1)) eventNumber = currentL1A[rui]; // No readable RUIs => fall out if (eventNumber < 0) return -1; // Expect next event to be incremented by 1 wrt. to the current event expectedNextL1A = eventNumber + 1; } while (nEvents++ < firstEvent); for (std::map<unsigned int, std::list<unsigned int> >::const_iterator fed = FED.begin(); fed != FED.end(); fed++) if (fed->first < (unsigned int)FEDNumbering::MINCSCTFFEDID) { // Now let's pretend that DDU data were wrapped with DCC Header (2 64-bit words) and Trailer (2 64-bit words): unsigned short *dccBuf = tmpBuf, *dccCur = dccBuf; dccCur[3] = 0x5000; dccCur[2] = 0x0000; dccCur[1] = 0x0000; dccCur[0] = 0x005F; // Fake DCC Header 1 dccCur[7] = 0xD900; dccCur[6] = 0x0000; dccCur[5] = 0x0000; dccCur[4] = 0x0017; // Fake DCC Header 2 dccCur += 8; for (std::list<unsigned int>::const_iterator rui = fed->second.begin(); rui != fed->second.end(); rui++) { //cout<<"Event:"<<eventNumber<<" FED:"<<fed->first<<" RUI:"<<*(fed->second.begin())<<" currL1A:"<<currentL1A[*rui]<<endl; if (currentL1A[*rui] == eventNumber) { if (dccCur - dccBuf + ruBufSize[*rui] >= 200000 * nRUIs + 8) throw cms::Exception("CSCFileReader|eventBuffer") << "OutOfBuffer: Event size exceeds maximal size allowed!"; memcpy(dccCur, ruBuf[*rui], ruBufSize[*rui] * sizeof(unsigned short)); dccCur += ruBufSize[*rui]; } } dccCur[3] = 0xEF00; dccCur[2] = 0x0000; dccCur[1] = 0x0000; dccCur[0] = 0x0000; // Fake DCC Trailer 2 dccCur[7] = 0xAF00; dccCur[6] = 0x0000; dccCur[5] = 0x0000; dccCur[4] = 0x0007; // Fake DCC Trailer 2 dccCur += 8; FEDRawData &fedRawData = data->FEDData(fed->first); fedRawData.resize((dccCur - dccBuf) * sizeof(unsigned short)); std::copy((unsigned char *)dccBuf, (unsigned char *)dccCur, fedRawData.data()); } else { for (std::list<unsigned int>::const_iterator rui = fed->second.begin(); rui != fed->second.end(); rui++) { FEDRawData &fedRawData = data->FEDData(fed->first); fedRawData.resize(ruBufSize[*rui] * sizeof(unsigned short)); std::copy((unsigned char *)ruBuf[*rui], (unsigned char *)(ruBuf[*rui] + ruBufSize[*rui]), fedRawData.data()); } } return eventNumber; } int CSCFileReader::nextEventFromFUs(FEDRawDataCollection *data) { int eventNumber = -1; // Will determine below // If this is a first time - read one event from each FU if (expectedNextL1A < 0) for (int fu = 0; fu < nFUs; fu++) currentL1A[fu] = readFU(fu, fuEvent[fu], fuEventSize[fu]); // Keep buffers for every FU ready at all times // When buffer from some FU is ready to go as the next event, // release it, but read next one int readyToGo = -1; for (int fu = 0; fu < nFUs; fu++) { // If FU is readable and (first loop of this cycle or current FU holds smallest L1A) if (currentL1A[fu] >= 0 && (eventNumber < 0 || currentL1A[fu] < eventNumber)) { readyToGo = fu; eventNumber = currentL1A[fu]; } } // No readable FUs => fall out if (readyToGo < 0) return -1; expectedNextL1A = eventNumber + 1; // Compose event from DDC record striped of Track-Finder DDU and a separate TF DDU event unsigned long long *start = (unsigned long long *)fuEvent[readyToGo]; unsigned long long *end = nullptr; enum { Header = 1, Trailer = 2 }; unsigned int eventStatus = 0; for (int dduRecord = 0; dduRecord <= tfDDUnumber; dduRecord++) { unsigned long long word_0 = 0, word_1 = 0, word_2 = 0; size_t dduWordCount = 0; while (!end && dduWordCount < fuEventSize[readyToGo]) { unsigned long long *dduWord = start; while (dduWordCount < fuEventSize[readyToGo]) { word_0 = word_1; // delay by 2 DDU words word_1 = word_2; // delay by 1 DDU word word_2 = *dduWord; // current DDU word if ((word_2 & 0xFFFFFFFFFFFF0000LL) == 0x8000000180000000LL) { if (eventStatus & Header) // Second header { word_2 = word_1; end = dduWord; break; } start = dduWord; } if ((word_0 & 0xFFFFFFFFFFFF0000LL) == 0x8000FFFF80000000LL) { eventStatus |= Trailer; end = ++dduWord; break; } // Increase counters by one DDU word dduWord++; dduWordCount++; } } // If reach max length if (dduWordCount == fuEventSize[readyToGo]) { end = (unsigned long long *)(fuEvent[readyToGo] + fuEventSize[readyToGo]); break; } } // Include 0x5xxx preHeader if exists if (start > (unsigned long long *)fuEvent[readyToGo] && (*(start - 1) & 0xF000000000000000LL) == 0x5000000000000000LL) start--; // If Track-Finder DDU was in readout if (tfDDUnumber >= 0) { // Cut out Track-Finder DDU from the buffer if (!end) throw cms::Exception("CSCFileReader|lookingForTF") << " Sanity check failed (end==0)! Should never happen"; FEDRawData &tfRawData = data->FEDData(FEDNumbering::MINCSCTFFEDID); tfRawData.resize((end - start) * sizeof(unsigned long long)); std::copy((unsigned char *)start, (unsigned char *)end, tfRawData.data()); // Create a new buffer from everything before and after TF DDU unsigned short *event = tmpBuf; memcpy(event, fuEvent[readyToGo], ((unsigned short *)start - fuEvent[readyToGo]) * sizeof(unsigned short)); event += ((unsigned short *)start - fuEvent[readyToGo]); memcpy(event, end, (fuEvent[readyToGo] + fuEventSize[readyToGo] - (unsigned short *)end) * sizeof(unsigned short)); event += fuEvent[readyToGo] + fuEventSize[readyToGo] - (unsigned short *)end; FEDRawData &fedRawData = data->FEDData(FEDNumbering::MINCSCFEDID); fedRawData.resize((fuEventSize[readyToGo] - ((unsigned short *)end - (unsigned short *)start)) * sizeof(unsigned short)); std::copy((unsigned char *)tmpBuf, (unsigned char *)event, fedRawData.data()); } else { FEDRawData &fedRawData = data->FEDData(FEDNumbering::MINCSCFEDID); fedRawData.resize((fuEventSize[readyToGo]) * sizeof(unsigned short)); std::copy((unsigned char *)fuEvent[readyToGo], (unsigned char *)(fuEvent[readyToGo] + fuEventSize[readyToGo]), fedRawData.data()); } currentL1A[readyToGo] = readFU(readyToGo, fuEvent[readyToGo], fuEventSize[readyToGo]); return eventNumber; } int CSCFileReader::fillRawData(edm::Event &e, /* edm::Timestamp& tstamp,*/ FEDRawDataCollection *&data) { edm::EventID eID = e.id(); data = new FEDRawDataCollection(); if (fFirstReadBug) { eID = edm::EventID(runNumber, 1U, 1); fFirstReadBug = false; return true; } // int runNumber = 0; // Unknown at the level of EMu local DAQ int eventNumber = -1; // Will determine below if (!nActiveFUs && nActiveRUIs) { eventNumber = buildEventFromRUIs(data); // std::cout << eventNumber << std::endl; } else { eventNumber = nextEventFromFUs(data); } if (eventNumber < 0) return false; eID = edm::EventID(runNumber, 1U, eventNumber); return true; } void CSCFileReader::produce(edm::Event &e, edm::EventSetup const &es) { edm::Handle<FEDRawDataCollection> rawdata; FEDRawDataCollection *fedcoll = nullptr; fillRawData(e, fedcoll); std::unique_ptr<FEDRawDataCollection> bare_product(fedcoll); e.put(std::move(bare_product)); } #undef nRUIs #undef nFUs