From 79affe1ea40c67d3c97e71e5833cff5b72a06c58 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 6 Jan 2022 18:46:14 +0100 Subject: [PATCH] updated client and rxr, not tested --- .../src/slsDetectorServer_funcs.c | 5 +- slsDetectorSoftware/src/Detector.cpp | 16 +- slsDetectorSoftware/src/DetectorImpl.cpp | 59 +- slsDetectorSoftware/src/Module.cpp | 4 +- slsReceiverSoftware/src/GeneralData.h | 561 ++++++++---------- slsReceiverSoftware/src/Implementation.cpp | 105 ++-- slsReceiverSoftware/src/Implementation.h | 2 - 7 files changed, 329 insertions(+), 423 deletions(-) diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 8328e2a18..f8624c777 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -4727,13 +4727,12 @@ void calculate_and_set_position() { } // calculating new position - int numInterfaces = getNumberofUDPInterfaces(); int modulePorts[2] = {1, 1}; // position does change for eiger and jungfrau (2 interfaces) #if defined(EIGERD) - modulePorts[1] = numInterfaces; // horz + modulePorts[1] = getNumberofUDPInterfaces(); // horz #elif defined(JUNGFRAUD) - modulePorts[0] = numInterfaces; // vert + modulePorts[0] = getNumberofUDPInterfaces(); // vert #endif int maxy = maxydet * modulePorts[0]; int pos[2] = {0, 0}; diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 3a4c6d42e..f9335a195 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -2306,20 +2306,8 @@ Result Detector::getRxCurrentFrameIndex(Positions pos) const { } std::vector Detector::getPortNumbers(int start_port) { - int num_sockets_per_detector = 1; - switch (getDetectorType().squash()) { - case defs::EIGER: - num_sockets_per_detector *= 2; - break; - case defs::JUNGFRAU: - case defs::GOTTHARD2: - if (pimpl->getNumberofUDPInterfaces({}).squash() == 2) { - num_sockets_per_detector *= 2; - } - break; - default: - break; - } + int num_sockets_per_detector = pimpl->getNumberofUDPInterfaces({}).tsquash( + "Number of UDP Interfaces is not consistent among modules"); std::vector res; res.reserve(size()); for (int idet = 0; idet < size(); ++idet) { diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 98c7e4748..56f5a8938 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -284,6 +284,8 @@ void DetectorImpl::addModule(const std::string &hostname) { .tsquash("Inconsistent detector types."); // for moench and ctb modules[pos]->updateNumberOfChannels(); + + modules[pos]->getNumberofUDPInterfaces(); } void DetectorImpl::updateDetectorSize() { @@ -402,31 +404,25 @@ int DetectorImpl::createReceivingDataSockets() { } LOG(logINFO) << "Going to create data sockets"; - size_t numSockets = modules.size(); - size_t numSocketsPerModule = 1; - if (shm()->detType == EIGER) { - numSocketsPerModule = 2; + size_t numUDPInterfaces = + Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).squash(1); + // gotthard2 second interface is only for veto debugging (not in gui) + if (shm()->detType == GOTTHARD2) { + numUDPInterfaces = 1; } - // gotthard2 second interface is only for veto debugging - else if (shm()->detType != GOTTHARD2) { - if (Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).squash() == - 2) { - numSocketsPerModule = 2; - } - } - numSockets *= numSocketsPerModule; + size_t numSockets = modules.size() * numUDPInterfaces; for (size_t iSocket = 0; iSocket < numSockets; ++iSocket) { uint32_t portnum = - (modules[iSocket / numSocketsPerModule]->getClientStreamingPort()); - portnum += (iSocket % numSocketsPerModule); + (modules[iSocket / numUDPInterfaces]->getClientStreamingPort()); + portnum += (iSocket % numUDPInterfaces); try { - zmqSocket.push_back(sls::make_unique( - modules[iSocket / numSocketsPerModule] - ->getClientStreamingIP() - .str() - .c_str(), - portnum)); + zmqSocket.push_back( + sls::make_unique(modules[iSocket / numUDPInterfaces] + ->getClientStreamingIP() + .str() + .c_str(), + portnum)); // set high water mark int hwm = shm()->zmqHwm; if (hwm >= 0) { @@ -460,13 +456,19 @@ void DetectorImpl::readFrameFromReceiver() { int nDetPixelsX = 0; int nDetPixelsY = 0; bool quadEnable = false; + // to flip image bool eiger = false; - bool numInterfaces = 1; + + // cannot pick up udp interfaces from zmq + int numInterfaces = + Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).squash(1); + int module_ports[2] = {1, 1}; // gotthard2 second interface is veto debugging - if (shm()->detType != GOTTHARD2) { - numInterfaces = Parallel(&Module::getNumberofUDPInterfacesFromShm, {}) - .squash(); // cannot pick up from zmq - } + if (shm()->detType == EIGER) + module_ports[1] = numInterfaces; // horz + else if (shm()->detType == JUNGFRAU) + module_ports[0] = numInterfaces; // vert + std::vector runningList(zmqSocket.size()); std::vector connectList(zmqSocket.size()); numZmqRunning = 0; @@ -543,9 +545,10 @@ void DetectorImpl::readFrameFromReceiver() { nPixelsX = zHeader.npixelsx; nPixelsY = zHeader.npixelsy; // module shape - nX = zHeader.ndetx; - nY = zHeader.ndety; - nY *= numInterfaces; + nX = zHeader.ndetx * + module_ports[1]; // TODO: check if module_ports[1] + // needed + nY = zHeader.ndety * module_ports[0]; nDetPixelsX = nX * nPixelsX; nDetPixelsY = nY * nPixelsY; // det type diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 1f357e5de..c22e1ad96 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -3114,8 +3114,8 @@ void Module::initializeModuleStructure(detectorType type) { sls::strcpy_safe(shm()->rxHostname, "none"); shm()->rxTCPPort = DEFAULT_PORTNO + 2; shm()->useReceiverFlag = false; - shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO + - (moduleIndex * ((shm()->detType == EIGER) ? 2 : 1)); + shm()->zmqport = + DEFAULT_ZMQ_CL_PORTNO + moduleIndex * shm()->numUDPInterfaces; shm()->zmqip = IpAddr{}; shm()->numUDPInterfaces = 1; shm()->stoppedFlag = false; diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index 1120918f4..dd06bfbc3 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -38,7 +38,7 @@ class GeneralData { /** Header size of data saved into fifo buffer at a time*/ uint32_t fifoBufferHeaderSize{0}; uint32_t defaultFifoDepth{0}; - uint32_t threadsPerReceiver{1}; + uint32_t numUDPInterfaces{1}; uint32_t headerPacketSize{0}; /** Streaming (for ROI - mainly short Gotthard) */ uint32_t nPixelsXComplete{0}; @@ -54,10 +54,27 @@ class GeneralData { uint32_t vetoImageSize{0}; uint32_t vetoHsize{0}; uint32_t maxRowsPerReadout{0}; + uint32_t dynamicRange{16}; + bool tengigaEnable{false}; + uint32_t nAnalogSamples{0}; + uint32_t nDigitalSamples{0}; + readoutMode readoutType{ANALOG_ONLY}; + uint32_t adcEnableMaskOneGiga{BIT32_MASK}; + uint32_t adcEnableMaskTenGiga{BIT32_MASK}; + slsDetectorDefs::ROI roi{}; GeneralData(){}; virtual ~GeneralData(){}; + // Returns the pixel depth in byte, 4 bits being 0.5 byte + float GetPixelDepth() { return float(dynamicRange) / 8; } + + void ThrowGenericError(std::string msg) { + throw sls::RuntimeError( + msg + std::string("SetROI is a generic function that should be " + "overloaded by a derived class")); + } + /** * Get Header Infomation (frame number, packet number) * @param index thread index for debugging purposes @@ -78,94 +95,65 @@ class GeneralData { bunchId = -1; } - /** - * Set ROI - * @param i ROI - */ virtual void SetROI(slsDetectorDefs::ROI i) { - LOG(logERROR) << "SetROI is a generic function that should be " - "overloaded by a derived class"; + ThrowGenericError("SetROI"); }; - /** - * Get Adc configured - * @param index thread index for debugging purposes - * @param i - * @returns adc configured - */ + /**@returns adc configured */ virtual int GetAdcConfigured(int index, slsDetectorDefs::ROI i) const { - LOG(logERROR) << "GetAdcConfigured is a generic function that should " - "be overloaded by a derived class"; + ThrowGenericError("GetAdcConfigured"); return 0; }; - /** - * Setting dynamic range changes member variables - * @param dr dynamic range - * @param tgEnable true if 10GbE is enabled, else false - */ - virtual void SetDynamicRange(int dr, bool tgEnable) { - LOG(logERROR) << "SetDynamicRange is a generic function that should be " - "overloaded by a derived class"; + virtual void SetDynamicRange(int dr) { + ThrowGenericError("SetDynamicRange"); }; - /** - * Setting ten giga enable changes member variables - * @param tgEnable true if 10GbE is enabled, else false - * @param dr dynamic range - */ - virtual void SetTenGigaEnable(bool tgEnable, int dr) { - LOG(logERROR) << "SetTenGigaEnable is a generic function that should " - "be overloaded by a derived class"; + virtual void SetTenGigaEnable(bool tgEnable) { + ThrowGenericError("SetTenGigaEnable"); }; - /** - * Set odd starting packet (gotthard) - * @param index thread index for debugging purposes - * @param packetData pointer to data - * @returns true or false for odd starting packet number - */ virtual bool SetOddStartingPacket(int index, char *packetData) { - LOG(logERROR) << "SetOddStartingPacket is a generic function that " - "should be overloaded by a derived class"; + ThrowGenericError("SetOddStartingPacket"); return false; }; - /** - * Set databytes (ctb, moench) - * @param a adc enable mask - * @param as analog number of samples - * @param ds digital number of samples - * @param t tengiga enable - * @param f readout flags - * @returns analog data bytes - */ - virtual int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t, - slsDetectorDefs::readoutMode f) { - LOG(logERROR) << "setImageSize is a generic function that should be " - "overloaded by a derived class"; + virtual void SetNumberofInterfaces(const int n) { + ThrowGenericError("SetNumberofInterfaces"); + }; + + virtual void SetNumberofCounters(const int n) { + ThrowGenericError("SetNumberofCounters"); + }; + + virtual int GetNumberOfAnalogDatabytes() { + ThrowGenericError("GetNumberOfAnalogDatabytes"); return 0; }; - /** - * set number of interfaces (jungfrau) - * @param n number of interfaces - */ - virtual void SetNumberofInterfaces(const int n) { - LOG(logERROR) << "SetNumberofInterfaces is a generic function that " - "should be overloaded by a derived class"; - } + virtual void SetNumberOfAnalogSamples(int n) { + ThrowGenericError("SetNumberOfAnalogSamples"); + }; - /** - * set number of counters (mythen3) - * @param n number of counters - * @param dr dynamic range - * @param tgEnable ten giga enable - */ - virtual void SetNumberofCounters(const int n, const int dr, bool tgEnable) { - LOG(logERROR) << "SetNumberofCounters is a generic function that " - "should be overloaded by a derived class"; - } + virtual void SetNumberOfDigitalSamples(int n) { + ThrowGenericError("SetNumberOfDigitalSamples"); + }; + + virtual void SetOneGigaAdcEnableMask(int n) { + ThrowGenericError("SetOneGigaAdcEnableMask"); + }; + + virtual void SetTenGigaAdcEnableMask(int n) { + ThrowGenericError("SetTenGigaAdcEnableMask"); + }; + + virtual void SetReadoutMode(slsDetectorDefs::readoutMode r) { + ThrowGenericError("SetReadoutMode"); + }; + + virtual void SetTenGigaEnable(bool tg) { + ThrowGenericError("SetTenGigaEnable"); + }; }; class GotthardData : public GeneralData { @@ -175,23 +163,15 @@ class GotthardData : public GeneralData { const int nChipsPerAdc = 2; public: - /** Constructor */ GotthardData() { myDetectorType = slsDetectorDefs::GOTTHARD; - nPixelsX = 1280; nPixelsY = 1; - headerSizeinPacket = 4; - dataSize = 1280; - packetSize = GOTTHARD_PACKET_SIZE; - packetsPerFrame = 2; - imageSize = dataSize * packetsPerFrame; - frameIndexMask = 0xFFFFFFFE; - frameIndexOffset = 1; - packetIndexMask = 1; + headerSizeinPacket = 6; maxFramesPerFile = MAX_FRAMES_PER_FILE; fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); defaultFifoDepth = 50000; + UpdateImageSize(); }; /** @@ -219,56 +199,7 @@ class GotthardData : public GeneralData { bunchId = -1; } - /** - * Set ROI - * @param i ROI - */ - void SetROI(slsDetectorDefs::ROI i) { - // all adcs - if (i.xmin == -1) { - nPixelsX = 1280; - dataSize = 1280; - packetSize = GOTTHARD_PACKET_SIZE; - packetsPerFrame = 2; - imageSize = dataSize * packetsPerFrame; - frameIndexMask = 0xFFFFFFFE; - frameIndexOffset = 1; - packetIndexMask = 1; - maxFramesPerFile = MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + - sizeof(slsDetectorDefs::sls_receiver_header); - defaultFifoDepth = 50000; - nPixelsXComplete = 0; - nPixelsYComplete = 0; - imageSizeComplete = 0; - } - - // single adc - else { - nPixelsX = 256; - dataSize = 512; - packetSize = 518; - packetsPerFrame = 1; - imageSize = dataSize * packetsPerFrame; - frameIndexMask = 0xFFFFFFFF; - frameIndexOffset = 0; - packetIndexMask = 0; - maxFramesPerFile = SHORT_MAX_FRAMES_PER_FILE; - fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + - sizeof(slsDetectorDefs::sls_receiver_header); - defaultFifoDepth = 75000; - nPixelsXComplete = 1280; - nPixelsYComplete = 1; - imageSizeComplete = 1280 * 2; - } - }; - - /** - * Get Adc configured - * @param index thread index for debugging purposes - * @param i ROI - * @returns adc configured - */ + /** @returns adc configured */ int GetAdcConfigured(int index, slsDetectorDefs::ROI i) const { int adc = -1; // single adc @@ -320,99 +251,114 @@ class GotthardData : public GeneralData { } return oddStartingPacket; }; + + void SetROI(slsDetectorDefs::ROI i) { + roi = i; + UpdateImageSize(); + }; + + private: + void UpdateImageSize() { + + // all adcs + if (roi.xmin == -1) { + nPixelsX = 1280; + dataSize = 1280; + packetsPerFrame = 2; + frameIndexMask = 0xFFFFFFFE; + frameIndexOffset = 1; + packetIndexMask = 1; + maxFramesPerFile = MAX_FRAMES_PER_FILE; + nPixelsXComplete = 0; + nPixelsYComplete = 0; + imageSizeComplete = 0; + defaultFifoDepth = 50000; + } else { + nPixelsX = 256; + dataSize = 512; + packetsPerFrame = 1; + frameIndexMask = 0xFFFFFFFF; + frameIndexOffset = 0; + packetIndexMask = 0; + maxFramesPerFile = SHORT_MAX_FRAMES_PER_FILE; + nPixelsXComplete = 1280; + nPixelsYComplete = 1; + imageSizeComplete = 1280 * 2; + defaultFifoDepth = 75000; + } + imageSize = int(nPixelsX * nPixelsY * GetPixelDepth()); + packetSize = headerSizeinPacket + dataSize; + packetsPerFrame = imageSize / dataSize; + }; }; class EigerData : public GeneralData { public: - /** Constructor */ EigerData() { myDetectorType = slsDetectorDefs::EIGER; - nPixelsX = (256 * 2); - nPixelsY = 256; headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); - dataSize = 1024; - packetSize = headerSizeinPacket + dataSize; - packetsPerFrame = 256; - imageSize = dataSize * packetsPerFrame; maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE; fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); - defaultFifoDepth = 1000; - threadsPerReceiver = 2; + numUDPInterfaces = 2; headerPacketSize = 40; standardheader = true; maxRowsPerReadout = 256; + UpdateImageSize(); }; - /** - * Setting dynamic range changes member variables - * @param dr dynamic range - * @param tgEnable true if 10GbE is enabled, else false - */ - void SetDynamicRange(int dr, bool tgEnable) { - packetsPerFrame = (tgEnable ? 4 : 16) * dr; - imageSize = dataSize * packetsPerFrame; - defaultFifoDepth = (dr == 32 ? 100 : 1000); + void SetDynamicRange(int dr) { + dynamicRange = dr; + UpdateImageSize(); } - /** - * Setting ten giga enable changes member variables - * @param tgEnable true if 10GbE is enabled, else false - * @param dr dynamic range - */ - void SetTenGigaEnable(bool tgEnable, int dr) { - dataSize = (tgEnable ? 4096 : 1024); + void SetTenGigaEnable(bool tgEnable) { + tengigaEnable = tgEnable; + UpdateImageSize(); + }; + + private: + void UpdateImageSize() { + nPixelsX = (256 * 4) / numUDPInterfaces; + nPixelsY = 256; + dataSize = (tengigaEnable ? 4096 : 1024); packetSize = headerSizeinPacket + dataSize; - packetsPerFrame = (tgEnable ? 4 : 16) * dr; - imageSize = dataSize * packetsPerFrame; + imageSize = int(nPixelsX * nPixelsY * GetPixelDepth()); + packetsPerFrame = imageSize / dataSize; + defaultFifoDepth = (dynamicRange == 32 ? 100 : 1000); }; }; class JungfrauData : public GeneralData { public: - /** Constructor */ JungfrauData() { myDetectorType = slsDetectorDefs::JUNGFRAU; - nPixelsX = (256 * 4); - nPixelsY = 512; headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); dataSize = 8192; packetSize = headerSizeinPacket + dataSize; - packetsPerFrame = 128; - imageSize = dataSize * packetsPerFrame; maxFramesPerFile = JFRAU_MAX_FRAMES_PER_FILE; fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); defaultFifoDepth = 2500; standardheader = true; - defaultUdpSocketBufferSize = (1000 * 1024 * 1024); maxRowsPerReadout = 512; + UpdateImageSize(); }; - /** - * set number of interfaces (jungfrau) - * @param n number of interfaces - */ void SetNumberofInterfaces(const int n) { - // 2 interfaces - if (n == 2) { - nPixelsY = 256; - packetsPerFrame = 64; - imageSize = dataSize * packetsPerFrame; - threadsPerReceiver = 2; - defaultUdpSocketBufferSize = (500 * 1024 * 1024); + numUDPInterfaces = n; + UpdateImageSize(); + }; - } - // 1 interface - else { - nPixelsY = 512; - packetsPerFrame = 128; - imageSize = dataSize * packetsPerFrame; - threadsPerReceiver = 1; - defaultUdpSocketBufferSize = (1000 * 1024 * 1024); - } + private: + void UpdateImageSize() { + nPixelsX = (256 * 4); + nPixelsY = (256 * 2) / numUDPInterfaces; + imageSize = int(nPixelsX * nPixelsY * GetPixelDepth()); + packetsPerFrame = imageSize / dataSize; + defaultUdpSocketBufferSize = (1000 * 1024 * 1024) / numUDPInterfaces; }; }; @@ -422,39 +368,44 @@ class Mythen3Data : public GeneralData { const int NCHAN = 1280; public: - /** Constructor */ Mythen3Data() { myDetectorType = slsDetectorDefs::MYTHEN3; ncounters = 3; - nPixelsX = (NCHAN * ncounters); // max 1280 channels x 3 counters nPixelsY = 1; headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); - dataSize = 7680; - packetSize = headerSizeinPacket + dataSize; - packetsPerFrame = 2; - imageSize = dataSize * packetsPerFrame; maxFramesPerFile = MYTHEN3_MAX_FRAMES_PER_FILE; fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); defaultFifoDepth = 50000; standardheader = true; defaultUdpSocketBufferSize = (1000 * 1024 * 1024); + UpdateImageSize(); }; - /** - * set number of counters (mythen3) - * @param n number of counters - * @param dr dynamic range - * @param tgEnable ten giga enable - */ - virtual void SetNumberofCounters(const int n, const int dr, bool tgEnable) { + void SetDynamicRange(int dr) { + dynamicRange = dr; + UpdateImageSize(); + }; + + void SetTenGigaEnable(bool tg) { + tengigaEnable = tg; + UpdateImageSize(); + }; + + virtual void SetNumberofCounters(const int n) { ncounters = n; - nPixelsX = NCHAN * ncounters; + UpdateImageSize(); + }; + + private: + void UpdateImageSize() { + nPixelsX = (NCHAN * ncounters); // max 1280 channels x 3 counters LOG(logINFO) << "nPixelsX: " << nPixelsX; - imageSize = nPixelsX * nPixelsY * ((double)dr / 8.00); + imageSize = nPixelsX * nPixelsY * GetPixelDepth(); + // 10g - if (tgEnable) { - if (dr == 32 && n > 1) { + if (tengigaEnable) { + if (dynamicRange == 32 && ncounters > 1) { packetsPerFrame = 2; } else { packetsPerFrame = 1; @@ -463,7 +414,7 @@ class Mythen3Data : public GeneralData { } // 1g else { - if (n == 3) { + if (ncounters == 3) { dataSize = 768; } else { dataSize = 1280; @@ -479,41 +430,26 @@ class Mythen3Data : public GeneralData { class Gotthard2Data : public GeneralData { public: - /** Constructor */ Gotthard2Data() { myDetectorType = slsDetectorDefs::GOTTHARD2; nPixelsX = 128 * 10; nPixelsY = 1; headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); dataSize = 2560; // 1280 channels * 2 bytes - packetSize = headerSizeinPacket + dataSize; packetsPerFrame = 1; - imageSize = dataSize * packetsPerFrame; maxFramesPerFile = GOTTHARD2_MAX_FRAMES_PER_FILE; fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); defaultFifoDepth = 50000; standardheader = true; - defaultUdpSocketBufferSize = (1000 * 1024 * 1024); vetoDataSize = 160; - vetoImageSize = vetoDataSize * packetsPerFrame; vetoHsize = 16; - vetoPacketSize = vetoHsize + vetoDataSize; + UpdateImageSize(); }; - /** - * set number of interfaces - * @param n number of interfaces - */ void SetNumberofInterfaces(const int n) { - // 2 interfaces (+veto) - if (n == 2) { - threadsPerReceiver = 2; - } - // 1 interface (data only) - else { - threadsPerReceiver = 1; - } + numUDPInterfaces = n; + UpdateImageSize(); }; /** @@ -532,14 +468,23 @@ class Gotthard2Data : public GeneralData { bunchId = *reinterpret_cast(packetData + 8); packetNumber = 0; }; + + private: + void UpdateImageSize() { + packetSize = headerSizeinPacket + dataSize; + imageSize = int(nPixelsX * nPixelsY * GetPixelDepth()); + packetsPerFrame = imageSize / dataSize; + vetoPacketSize = vetoHsize + vetoDataSize; + vetoImageSize = vetoDataSize * packetsPerFrame; + defaultUdpSocketBufferSize = (1000 * 1024 * 1024) / numUDPInterfaces; + }; }; class ChipTestBoardData : public GeneralData { private: - /** Number of digital channels */ const int NCHAN_DIGITAL = 64; - /** Number of bytes per analog channel */ const int NUM_BYTES_PER_ANALOG_CHANNEL = 2; + int nAnalogBytes = 0; public: /** Constructor */ @@ -548,118 +493,136 @@ class ChipTestBoardData : public GeneralData { nPixelsX = 36; // total number of channels nPixelsY = 1; // number of samples headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); - dataSize = UDP_PACKET_DATA_BYTES; - packetSize = headerSizeinPacket + dataSize; - // packetsPerFrame = 1; - imageSize = nPixelsX * nPixelsY * 2; frameIndexMask = 0xFFFFFF; // 10g frameIndexOffset = 8; // 10g packetIndexMask = 0xFF; // 10g - packetsPerFrame = - ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES); maxFramesPerFile = CTB_MAX_FRAMES_PER_FILE; fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); defaultFifoDepth = 2500; standardheader = true; + UpdateImageSize(); }; - /** - * Set databytes - * @param a adc enable mask - * @param as analog number of samples - * @param ds digital number of samples - * @param t tengiga enable - * @param f readout flags - * @returns analog data bytes - */ - int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t, - slsDetectorDefs::readoutMode f) { - int nachans = 0, ndchans = 0; - int adatabytes = 0, ddatabytes = 0; + public: + int GetNumberOfAnalogDatabytes() { return nAnalogBytes; }; + + void SetNumberOfAnalogSamples(int n) { + nAnalogSamples = n; + UpdateImageSize(); + }; + + void SetNumberOfDigitalSamples(int n) { + nDigitalSamples = n; + UpdateImageSize(); + }; + + void SetOneGigaAdcEnableMask(int n) { + adcEnableMaskOneGiga = n; + UpdateImageSize(); + }; + + void SetTenGigaAdcEnableMask(int n) { + adcEnableMaskTenGiga = n; + UpdateImageSize(); + }; + + void SetReadoutMode(slsDetectorDefs::readoutMode r) { + readoutType = r; + UpdateImageSize(); + }; + + void SetTenGigaEnable(bool tg) { + tengigaEnable = tg; + UpdateImageSize(); + }; + + private: + void UpdateImageSize() { + nAnalogBytes = 0; + int nDigitalBytes = 0; + int nAnalogChans = 0, nDigitalChans = 0; // analog channels (normal, analog/digital readout) - if (f == slsDetectorDefs::ANALOG_ONLY || - f == slsDetectorDefs::ANALOG_AND_DIGITAL) { - nachans = __builtin_popcount(a); + if (readoutType == slsDetectorDefs::ANALOG_ONLY || + readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL) { + uint32_t adcEnableMask = + (tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga); + nAnalogChans = __builtin_popcount(adcEnableMask); - adatabytes = nachans * NUM_BYTES_PER_ANALOG_CHANNEL * as; - LOG(logDEBUG1) << " Number of Analog Channels:" << nachans - << " Databytes: " << adatabytes; + nAnalogBytes = + nAnalogChans * NUM_BYTES_PER_ANALOG_CHANNEL * nAnalogSamples; + LOG(logDEBUG1) << " Number of Analog Channels:" << nAnalogChans + << " Databytes: " << nAnalogBytes; } // digital channels - if (f == slsDetectorDefs::DIGITAL_ONLY || - f == slsDetectorDefs::ANALOG_AND_DIGITAL) { - ndchans = NCHAN_DIGITAL; - ddatabytes = (sizeof(uint64_t) * ds); - LOG(logDEBUG1) << "Number of Digital Channels:" << ndchans - << " Databytes: " << ddatabytes; + if (readoutType == slsDetectorDefs::DIGITAL_ONLY || + readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL) { + nDigitalChans = NCHAN_DIGITAL; + nDigitalBytes = (sizeof(uint64_t) * nDigitalSamples); + LOG(logDEBUG1) << "Number of Digital Channels:" << nDigitalChans + << " Databytes: " << nDigitalBytes; } - LOG(logDEBUG1) << "Total Number of Channels:" << nachans + ndchans - << " Databytes: " << adatabytes + ddatabytes; - nPixelsX = nachans + ndchans; + nPixelsX = nAnalogChans + nDigitalChans; nPixelsY = 1; + LOG(logDEBUG1) << "Total Number of Channels:" << nPixelsX + << " Databytes: " << nAnalogBytes + nDigitalBytes; - // 10G - if (t) { - dataSize = 8144; - } - // 1g udp (via fifo readout) - else { - dataSize = UDP_PACKET_DATA_BYTES; - } - + dataSize = tengigaEnable ? 8144 : UDP_PACKET_DATA_BYTES; packetSize = headerSizeinPacket + dataSize; imageSize = adatabytes + ddatabytes; packetsPerFrame = ceil((double)imageSize / (double)dataSize); - - return adatabytes; - } + }; }; class MoenchData : public GeneralData { private: - /** Number of bytes per analog channel */ const int NUM_BYTES_PER_ANALOG_CHANNEL = 2; public: - /** Constructor */ MoenchData() { myDetectorType = slsDetectorDefs::MOENCH; - nPixelsX = 32; // total number of channels - nPixelsY = 1; // number of samples + nPixelsY = 1; // number of samples headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); - dataSize = UDP_PACKET_DATA_BYTES; - packetSize = headerSizeinPacket + dataSize; - // packetsPerFrame = 1; - imageSize = nPixelsX * nPixelsY * 2; - packetsPerFrame = - ceil((double)imageSize / (double)UDP_PACKET_DATA_BYTES); frameIndexMask = 0xFFFFFF; maxFramesPerFile = MOENCH_MAX_FRAMES_PER_FILE; fifoBufferHeaderSize = FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); defaultFifoDepth = 2500; standardheader = true; + UpdateImageSize(); }; - /** - * Set databytes - * @param a adc enable mask - * @param as analog number of samples - * @param ds digital number of samples - * @param t tengiga enable - * @param f readout flags - * @returns analog data bytes - */ - int setImageSize(uint32_t a, uint32_t as, uint32_t ds, bool t, - slsDetectorDefs::readoutMode f) { + void SetNumberOfAnalogSamples(int n) { + nAnalogSamples = n; + UpdateImageSize(); + }; + + void SetOneGigaAdcEnableMask(int n) { + adcEnableMaskOneGiga = n; + UpdateImageSize(); + }; + + void SetTenGigaAdcEnableMask(int n) { + adcEnableMaskTenGiga = n; + UpdateImageSize(); + }; + + void SetTenGigaEnable(bool tg) { + tengigaEnable = tg; + UpdateImageSize(); + }; + + private: + void UpdateImageSize() { + uint32_t adcEnableMask = + (tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga); // count number of channels in x, each adc has 25 channels each - int nchanTop = __builtin_popcount(a & 0xF0F0F0F0) * 25; - int nchanBot = __builtin_popcount(a & 0x0F0F0F0F) * 25; + int nchanTop = __builtin_popcount(adcEnableMask & 0xF0F0F0F0) * 25; + int nchanBot = __builtin_popcount(adcEnableMask & 0x0F0F0F0F) * 25; nPixelsX = nchanTop > 0 ? nchanTop : nchanBot; // if both top and bottom adcs enabled, rows = 2 @@ -667,25 +630,15 @@ class MoenchData : public GeneralData { if (nchanTop > 0 && nchanBot > 0) { nrows = 2; } - nPixelsY = as / 25 * nrows; + nPixelsY = nAnalogSamples / 25 * nrows; LOG(logINFO) << "Number of Pixels: [" << nPixelsX << ", " << nPixelsY << "]"; - // 10G - if (t) { - dataSize = 8144; - } - // 1g udp (via fifo readout) - else { - dataSize = UDP_PACKET_DATA_BYTES; - } - - imageSize = nPixelsX * nPixelsY * NUM_BYTES_PER_ANALOG_CHANNEL; + dataSize = tengigaEnable ? 8144 : UDP_PACKET_DATA_BYTES; packetSize = headerSizeinPacket + dataSize; + imageSize = nPixelsX * nPixelsY * NUM_BYTES_PER_ANALOG_CHANNEL; packetsPerFrame = ceil((double)imageSize / (double)dataSize); LOG(logDEBUG) << "Databytes: " << imageSize; - - return imageSize; - } + }; }; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 4e68049a7..f1f024b1e 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -64,7 +64,7 @@ void Implementation::SetThreadPriorities() { void Implementation::SetupFifoStructure() { fifo.clear(); - for (int i = 0; i < numThreads; ++i) { + for (int i = 0; i < numUDPInterfaces; ++i) { uint32_t datasize = generalData->imageSize; // veto data size if (detType == GOTTHARD2 && i != 0) { @@ -97,7 +97,7 @@ void Implementation::SetupFifoStructure() { (double)(1024 * 1024) << " MB"; } - LOG(logINFO) << numThreads << " Fifo structure(s) reconstructed"; + LOG(logINFO) << numUDPInterfaces << " Fifo structure(s) reconstructed"; } /************************************************** @@ -152,7 +152,7 @@ void Implementation::setDetectorType(const detectorType d) { default: break; } - numThreads = generalData->threadsPerReceiver; + numUDPInterfaces = generalData->numUDPInterfaces; fifoDepth = generalData->defaultFifoDepth; udpSocketBufferSize = generalData->defaultUdpSocketBufferSize; framesPerFile = generalData->maxFramesPerFile; @@ -161,7 +161,7 @@ void Implementation::setDetectorType(const detectorType d) { SetupFifoStructure(); // create threads - for (int i = 0; i < numThreads; ++i) { + for (int i = 0; i < numUDPInterfaces; ++i) { try { auto fifo_ptr = fifo[i].get(); @@ -170,6 +170,10 @@ void Implementation::setDetectorType(const detectorType d) { &udpSocketBufferSize, &actualUDPSocketBufferSize, &framesPerFile, &frameDiscardMode, &activated, &detectorDataStream[i], &silentMode)); + int ctbAnalogDataBytes = 0; + if (myDetectorType == CHIPTESTBOARD) { + ctbAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); + } dataProcessor.push_back(sls::make_unique( i, detType, fifo_ptr, &activated, &dataStreamEnable, &streamingFrequency, &streamingTimerInMs, &streamingStartFnum, @@ -308,7 +312,7 @@ std::array Implementation::getThreadIds() const { } else { retval[id++] = 0; } - if (numThreads == 2) { + if (numUDPInterfaces == 2) { retval[id++] = listener[1]->GetThreadId(); retval[id++] = dataProcessor[1]->GetThreadId(); if (dataStreamEnable) { @@ -474,8 +478,8 @@ double Implementation::getProgress() const { } std::vector Implementation::getNumMissingPackets() const { - std::vector mp(numThreads); - for (int i = 0; i < numThreads; i++) { + std::vector mp(numUDPInterfaces); + for (int i = 0; i < numUDPInterfaces; i++) { int np = generalData->packetsPerFrame; uint64_t totnp = np; // ReadNRows @@ -565,8 +569,9 @@ void Implementation::stopReceiver() { (numMods[X] * numMods[Y]) > 1) { dataProcessor[0]->CreateVirtualFile( filePath, fileName, fileIndex, overwriteEnable, silentMode, - modulePos, numThreads, framesPerFile, numberOfTotalFrames, - dynamicRange, numMods[X], numMods[Y], &hdf5Lib); + modulePos, numUDPInterfaces, framesPerFile, + numberOfTotalFrames, dynamicRange, numMods[X], numMods[Y], + &hdf5Lib); } // link file in master dataProcessor[0]->LinkDataInMasterFile(silentMode); @@ -603,7 +608,7 @@ void Implementation::stopReceiver() { } // print summary uint64_t tot = 0; - for (int i = 0; i < numThreads; i++) { + for (int i = 0; i < numUDPInterfaces; i++) { int nf = dataProcessor[i]->GetNumCompleteFramesCaught(); tot += nf; std::string mpMessage = std::to_string(mp[i]); @@ -634,7 +639,7 @@ void Implementation::stopReceiver() { // callback if (acquisitionFinishedCallBack) { try { - acquisitionFinishedCallBack((tot / numThreads), + acquisitionFinishedCallBack((tot / numUDPInterfaces), pAcquisitionFinished); } catch (const std::exception &e) { // change status @@ -815,7 +820,7 @@ void Implementation::SetupWriter() { for (unsigned int i = 0; i < dataProcessor.size(); ++i) { dataProcessor[i]->CreateFirstFiles( masterAttributes.get(), filePath, fileName, fileIndex, - overwriteEnable, silentMode, modulePos, numThreads, + overwriteEnable, silentMode, modulePos, numUDPInterfaces, udpPortNum[i], framesPerFile, numberOfTotalFrames, dynamicRange, detectorDataStream[i]); } @@ -873,14 +878,13 @@ void Implementation::setNumberofUDPInterfaces(const int n) { // set local variables generalData->SetNumberofInterfaces(n); - numThreads = generalData->threadsPerReceiver; udpSocketBufferSize = generalData->defaultUdpSocketBufferSize; // fifo SetupFifoStructure(); // create threads - for (int i = 0; i < numThreads; ++i) { + for (int i = 0; i < numUDPInterfaces; ++i) { // listener and dataprocessor threads try { auto fifo_ptr = fifo[i].get(); @@ -891,6 +895,11 @@ void Implementation::setNumberofUDPInterfaces(const int n) { &detectorDataStream[i], &silentMode)); listener[i]->SetGeneralData(generalData); + int ctbAnalogDataBytes = 0; + if (myDetectorType == CHIPTESTBOARD) { + ctbAnalogDataBytes = + generalData->GetNumberOfAnalogDatabytes(); + } dataProcessor.push_back(sls::make_unique( i, detType, fifo_ptr, &activated, &dataStreamEnable, &streamingFrequency, &streamingTimerInMs, @@ -919,7 +928,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) { (int *)nm, &quadEnable, &numberOfTotalFrames)); dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->CreateZmqSockets( - &numThreads, streamingPort, streamingSrcIP, + &numUDPInterfaces, streamingPort, streamingSrcIP, streamingHwm); dataStreamer[i]->SetAdditionalJsonHeader( additionalJsonHeader); @@ -1034,7 +1043,7 @@ void Implementation::setDataStreamEnable(const bool enable) { dataStreamer.clear(); if (enable) { - for (int i = 0; i < numThreads; ++i) { + for (int i = 0; i < numUDPInterfaces; ++i) { try { bool flip = flipRows; int nm[2] = {numMods[0], numMods[1]}; @@ -1048,7 +1057,7 @@ void Implementation::setDataStreamEnable(const bool enable) { (int *)nm, &quadEnable, &numberOfTotalFrames)); dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->CreateZmqSockets( - &numThreads, streamingPort, streamingSrcIP, + &numUDPInterfaces, streamingPort, streamingSrcIP, streamingHwm); dataStreamer[i]->SetAdditionalJsonHeader( additionalJsonHeader); @@ -1353,11 +1362,7 @@ void Implementation::setNumberofAnalogSamples(const uint32_t i) { if (numberOfAnalogSamples != i) { numberOfAnalogSamples = i; - ctbAnalogDataBytes = generalData->setImageSize( - tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, - numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, - readoutType); - + generalData->SetNumberOfAnalogSamples(i); SetupFifoStructure(); } LOG(logINFO) << "Number of Analog Samples: " << numberOfAnalogSamples; @@ -1372,11 +1377,7 @@ void Implementation::setNumberofDigitalSamples(const uint32_t i) { if (numberOfDigitalSamples != i) { numberOfDigitalSamples = i; - ctbAnalogDataBytes = generalData->setImageSize( - tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, - numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, - readoutType); - + generalData->SetNumberOfDigitalSamples(i); SetupFifoStructure(); } LOG(logINFO) << "Number of Digital Samples: " << numberOfDigitalSamples; @@ -1394,8 +1395,7 @@ void Implementation::setCounterMask(const uint32_t i) { ". Expected 1-3."); } counterMask = i; - generalData->SetNumberofCounters(ncounters, dynamicRange, - tengigaEnable); + generalData->SetNumberofCounters(ncounters); SetupFifoStructure(); } LOG(logINFO) << "Counter mask: " << sls::ToStringHex(counterMask); @@ -1410,14 +1410,7 @@ void Implementation::setDynamicRange(const uint32_t i) { dynamicRange = i; if (detType == EIGER || detType == MYTHEN3) { - - if (detType == EIGER) { - generalData->SetDynamicRange(i, tengigaEnable); - } else { - int ncounters = __builtin_popcount(counterMask); - generalData->SetNumberofCounters(ncounters, i, tengigaEnable); - } - + generalData->SetDynamicRange(i); fifoDepth = generalData->defaultFifoDepth; SetupFifoStructure(); } @@ -1447,25 +1440,8 @@ bool Implementation::getTenGigaEnable() const { return tengigaEnable; } void Implementation::setTenGigaEnable(const bool b) { if (tengigaEnable != b) { tengigaEnable = b; - int ncounters = __builtin_popcount(counterMask); - // side effects - switch (detType) { - case EIGER: - generalData->SetTenGigaEnable(b, dynamicRange); - break; - case MYTHEN3: - generalData->SetNumberofCounters(ncounters, dynamicRange, b); - break; - case MOENCH: - case CHIPTESTBOARD: - ctbAnalogDataBytes = generalData->setImageSize( - tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, - numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, - readoutType); - break; - default: - break; - } + + generalData->SetTenGigaEnable(b); SetupFifoStructure(); } LOG(logINFO) << "Ten Giga: " << (tengigaEnable ? "enabled" : "disabled"); @@ -1568,11 +1544,7 @@ void Implementation::setReadoutMode(const readoutMode f) { if (readoutType != f) { readoutType = f; - // side effects - ctbAnalogDataBytes = generalData->setImageSize( - tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, - numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, - readoutType); + generalData->SetReadoutMode(f); SetupFifoStructure(); } LOG(logINFO) << "Readout Mode: " << sls::ToString(f); @@ -1586,11 +1558,8 @@ uint32_t Implementation::getADCEnableMask() const { void Implementation::setADCEnableMask(uint32_t mask) { if (adcEnableMaskOneGiga != mask) { adcEnableMaskOneGiga = mask; - ctbAnalogDataBytes = generalData->setImageSize( - tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, - numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, - readoutType); + generalData->SetOneGigaAdcEnableMask(mask); SetupFifoStructure(); } LOG(logINFO) << "ADC Enable Mask for 1Gb mode: 0x" << std::hex @@ -1606,11 +1575,7 @@ void Implementation::setTenGigaADCEnableMask(uint32_t mask) { if (adcEnableMaskTenGiga != mask) { adcEnableMaskTenGiga = mask; - ctbAnalogDataBytes = generalData->setImageSize( - tengigaEnable ? adcEnableMaskTenGiga : adcEnableMaskOneGiga, - numberOfAnalogSamples, numberOfDigitalSamples, tengigaEnable, - readoutType); - + generalData->SetTenGigaAdcEnableMask(mask); SetupFifoStructure(); } LOG(logINFO) << "ADC Enable Mask for 10Gb mode: 0x" << std::hex diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 5e5baf863..c29171fd4 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -278,7 +278,6 @@ class Implementation : private virtual slsDetectorDefs { * ************************************************/ // config parameters - int numThreads{1}; detectorType detType{GENERIC}; int numMods[MAX_DIMENSIONS] = {0, 0}; int modulePos{0}; @@ -361,7 +360,6 @@ class Implementation : private virtual slsDetectorDefs { uint32_t adcEnableMaskTenGiga{BIT32_MASK}; std::vector ctbDbitList; int ctbDbitOffset{0}; - int ctbAnalogDataBytes{0}; // callbacks int (*startAcquisitionCallBack)(std::string, std::string, uint64_t,