From 23aa9c2814de02411c5e9b2b1696f5ef9927794e Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Tue, 11 Mar 2025 12:07:10 +0100 Subject: [PATCH 01/38] added reorder variable, changed function ArrangeDBitData to support reordering and no reordering. Moved transceiver data such that it is contiguous with rearranged digital data --- slsReceiverSoftware/src/DataProcessor.cpp | 128 ++++++++++++++++------ slsReceiverSoftware/src/DataProcessor.h | 8 +- 2 files changed, 99 insertions(+), 37 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index fd5f2456a..49a5ed6f3 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -75,6 +75,10 @@ void DataProcessor::SetCtbDbitList(std::vector value) { ctbDbitList = value; } +void DataProcessor::SetReorder(const bool value) { + reorder = value; +} + void DataProcessor::SetCtbDbitOffset(int value) { ctbDbitOffset = value; } void DataProcessor::SetQuadEnable(bool value) { quadEnable = value; } @@ -213,8 +217,9 @@ std::string DataProcessor::CreateVirtualFile( "Skipping virtual hdf5 file since rx_roi is enabled."); } - bool gotthard25um = - (generalData->detType == GOTTHARD2 && (numModX * numModY) == 2); + bool gotthard25um = ((generalData->detType == GOTTHARD || + generalData->detType == GOTTHARD2) && + (numModX * numModY) == 2); // 0 for infinite files uint32_t framesPerFile = @@ -357,7 +362,7 @@ void DataProcessor::ProcessAnImage(sls_receiver_header &header, size_t &size, // rearrange ctb digital bits (if ctbDbitlist is not empty) if (!ctbDbitList.empty()) { - RearrangeDbitData(size, data); + ArrangeDbitData(size, data); } // 'stream Image' check has to be done here before crop image @@ -504,6 +509,16 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) { // missing packet switch (generalData->detType) { + // for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes + // data + // 2nd packet: 4 bytes fnum, previous 1*2 bytes data + + // 640*2 bytes data !! + case GOTTHARD: + if (pnum == 0u) + memset(data + (pnum * dsize), 0xFF, dsize - 2); + else + memset(data + (pnum * dsize), 0xFF, dsize + 2); + break; case CHIPTESTBOARD: case XILINX_CHIPTESTBOARD: if (pnum == (pperFrame - 1)) @@ -520,10 +535,10 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) { } /** ctb specific */ -void DataProcessor::RearrangeDbitData(size_t &size, char *data) { - int nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); - int nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); - int nTransceiverDataBytes = generalData->GetNumberOfTransceiverDatabytes(); +void DataProcessor::ArrangeDbitData(size_t &size, char *data) { + size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); + size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); + size_t nTransceiverDataBytes = generalData->GetNumberOfTransceiverDatabytes(); // TODO! (Erik) Refactor and add tests int ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset; @@ -534,47 +549,90 @@ void DataProcessor::RearrangeDbitData(size_t &size, char *data) { return; } - const int numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); - - // const int numResult8Bits = ceil((numDigitalSamples * ctbDbitList.size()) - // / 8.00); - int numBitsPerDbit = numDigitalSamples; - if ((numBitsPerDbit % 8) != 0) - numBitsPerDbit += (8 - (numDigitalSamples % 8)); - const int totalNumBytes = (numBitsPerDbit / 8) * ctbDbitList.size(); - std::vector result(totalNumBytes); - uint8_t *dest = &result[0]; - auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); - // loop through digital bit enable vector - int bitoffset = 0; - for (auto bi : ctbDbitList) { - // where numbits * numDigitalSamples is not a multiple of 8 - if (bitoffset != 0) { - bitoffset = 0; - ++dest; - } + const int numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); - // loop through the frame digital data - for (auto *ptr = source; ptr < (source + numDigitalSamples);) { - // get selected bit from each 8 bit - uint8_t bit = (*ptr++ >> bi) & 1; - *dest |= bit << bitoffset; - ++bitoffset; - // extract destination in 8 bit batches - if (bitoffset == 8) { + int totalNumBytes = 0; //number of bytes for selected digital data given by dtbDbitList + + //store each selected bit from all samples consecutively + if(reorder) { + int numBitsPerDbit = numDigitalSamples; //num bits per selected digital Bit for all samples + if ((numBitsPerDbit % 8) != 0) + numBitsPerDbit += (8 - (numDigitalSamples % 8)); + totalNumBytes = (numBitsPerDbit / 8) * ctbDbitList.size(); + } + //store all selected bits from one sample consecutively + else { + size_t numBitsPerSample = ctbDbitList.size(); //num bits for all selected bits per sample + if ((numBitsPerSample % 8) != 0) + numBitsPerSample += (8 - (numBitsPerSample % 8)); + totalNumBytes = (numBitsPerSample / 8) * numDigitalSamples; + } + + std::vector result(totalNumBytes, 0); + uint8_t *dest = &result[0]; + + if(reorder) { + // loop through digital bit enable vector + int bitoffset = 0; + for (auto bi : ctbDbitList) { + // where numbits * numDigitalSamples is not a multiple of 8 + if (bitoffset != 0) { bitoffset = 0; ++dest; } + + // loop through the frame digital data + for (auto *ptr = source; ptr < (source + numDigitalSamples);) { + // get selected bit from each 8 bit + uint8_t bit = (*ptr++ >> bi) & 1; + *dest |= bit << bitoffset; + ++bitoffset; + // extract destination in 8 bit batches + if (bitoffset == 8) { + bitoffset = 0; + ++dest; + } + } + } + } + else { + // loop through the digital data + int bitoffset = 0; + for (auto *ptr = source; ptr < (source + numDigitalSamples); ++ptr) { + // where bit enable vector size is not a multiple of 8 + if (bitoffset != 0) { + bitoffset = 0; + ++dest; + } + + // loop through digital bit enable vector + for (auto bi : ctbDbitList) { + // get selected bit from each 64 bit + uint8_t bit = (*ptr >> bi) & 1; + *dest |= bit << bitoffset; + ++bitoffset; + // extract destination in 8 bit batches + if (bitoffset == 8) { + bitoffset = 0; + ++dest; + } + } } } // copy back to memory and update size memcpy(data + nAnalogDataBytes, result.data(), totalNumBytes * sizeof(uint8_t)); - size = totalNumBytes * sizeof(uint8_t) + nAnalogDataBytes + ctbDbitOffset + + + size = totalNumBytes * sizeof(uint8_t) + nAnalogDataBytes + nTransceiverDataBytes; + + //check if size changed, if so move transceiver data to avoid gap in memory + if(size < nAnalogDataBytes + nDigitalDataBytes + nTransceiverDataBytes) + memmove(data + nAnalogDataBytes + totalNumBytes * sizeof(uint8_t), data + nAnalogDataBytes + nDigitalDataBytes, nTransceiverDataBytes); + LOG(logDEBUG1) << "totalNumBytes: " << totalNumBytes << " nAnalogDataBytes:" << nAnalogDataBytes << " ctbDbitOffset:" << ctbDbitOffset diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 29ea9e84c..4937d0d37 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -46,6 +46,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { void SetStreamingStartFnum(uint32_t value); void SetFramePadding(bool enable); void SetCtbDbitList(std::vector value); + void SetReorder(const bool reorder); void SetCtbDbitOffset(int value); void SetQuadEnable(bool value); void SetFlipRows(bool fd); @@ -139,9 +140,11 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { /** * Align corresponding digital bits together (CTB only if ctbDbitlist is not - * empty) + * empty) + * set variable reorder to true if, data should be rearranged such that + * individual digital bits from all samples are consecutive in memory */ - void RearrangeDbitData(size_t &size, char *data); + void ArrangeDbitData(size_t &size, char *data); void CropImage(size_t &size, char *data); @@ -165,6 +168,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { struct timespec timerbegin {}; bool framePadding; std::vector ctbDbitList; + bool reorder{false}; //true if data should be reordered TODO: add as mode int ctbDbitOffset; std::atomic startedFlag{false}; std::atomic firstIndex{0}; From 8d87a6ee4ecedc2da750ac7273b4b4727e949de3 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Tue, 11 Mar 2025 16:32:31 +0100 Subject: [PATCH 02/38] used clang-formating --- slsReceiverSoftware/src/DataProcessor.cpp | 43 ++++++++++++---------- slsReceiverSoftware/src/DataProcessor.h | 8 ++-- slsReceiverSoftware/src/Implementation.cpp | 6 +-- slsSupportLib/include/sls/versionAPI.h | 10 ++--- 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 49a5ed6f3..e80ab531e 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -75,9 +75,7 @@ void DataProcessor::SetCtbDbitList(std::vector value) { ctbDbitList = value; } -void DataProcessor::SetReorder(const bool value) { - reorder = value; -} +void DataProcessor::SetReorder(const bool value) { reorder = value; } void DataProcessor::SetCtbDbitOffset(int value) { ctbDbitOffset = value; } @@ -536,9 +534,10 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) { /** ctb specific */ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { - size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); + size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); - size_t nTransceiverDataBytes = generalData->GetNumberOfTransceiverDatabytes(); + size_t nTransceiverDataBytes = + generalData->GetNumberOfTransceiverDatabytes(); // TODO! (Erik) Refactor and add tests int ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset; @@ -553,18 +552,21 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { const int numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); - int totalNumBytes = 0; //number of bytes for selected digital data given by dtbDbitList + int totalNumBytes = + 0; // number of bytes for selected digital data given by dtbDbitList - //store each selected bit from all samples consecutively - if(reorder) { - int numBitsPerDbit = numDigitalSamples; //num bits per selected digital Bit for all samples + // store each selected bit from all samples consecutively + if (reorder) { + int numBitsPerDbit = numDigitalSamples; // num bits per selected digital + // Bit for all samples if ((numBitsPerDbit % 8) != 0) numBitsPerDbit += (8 - (numDigitalSamples % 8)); totalNumBytes = (numBitsPerDbit / 8) * ctbDbitList.size(); } - //store all selected bits from one sample consecutively - else { - size_t numBitsPerSample = ctbDbitList.size(); //num bits for all selected bits per sample + // store all selected bits from one sample consecutively + else { + size_t numBitsPerSample = + ctbDbitList.size(); // num bits for all selected bits per sample if ((numBitsPerSample % 8) != 0) numBitsPerSample += (8 - (numBitsPerSample % 8)); totalNumBytes = (numBitsPerSample / 8) * numDigitalSamples; @@ -573,7 +575,7 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { std::vector result(totalNumBytes, 0); uint8_t *dest = &result[0]; - if(reorder) { + if (reorder) { // loop through digital bit enable vector int bitoffset = 0; for (auto bi : ctbDbitList) { @@ -596,8 +598,7 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { } } } - } - else { + } else { // loop through the digital data int bitoffset = 0; for (auto *ptr = source; ptr < (source + numDigitalSamples); ++ptr) { @@ -625,13 +626,15 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { // copy back to memory and update size memcpy(data + nAnalogDataBytes, result.data(), totalNumBytes * sizeof(uint8_t)); - + size = totalNumBytes * sizeof(uint8_t) + nAnalogDataBytes + nTransceiverDataBytes; - - //check if size changed, if so move transceiver data to avoid gap in memory - if(size < nAnalogDataBytes + nDigitalDataBytes + nTransceiverDataBytes) - memmove(data + nAnalogDataBytes + totalNumBytes * sizeof(uint8_t), data + nAnalogDataBytes + nDigitalDataBytes, nTransceiverDataBytes); + + // check if size changed, if so move transceiver data to avoid gap in memory + if (size < nAnalogDataBytes + nDigitalDataBytes + nTransceiverDataBytes) + memmove(data + nAnalogDataBytes + totalNumBytes * sizeof(uint8_t), + data + nAnalogDataBytes + nDigitalDataBytes, + nTransceiverDataBytes); LOG(logDEBUG1) << "totalNumBytes: " << totalNumBytes << " nAnalogDataBytes:" << nAnalogDataBytes diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 4937d0d37..d09a9ca3f 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -140,11 +140,11 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { /** * Align corresponding digital bits together (CTB only if ctbDbitlist is not - * empty) - * set variable reorder to true if, data should be rearranged such that + * empty) + * set variable reorder to true if, data should be rearranged such that * individual digital bits from all samples are consecutive in memory */ - void ArrangeDbitData(size_t &size, char *data); + void ArrangeDbitData(size_t &size, char *data); void CropImage(size_t &size, char *data); @@ -168,7 +168,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { struct timespec timerbegin {}; bool framePadding; std::vector ctbDbitList; - bool reorder{false}; //true if data should be reordered TODO: add as mode + bool reorder{false}; // true if data should be reordered TODO: add as mode int ctbDbitOffset; std::atomic startedFlag{false}; std::atomic firstIndex{0}; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 6016d10fb..8104e8c7a 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -915,10 +915,10 @@ void Implementation::CreateUDPSockets() { } void Implementation::SetupWriter() { - + try { - //check if filePath empty and throw error - if(filePath.empty()){ + // check if filePath empty and throw error + if (filePath.empty()) { throw ReceiverError("File path cannot be empty"); } // check if folder exists and throw if it cant create diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 4fbb0db7b..7a0e6c77b 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -3,10 +3,10 @@ /** API versions */ #define APILIB "developer 0x241122" #define APIRECEIVER "developer 0x241122" -#define APICTB "developer 0x250310" +#define APICTB "developer 0x250310" #define APIGOTTHARD2 "developer 0x250310" -#define APIJUNGFRAU "developer 0x250310" -#define APIMYTHEN3 "developer 0x250310" -#define APIMOENCH "developer 0x250310" +#define APIJUNGFRAU "developer 0x250310" +#define APIMYTHEN3 "developer 0x250310" +#define APIMOENCH "developer 0x250310" #define APIXILINXCTB "developer 0x250310" -#define APIEIGER "developer 0x250310" +#define APIEIGER "developer 0x250310" From 63bb79d727bd3998a696ce347d238d93a8009f8c Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Wed, 12 Mar 2025 10:51:18 +0100 Subject: [PATCH 03/38] added first rather generic test for Rearrange Function, could be changed to a parametrized test --- slsReceiverSoftware/src/DataProcessor.h | 17 +-- slsReceiverSoftware/tests/CMakeLists.txt | 3 + .../tests/test-ArrangeDataBasedOnBitList.cpp | 134 ++++++++++++++++++ 3 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index d09a9ca3f..458e750c5 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -92,6 +92,15 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { size_t &, void *), void *arg); + protected: + /** + * Align corresponding digital bits together (CTB only if ctbDbitlist is not + * empty) + * set variable reorder to true if, data should be rearranged such that + * individual digital bits from all samples are consecutive in memory + */ + void ArrangeDbitData(size_t &size, char *data); + private: void RecordFirstIndex(uint64_t fnum); @@ -138,14 +147,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { void PadMissingPackets(sls_receiver_header header, char *data); - /** - * Align corresponding digital bits together (CTB only if ctbDbitlist is not - * empty) - * set variable reorder to true if, data should be rearranged such that - * individual digital bits from all samples are consecutive in memory - */ - void ArrangeDbitData(size_t &size, char *data); - void CropImage(size_t &size, char *data); static const std::string typeName; diff --git a/slsReceiverSoftware/tests/CMakeLists.txt b/slsReceiverSoftware/tests/CMakeLists.txt index e656b51ad..9a9455408 100755 --- a/slsReceiverSoftware/tests/CMakeLists.txt +++ b/slsReceiverSoftware/tests/CMakeLists.txt @@ -3,6 +3,9 @@ target_sources(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test-GeneralData.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-CircularFifo.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test-ArrangeDataBasedOnBitList.cpp ) target_include_directories(tests PUBLIC "$") + +message(STATUS "Resolved path: ${CMAKE_CURRENT_SOURCE_DIR}/../src") \ No newline at end of file diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp new file mode 100644 index 000000000..3012ddf64 --- /dev/null +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2025 Contributors to the SLS Detector Package +/************************************************ + * @file test-ArrangeDataBasedOnBitList.cpp + * @short test case for DataProcessor member function ArrangeDbitData, + ***********************************************/ + +#include "DataProcessor.h" +#include "GeneralData.h" +#include "catch.hpp" +#include + +namespace sls { + +// dummy GeneralData class for testing +class GeneralDataTest : public GeneralData { + + public: + int GetNumberOfAnalogDatabytes() { return nAnalogBytes; }; + + int GetNumberOfDigitalDatabytes() { return nDigitalBytes; }; + + int GetNumberOfTransceiverDatabytes() { return nTransceiverBytes; }; + + void SetNumberOfAnalogDatabytes(int value) { nAnalogBytes = value; } + + void SetNumberOfDigitalDatabytes(int value) { nDigitalBytes = value; } + + void SetNumberOfTransceiverDatabytes(int value) { + nTransceiverBytes = value; + } + + private: + int nAnalogBytes; + int nDigitalBytes; + int nTransceiverBytes; +}; + +// oke maybe just make it static +class DataProcessorTest : public DataProcessor { + public: + DataProcessorTest() : DataProcessor(0){}; + ~DataProcessorTest(){}; + void ArrangeDbitData(size_t &size, char *data) { + DataProcessor::ArrangeDbitData(size, data); + } +}; + +TEST_CASE("Arrange with reorder false") { + DataProcessorTest dataprocessor; + + std::vector bitlist{1, 4, 5}; + dataprocessor.SetCtbDbitList(bitlist); + + size_t num_digital_samples = 5; // size_t or uint8_t ? + size_t num_digital_bytes = num_digital_samples * 8; + size_t num_analog_bytes = 1; + size_t num_transceiver_bytes = 2; + size_t random_offset_bytes = 0; + + size_t size = num_analog_bytes + num_digital_bytes + num_transceiver_bytes + + random_offset_bytes; + + char *data = new char[size]; + + char dummy_value = static_cast(125); + memset(data, dummy_value, num_analog_bytes); + memset(data + num_analog_bytes, 0xFF, + num_digital_bytes); // all digital bits are one + memset(data + num_digital_bytes + num_analog_bytes, dummy_value, + num_transceiver_bytes); + + GeneralDataTest *generaldata = new GeneralDataTest; + generaldata->SetNumberOfAnalogDatabytes(num_analog_bytes); + generaldata->SetNumberOfDigitalDatabytes(num_digital_bytes); + generaldata->SetNumberOfTransceiverDatabytes(num_transceiver_bytes); + + dataprocessor.SetGeneralData(generaldata); + + size_t new_num_digital_bytes = + (bitlist.size() / 8 + static_cast(bitlist.size() % 8 != 0)) * + num_digital_samples; + + size_t new_size = + num_analog_bytes + num_transceiver_bytes + new_num_digital_bytes; + + char *new_data = new char[new_size]; + + memset(new_data, dummy_value, num_analog_bytes); + + // TODO: Make test more explicit and less generic + size_t num_bytes_for_bitlist = + bitlist.size() / 8 + static_cast(bitlist.size() % 8 != 0); + + // 125 7 7 7 7 7 125 125 + for (size_t sample = 0; sample < num_digital_samples; ++sample) { + if (bitlist.size() / 8 != 0) { + memset(new_data + sample * num_bytes_for_bitlist + num_analog_bytes, + 0xFF, + bitlist.size() / 8); // set to 1 + } else if (bitlist.size() % 8 != 0) { + memset(new_data + sample * num_bytes_for_bitlist + + bitlist.size() / 8 + num_analog_bytes, + static_cast(pow(2, (bitlist.size() % 8)) - 1), + 1); // convert binary number to decimal + } + } + + memset(new_data + new_num_digital_bytes + num_analog_bytes, dummy_value, + num_transceiver_bytes); + + dataprocessor.ArrangeDbitData(size, data); + + CHECK(size == new_size); + + CHECK(memcmp(data, new_data, size) == 0); + + // Free allocated memory + delete[] data; + delete[] new_data; + delete generaldata; +} + +// TEST_CASE("Arrange with reorder on") { + +//} + +// test case reorder on and bitoffset set + +// test with different samples + +// test with sample number not divisable and ctbitlist not divisable + +} // namespace sls From a74fb2bcd1306a71f6e1e8ad4398fca01aa1f95f Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Wed, 12 Mar 2025 16:12:00 +0100 Subject: [PATCH 04/38] added function Reorder --- slsReceiverSoftware/src/DataProcessor.cpp | 88 ++++++++++++++++++++++- slsReceiverSoftware/src/DataProcessor.h | 6 ++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index e80ab531e..ce744e531 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -358,6 +358,10 @@ void DataProcessor::ProcessAnImage(sls_receiver_header &header, size_t &size, if (framePadding && nump < generalData->packetsPerFrame) PadMissingPackets(header, data); + if (reorder && ctbDbitList.empty()) { + Reorder(size, data); + } + // rearrange ctb digital bits (if ctbDbitlist is not empty) if (!ctbDbitList.empty()) { ArrangeDbitData(size, data); @@ -532,6 +536,88 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) { } } +void DataProcessor::Reorder(size_t &size, char *data) { + const size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); + const size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); + const size_t nTransceiverDataBytes = + generalData->GetNumberOfTransceiverDatabytes(); + + const size_t ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset; + + // no digital data + if (ctbDigitalDataBytes == 0) { + LOG(logWARNING) + << "No digital data for call back, yet reorder is set to 1."; + return; + } + + auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); + + const size_t numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); + + size_t numBytesPerBit = + 0; // number of bytes per bit in digital data after reordering + + if ((numDigitalSamples % 8) == 0) + numBytesPerBit = numDigitalSamples / 8; + else + numBytesPerBit = numDigitalSamples / 8 + 1; + + size_t totalNumBytes = + numBytesPerBit * + 64; // number of bytes for digital data after reordering + + LOG(logDEBUG1) << "totalNumBytes: " << totalNumBytes + << " nAnalogDataBytes:" << nAnalogDataBytes + << " nDigitalDataBytes: " << nDigitalDataBytes + << " ctbDbitOffset:" << ctbDbitOffset + << " nTransceiverDataBytes:" << nTransceiverDataBytes + << " size:" << size << " numsamples:" << numDigitalSamples; + + std::vector result(totalNumBytes, 0); + uint8_t *dest = &result[0]; + + int bitoffset = 0; + // reorder + for (size_t bi = 0; bi < 64; ++bi) { + + if (bitoffset != 0) { + bitoffset = 0; + ++dest; + } + + for (auto *ptr = source; ptr < (source + numDigitalSamples); ++ptr) { + uint8_t bit = (*ptr >> bi) & 1; + *dest |= bit << bitoffset; // most significant bits will be padded + ++bitoffset; + + if (bitoffset == 8) { + bitoffset = 0; + ++dest; + } + } + } + + // move transceiver data to not overwrite and avoid gap in memory + if (totalNumBytes != nDigitalDataBytes) + memmove(data + nAnalogDataBytes + totalNumBytes * sizeof(uint8_t), + data + nAnalogDataBytes + nDigitalDataBytes, + nTransceiverDataBytes); + + // copy back to memory and update size + size = totalNumBytes * sizeof(uint8_t) + nAnalogDataBytes + + nTransceiverDataBytes; + + memcpy(data + nAnalogDataBytes, result.data(), + totalNumBytes * sizeof(uint8_t)); + + LOG(logDEBUG1) << "totalNumBytes: " << totalNumBytes + << " nAnalogDataBytes:" << nAnalogDataBytes + << " ctbDbitOffset:" << ctbDbitOffset + << " nTransceiverDataBytes:" << nTransceiverDataBytes + << " size:" << size; +} + /** ctb specific */ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); @@ -589,7 +675,7 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { for (auto *ptr = source; ptr < (source + numDigitalSamples);) { // get selected bit from each 8 bit uint8_t bit = (*ptr++ >> bi) & 1; - *dest |= bit << bitoffset; + *dest |= bit << bitoffset; // stored as least significant ++bitoffset; // extract destination in 8 bit batches if (bitoffset == 8) { diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 458e750c5..6b4d9d6d9 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -101,6 +101,12 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { */ void ArrangeDbitData(size_t &size, char *data); + /** + * reorder datastream such that individual digital bits from all samples are + * stored consecutively in memory + */ + void Reorder(size_t &size, char *data); + private: void RecordFirstIndex(uint64_t fnum); From 3c79e8d7b2fae623ab3fbf84d50d52948734a89e Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Wed, 12 Mar 2025 16:38:18 +0100 Subject: [PATCH 05/38] trailing bits are removed even if reorder false and bitlist empty --- slsReceiverSoftware/src/DataProcessor.cpp | 33 +++++++++++++++++++---- slsReceiverSoftware/src/DataProcessor.h | 7 ++++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index ce744e531..b0a3550ae 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -358,13 +358,13 @@ void DataProcessor::ProcessAnImage(sls_receiver_header &header, size_t &size, if (framePadding && nump < generalData->packetsPerFrame) PadMissingPackets(header, data); - if (reorder && ctbDbitList.empty()) { - Reorder(size, data); - } - - // rearrange ctb digital bits (if ctbDbitlist is not empty) + // rearrange ctb digital bits if (!ctbDbitList.empty()) { ArrangeDbitData(size, data); + } else if (reorder) { + Reorder(size, data); + } else if (ctbDbitOffset > 0) { + RemoveTrailingBits(size, data); } // 'stream Image' check has to be done here before crop image @@ -536,6 +536,29 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) { } } +void DataProcessor::RemoveTrailingBits(size_t &size, char *data) { + const size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); + const size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); + const size_t nTransceiverDataBytes = + generalData->GetNumberOfTransceiverDatabytes(); + + const size_t ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset; + + // no digital data + if (ctbDigitalDataBytes == 0) { + LOG(logWARNING) + << "No digital data for call back, yet ctbDbitOffset is non zero."; + return; + } + + // update size and copy data + memmove(data + nAnalogDataBytes, + data + nAnalogDataBytes + ctbDigitalDataBytes, + ctbDigitalDataBytes + nTransceiverDataBytes); + + size = nAnalogDataBytes + ctbDigitalDataBytes + nTransceiverDataBytes; +} + void DataProcessor::Reorder(size_t &size, char *data) { const size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); const size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 6b4d9d6d9..6febaedbf 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -107,6 +107,11 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { */ void Reorder(size_t &size, char *data); + /** + * remove trailing bits in digital data stream + */ + void RemoveTrailingBits(size_t &size, char *data); + private: void RecordFirstIndex(uint64_t fnum); @@ -172,7 +177,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { uint32_t streamingTimerInMs; uint32_t streamingStartFnum; uint32_t currentFreqCount{0}; - struct timespec timerbegin {}; + struct timespec timerbegin{}; bool framePadding; std::vector ctbDbitList; bool reorder{false}; // true if data should be reordered TODO: add as mode From e8ac0481141b0b43792ab8b575fda70fbf2aedd4 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 12 Mar 2025 17:13:30 +0100 Subject: [PATCH 06/38] ctb: added command 'rx_dbitreorder' that sets a flag in the receiver to set the reorder flag. By default it is 1. Setting to false means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together --- python/slsdet/detector.py | 10 +++ .../autocomplete/bash_autocomplete.sh | 11 +++- .../autocomplete/zsh_autocomplete.sh | 11 +++- slsDetectorSoftware/generator/commands.yaml | 12 ++++ .../generator/extended_commands.yaml | 41 ++++++++++++ slsDetectorSoftware/include/sls/Detector.h | 9 +++ slsDetectorSoftware/src/Caller.cpp | 62 +++++++++++++++++++ slsDetectorSoftware/src/Caller.h | 2 + slsDetectorSoftware/src/Detector.cpp | 8 +++ slsDetectorSoftware/src/Module.cpp | 9 +++ slsDetectorSoftware/src/Module.h | 2 + slsDetectorSoftware/src/inferAction.cpp | 16 +++++ slsDetectorSoftware/src/inferAction.h | 2 + slsReceiverSoftware/src/ClientInterface.cpp | 23 +++++++ slsReceiverSoftware/src/ClientInterface.h | 2 + slsReceiverSoftware/src/DataProcessor.cpp | 8 +-- slsReceiverSoftware/src/DataProcessor.h | 6 +- slsReceiverSoftware/src/Implementation.cpp | 10 +++ slsReceiverSoftware/src/Implementation.h | 5 ++ .../include/sls/sls_detector_funcs.h | 5 +- 20 files changed, 244 insertions(+), 10 deletions(-) diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 459e4a25c..3a34f80ad 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -3463,6 +3463,16 @@ class Detector(CppDetectorApi): def rx_dbitoffset(self, value): ut.set_using_dict(self.setRxDbitOffset, value) + @property + @element + def rx_dbitreorder(self): + """[Ctb] Reorder digital data to group together all samples per signal. Default is 1. Setting to 0 means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together.""" + return self.getRxDbitReorder() + + @rx_dbitreorder.setter + def rx_dbitreorder(self, value): + ut.set_using_dict(self.setRxDbitReorder, value) + @property @element def maxadcphaseshift(self): diff --git a/slsDetectorSoftware/generator/autocomplete/bash_autocomplete.sh b/slsDetectorSoftware/generator/autocomplete/bash_autocomplete.sh index 9345f192d..3ce858ee8 100644 --- a/slsDetectorSoftware/generator/autocomplete/bash_autocomplete.sh +++ b/slsDetectorSoftware/generator/autocomplete/bash_autocomplete.sh @@ -80,7 +80,7 @@ _sd() { local IS_PATH=0 -local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport " +local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport " __acquire() { FCN_RETURN="" return 0 @@ -2088,6 +2088,15 @@ fi fi return 0 } +__rx_dbitreorder() { +FCN_RETURN="" +if [[ ${IS_GET} -eq 0 ]]; then +if [[ "${cword}" == "2" ]]; then +FCN_RETURN="0 1" +fi +fi +return 0 +} __rx_discardpolicy() { FCN_RETURN="" if [[ ${IS_GET} -eq 0 ]]; then diff --git a/slsDetectorSoftware/generator/autocomplete/zsh_autocomplete.sh b/slsDetectorSoftware/generator/autocomplete/zsh_autocomplete.sh index 9eaf07382..c59c1e4a3 100644 --- a/slsDetectorSoftware/generator/autocomplete/zsh_autocomplete.sh +++ b/slsDetectorSoftware/generator/autocomplete/zsh_autocomplete.sh @@ -4,7 +4,7 @@ _sd() { -local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport " +local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport " __acquire() { FCN_RETURN="" return 0 @@ -2012,6 +2012,15 @@ fi fi return 0 } +__rx_dbitreorder() { +FCN_RETURN="" +if [[ ${IS_GET} -eq 0 ]]; then +if [[ "${cword}" == "2" ]]; then +FCN_RETURN="0 1" +fi +fi +return 0 +} __rx_discardpolicy() { FCN_RETURN="" if [[ ${IS_GET} -eq 0 ]]; then diff --git a/slsDetectorSoftware/generator/commands.yaml b/slsDetectorSoftware/generator/commands.yaml index 95c4f0ca8..47e2e1898 100644 --- a/slsDetectorSoftware/generator/commands.yaml +++ b/slsDetectorSoftware/generator/commands.yaml @@ -1412,6 +1412,18 @@ lock: function: setDetectorLock input_types: [ bool ] + +rx_dbitreorder: + help: "[0, 1]\n\t[Ctb] Reorder digital data to group together all samples per signal. Default is 1. Setting to 0 means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together." + inherit_actions: INTEGER_COMMAND_VEC_ID + actions: + GET: + function: getRxDbitReorder + PUT: + function: setRxDbitReorder + input_types: [ bool ] + + ################# INTEGER_COMMAND_VEC_ID_GET ################# master: diff --git a/slsDetectorSoftware/generator/extended_commands.yaml b/slsDetectorSoftware/generator/extended_commands.yaml index 908cc2dfb..4e4b52a72 100644 --- a/slsDetectorSoftware/generator/extended_commands.yaml +++ b/slsDetectorSoftware/generator/extended_commands.yaml @@ -8305,6 +8305,47 @@ rx_dbitoffset: help: "[n_bytes]\n\t[Ctb] Offset in bytes in digital data to skip in receiver." infer_action: true template: true +rx_dbitreorder: + actions: + GET: + args: + - arg_types: [] + argc: 0 + cast_input: [] + check_det_id: false + convert_det_id: true + function: getRxDbitReorder + input: [] + input_types: [] + output: + - OutString(t) + require_det_id: true + store_result_in_t: true + PUT: + args: + - arg_types: + - bool + argc: 1 + cast_input: + - true + check_det_id: false + convert_det_id: true + function: setRxDbitReorder + input: + - args[0] + input_types: + - bool + output: + - args.front() + require_det_id: true + store_result_in_t: false + command_name: rx_dbitreorder + function_alias: rx_dbitreorder + help: "[0, 1]\n\t[Ctb] Reorder digital data to group together all samples per signal.\ + \ Default is 1. Setting to 0 means 'do not reorder' and to keep what the board\ + \ spits out, which is that all signals in a sample are grouped together." + infer_action: true + template: true rx_discardpolicy: actions: GET: diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index a58265324..8096f75a7 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1729,6 +1729,15 @@ class Detector { /** [CTB] Set number of bytes of digital data to skip in the Receiver */ void setRxDbitOffset(int value, Positions pos = {}); + /** [CTB] */ + Result getRxDbitReorder(Positions pos = {}) const; + + /** [CTB] Reorder digital data to group together all samples per signal. + * Default is true. Setting to false means 'do not reorder' and to keep what + * the board spits out, which is that all signals in a sample are grouped + * together */ + void setRxDbitReorder(bool reorder, Positions pos = {}); + /** * [CTB] Set Digital IO Delay * cannot get diff --git a/slsDetectorSoftware/src/Caller.cpp b/slsDetectorSoftware/src/Caller.cpp index da761afa2..c284b1957 100644 --- a/slsDetectorSoftware/src/Caller.cpp +++ b/slsDetectorSoftware/src/Caller.cpp @@ -10700,6 +10700,68 @@ std::string Caller::rx_dbitoffset(int action) { return os.str(); } +std::string Caller::rx_dbitreorder(int action) { + + std::ostringstream os; + // print help + if (action == slsDetectorDefs::HELP_ACTION) { + os << R"V0G0N([0, 1] + [Ctb] Reorder digital data to group together all samples per signal. Default is 1. Setting to 0 means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together. )V0G0N" + << std::endl; + return os.str(); + } + + // check if action and arguments are valid + if (action == slsDetectorDefs::GET_ACTION) { + if (1 && args.size() != 0) { + throw RuntimeError("Wrong number of arguments for action GET"); + } + + if (args.size() == 0) { + } + + } + + else if (action == slsDetectorDefs::PUT_ACTION) { + if (1 && args.size() != 1) { + throw RuntimeError("Wrong number of arguments for action PUT"); + } + + if (args.size() == 1) { + try { + StringTo(args[0]); + } catch (...) { + throw RuntimeError("Could not convert argument 0 to bool"); + } + } + + } + + else { + + throw RuntimeError("INTERNAL ERROR: Invalid action: supported actions " + "are ['GET', 'PUT']"); + } + + // generate code for each action + if (action == slsDetectorDefs::GET_ACTION) { + if (args.size() == 0) { + auto t = det->getRxDbitReorder(std::vector{det_id}); + os << OutString(t) << '\n'; + } + } + + if (action == slsDetectorDefs::PUT_ACTION) { + if (args.size() == 1) { + auto arg0 = StringTo(args[0]); + det->setRxDbitReorder(arg0, std::vector{det_id}); + os << args.front() << '\n'; + } + } + + return os.str(); +} + std::string Caller::rx_discardpolicy(int action) { std::ostringstream os; diff --git a/slsDetectorSoftware/src/Caller.h b/slsDetectorSoftware/src/Caller.h index d7cfbdd02..3e1be13ac 100644 --- a/slsDetectorSoftware/src/Caller.h +++ b/slsDetectorSoftware/src/Caller.h @@ -236,6 +236,7 @@ class Caller { std::string rx_clearroi(int action); std::string rx_dbitlist(int action); std::string rx_dbitoffset(int action); + std::string rx_dbitreorder(int action); std::string rx_discardpolicy(int action); std::string rx_fifodepth(int action); std::string rx_frameindex(int action); @@ -582,6 +583,7 @@ class Caller { {"rx_clearroi", &Caller::rx_clearroi}, {"rx_dbitlist", &Caller::rx_dbitlist}, {"rx_dbitoffset", &Caller::rx_dbitoffset}, + {"rx_dbitreorder", &Caller::rx_dbitreorder}, {"rx_discardpolicy", &Caller::rx_discardpolicy}, {"rx_fifodepth", &Caller::rx_fifodepth}, {"rx_frameindex", &Caller::rx_frameindex}, diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 2e85c7c2c..f84e5fbb3 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -2277,6 +2277,14 @@ void Detector::setRxDbitOffset(int value, Positions pos) { pimpl->Parallel(&Module::setReceiverDbitOffset, pos, value); } +Result Detector::getRxDbitReorder(Positions pos) const { + return pimpl->Parallel(&Module::getReceiverDbitReorder, pos); +} + +void Detector::setRxDbitReorder(bool reorder, Positions pos) { + pimpl->Parallel(&Module::setReceiverDbitReorder, pos, reorder); +} + void Detector::setDigitalIODelay(uint64_t pinMask, int delay, Positions pos) { pimpl->Parallel(&Module::setDigitalIODelay, pos, pinMask, delay); } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 5b535b92a..d1356c30f 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -2509,6 +2509,15 @@ void Module::setReceiverDbitOffset(int value) { sendToReceiver(F_SET_RECEIVER_DBIT_OFFSET, value, nullptr); } +bool Module::getReceiverDbitReorder() const { + return sendToReceiver(F_GET_RECEIVER_DBIT_REORDER); +} + +void Module::setReceiverDbitReorder(bool reorder) { + sendToReceiver(F_SET_RECEIVER_DBIT_REORDER, static_cast(reorder), + nullptr); +} + void Module::setDigitalIODelay(uint64_t pinMask, int delay) { uint64_t args[]{pinMask, static_cast(delay)}; sendToDetector(F_DIGITAL_IO_DELAY, args, nullptr); diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 18fbaa296..86c9e3d5f 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -510,6 +510,8 @@ class Module : public virtual slsDetectorDefs { void setReceiverDbitList(std::vector list); int getReceiverDbitOffset() const; void setReceiverDbitOffset(int value); + bool getReceiverDbitReorder() const; + void setReceiverDbitReorder(bool value); void setDigitalIODelay(uint64_t pinMask, int delay); bool getLEDEnable() const; void setLEDEnable(bool enable); diff --git a/slsDetectorSoftware/src/inferAction.cpp b/slsDetectorSoftware/src/inferAction.cpp index 56ff942cd..68c8638f1 100644 --- a/slsDetectorSoftware/src/inferAction.cpp +++ b/slsDetectorSoftware/src/inferAction.cpp @@ -2568,6 +2568,22 @@ int InferAction::rx_dbitoffset() { } } +int InferAction::rx_dbitreorder() { + + if (args.size() == 0) { + return slsDetectorDefs::GET_ACTION; + } + + if (args.size() == 1) { + return slsDetectorDefs::PUT_ACTION; + } + + else { + + throw RuntimeError("Could not infer action: Wrong number of arguments"); + } +} + int InferAction::rx_discardpolicy() { if (args.size() == 0) { diff --git a/slsDetectorSoftware/src/inferAction.h b/slsDetectorSoftware/src/inferAction.h index 35d1109ef..ffc6944d7 100644 --- a/slsDetectorSoftware/src/inferAction.h +++ b/slsDetectorSoftware/src/inferAction.h @@ -193,6 +193,7 @@ class InferAction { int rx_clearroi(); int rx_dbitlist(); int rx_dbitoffset(); + int rx_dbitreorder(); int rx_discardpolicy(); int rx_fifodepth(); int rx_frameindex(); @@ -527,6 +528,7 @@ class InferAction { {"rx_clearroi", &InferAction::rx_clearroi}, {"rx_dbitlist", &InferAction::rx_dbitlist}, {"rx_dbitoffset", &InferAction::rx_dbitoffset}, + {"rx_dbitreorder", &InferAction::rx_dbitreorder}, {"rx_discardpolicy", &InferAction::rx_discardpolicy}, {"rx_fifodepth", &InferAction::rx_fifodepth}, {"rx_frameindex", &InferAction::rx_frameindex}, diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index a75a87d2f..0180af8fb 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -218,6 +218,8 @@ int ClientInterface::functionTable(){ flist[F_RECEIVER_SET_TRANSCEIVER_MASK] = &ClientInterface::set_transceiver_mask; flist[F_RECEIVER_SET_ROW] = &ClientInterface::set_row; flist[F_RECEIVER_SET_COLUMN] = &ClientInterface::set_column; + flist[F_GET_RECEIVER_DBIT_REORDER] = &ClientInterface::get_dbit_reorder; + flist[F_SET_RECEIVER_DBIT_REORDER] = &ClientInterface::set_dbit_reorder; for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { @@ -1789,4 +1791,25 @@ int ClientInterface::set_column(Interface &socket) { return socket.Send(OK); } +int ClientInterface::get_dbit_reorder(Interface &socket) { + if (detType != CHIPTESTBOARD && detType != XILINX_CHIPTESTBOARD) + functionNotImplemented(); + int retval = impl()->getDbitReorder(); + LOG(logDEBUG1) << "Dbit reorder retval: " << retval; + return socket.sendResult(retval); +} + +int ClientInterface::set_dbit_reorder(Interface &socket) { + auto arg = socket.Receive(); + if (detType != CHIPTESTBOARD && detType != XILINX_CHIPTESTBOARD) + functionNotImplemented(); + if (arg < 0) { + throw RuntimeError("Invalid dbit reorder: " + std::to_string(arg)); + } + verifyIdle(socket); + LOG(logDEBUG1) << "Setting Dbit offset: " << arg; + impl()->setDbitReorder(arg); + return socket.Send(OK); +} + } // namespace sls diff --git a/slsReceiverSoftware/src/ClientInterface.h b/slsReceiverSoftware/src/ClientInterface.h index a6749e33f..665e0f396 100644 --- a/slsReceiverSoftware/src/ClientInterface.h +++ b/slsReceiverSoftware/src/ClientInterface.h @@ -164,6 +164,8 @@ class ClientInterface : private virtual slsDetectorDefs { int set_transceiver_mask(ServerInterface &socket); int set_row(ServerInterface &socket); int set_column(ServerInterface &socket); + int get_dbit_reorder(ServerInterface &socket); + int set_dbit_reorder(ServerInterface &socket); Implementation *impl() { if (receiver != nullptr) { diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index e80ab531e..35b17f538 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -75,10 +75,10 @@ void DataProcessor::SetCtbDbitList(std::vector value) { ctbDbitList = value; } -void DataProcessor::SetReorder(const bool value) { reorder = value; } - void DataProcessor::SetCtbDbitOffset(int value) { ctbDbitOffset = value; } +void DataProcessor::SetCtbDbitReorder(bool value) { ctbDbitReorder = value; } + void DataProcessor::SetQuadEnable(bool value) { quadEnable = value; } void DataProcessor::SetFlipRows(bool fd) { @@ -556,7 +556,7 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { 0; // number of bytes for selected digital data given by dtbDbitList // store each selected bit from all samples consecutively - if (reorder) { + if (ctbDbitReorder) { int numBitsPerDbit = numDigitalSamples; // num bits per selected digital // Bit for all samples if ((numBitsPerDbit % 8) != 0) @@ -575,7 +575,7 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { std::vector result(totalNumBytes, 0); uint8_t *dest = &result[0]; - if (reorder) { + if (ctbDbitReorder) { // loop through digital bit enable vector int bitoffset = 0; for (auto bi : ctbDbitList) { diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index d09a9ca3f..30873a1f9 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -46,8 +46,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { void SetStreamingStartFnum(uint32_t value); void SetFramePadding(bool enable); void SetCtbDbitList(std::vector value); - void SetReorder(const bool reorder); void SetCtbDbitOffset(int value); + void SetCtbDbitReorder(bool value); void SetQuadEnable(bool value); void SetFlipRows(bool fd); void SetNumberofTotalFrames(uint64_t value); @@ -168,8 +168,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { struct timespec timerbegin {}; bool framePadding; std::vector ctbDbitList; - bool reorder{false}; // true if data should be reordered TODO: add as mode - int ctbDbitOffset; + int ctbDbitOffset{0}; + bool ctbDbitReorder{false}; std::atomic startedFlag{false}; std::atomic firstIndex{0}; bool quadEnable{false}; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index 8104e8c7a..ea636258c 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -202,6 +202,7 @@ void Implementation::SetupDataProcessor(int i) { dataProcessor[i]->SetFramePadding(framePadding); dataProcessor[i]->SetCtbDbitList(ctbDbitList); dataProcessor[i]->SetCtbDbitOffset(ctbDbitOffset); + dataProcessor[i]->SetCtbDbitReorder(ctbDbitReorder); dataProcessor[i]->SetQuadEnable(quadEnable); dataProcessor[i]->SetFlipRows(flipRows); dataProcessor[i]->SetNumberofTotalFrames(numberOfTotalFrames); @@ -1766,6 +1767,15 @@ void Implementation::setDbitOffset(const int s) { LOG(logINFO) << "Dbit offset: " << ctbDbitOffset; } +bool Implementation::getDbitReorder() const { return ctbDbitReorder; } + +void Implementation::setDbitReorder(const bool reorder) { + ctbDbitReorder = reorder; + for (const auto &it : dataProcessor) + it->SetCtbDbitReorder(ctbDbitReorder); + LOG(logINFO) << "Dbit reorder: " << ctbDbitReorder; +} + uint32_t Implementation::getTransceiverEnableMask() const { return generalData->transceiverMask; } diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 70ceb4a54..79baa670b 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -252,6 +252,10 @@ class Implementation : private virtual slsDetectorDefs { int getDbitOffset() const; /* [Ctb] */ void setDbitOffset(const int s); + bool getDbitReorder() const; + /* [Ctb] */ + void setDbitReorder(const bool reorder); + uint32_t getTransceiverEnableMask() const; /* [Ctb] */ void setTransceiverEnableMask(const uint32_t mask); @@ -368,6 +372,7 @@ class Implementation : private virtual slsDetectorDefs { std::vector rateCorrections; std::vector ctbDbitList; int ctbDbitOffset{0}; + bool ctbDbitReorder{true}; // callbacks void (*startAcquisitionCallBack)(const startCallbackHeader, diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index 8a7ef3508..ec1c6d2f1 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -410,6 +410,8 @@ enum detFuncs { F_RECEIVER_SET_TRANSCEIVER_MASK, F_RECEIVER_SET_ROW, F_RECEIVER_SET_COLUMN, + F_GET_RECEIVER_DBIT_REORDER, + F_SET_RECEIVER_DBIT_REORDER, NUM_REC_FUNCTIONS }; @@ -816,7 +818,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_RECEIVER_SET_TRANSCEIVER_MASK: return "F_RECEIVER_SET_TRANSCEIVER_MASK"; case F_RECEIVER_SET_ROW: return "F_RECEIVER_SET_ROW"; case F_RECEIVER_SET_COLUMN: return "F_RECEIVER_SET_COLUMN"; - + case F_GET_RECEIVER_DBIT_REORDER: return "F_GET_RECEIVER_DBIT_REORDER"; + case F_SET_RECEIVER_DBIT_REORDER: return "F_SET_RECEIVER_DBIT_REORDER"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; default: return "Unknown Function"; From ff101e19cd98771b944a146992ac86f319d51f2f Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 12 Mar 2025 17:17:40 +0100 Subject: [PATCH 07/38] added pybind for it --- python/src/detector.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/src/detector.cpp b/python/src/detector.cpp index 2d2c224b7..5393cbf6e 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -1664,6 +1664,14 @@ void init_det(py::module &m) { (void (Detector::*)(int, sls::Positions)) & Detector::setRxDbitOffset, py::arg(), py::arg() = Positions{}); + CppDetectorApi.def("getRxDbitReorder", + (Result(Detector::*)(sls::Positions) const) & + Detector::getRxDbitReorder, + py::arg() = Positions{}); + CppDetectorApi.def("setRxDbitReorder", + (void (Detector::*)(bool, sls::Positions)) & + Detector::setRxDbitReorder, + py::arg(), py::arg() = Positions{}); CppDetectorApi.def("setDigitalIODelay", (void (Detector::*)(uint64_t, int, sls::Positions)) & Detector::setDigitalIODelay, From e1c9754cd2dca111e080bc776c550a0f697c8936 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 12 Mar 2025 17:21:05 +0100 Subject: [PATCH 08/38] Added test for rx_dbitreorder command --- .../tests/Caller/test-Caller-rx.cpp | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp index 38fe14e86..d04890b0a 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp @@ -956,6 +956,42 @@ TEST_CASE("rx_dbitoffset", "[.cmdcall][.rx]") { } } +TEST_CASE("rx_dbitreorder", "[.cmdcall][.rx]") { + Detector det; + Caller caller(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::CHIPTESTBOARD || + det_type == defs::XILINX_CHIPTESTBOARD) { + auto prev_val = det.getRxDbitReorder(); + { + std::ostringstream oss; + caller.call("rx_dbitreorder", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_dbitreorder 1\n"); + } + { + std::ostringstream oss; + caller.call("rx_dbitreorder", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_dbitreorder 0\n"); + } + { + std::ostringstream oss; + caller.call("rx_dbitreorder", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_dbitreorder 1\n"); + } + { + std::ostringstream oss; + caller.call("rx_dbitreorder", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_dbitreorder 1\n"); + } + REQUIRE_THROWS(caller.call("rx_dbitreorder", {"15"}, -1, PUT)); + for (int i = 0; i != det.size(); ++i) { + det.setRxDbitReorder(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(caller.call("rx_dbitoffset", {}, -1, GET)); + } +} + TEST_CASE("rx_jsonaddheader", "[.cmdcall][.rx]") { Detector det; Caller caller(&det); From bd66228b30f982d44bdc26c33ba023e0ffb58fcb Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 13 Mar 2025 11:14:01 +0100 Subject: [PATCH 09/38] minor to check workflow --- slsReceiverSoftware/src/DataProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 35b17f538..a6dbd8cf7 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -3,7 +3,7 @@ /************************************************ * @file DataProcessor.cpp * @short creates data processor thread that - * pulls pointers to memory addresses from fifos + * pulls pointers to memory addresses from fifos * and processes data stored in them & writes them to file ***********************************************/ From 6e5b058fc1a51714c11e93cdf04df28fe9059882 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 13 Mar 2025 13:17:54 +0100 Subject: [PATCH 10/38] merge fix --- slsReceiverSoftware/src/DataProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 712956c0d..657bbb98f 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -361,7 +361,7 @@ void DataProcessor::ProcessAnImage(sls_receiver_header &header, size_t &size, // rearrange ctb digital bits if (!ctbDbitList.empty()) { ArrangeDbitData(size, data); - } else if (reorder) { + } else if (ctbDbitReorder) { Reorder(size, data); } else if (ctbDbitOffset > 0) { RemoveTrailingBits(size, data); From 0a5b5aac4bb9dff039808ffba998ead9a11c7bd6 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Fri, 14 Mar 2025 14:04:55 +0100 Subject: [PATCH 11/38] added unit tests for dataprocessor rearranging functions --- slsReceiverSoftware/src/DataProcessor.cpp | 16 +- slsReceiverSoftware/src/DataProcessor.h | 4 +- .../tests/test-ArrangeDataBasedOnBitList.cpp | 415 ++++++++++++++---- 3 files changed, 347 insertions(+), 88 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index b0a3550ae..222917d4e 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -552,8 +552,7 @@ void DataProcessor::RemoveTrailingBits(size_t &size, char *data) { } // update size and copy data - memmove(data + nAnalogDataBytes, - data + nAnalogDataBytes + ctbDigitalDataBytes, + memmove(data + nAnalogDataBytes, data + nAnalogDataBytes + ctbDbitOffset, ctbDigitalDataBytes + nTransceiverDataBytes); size = nAnalogDataBytes + ctbDigitalDataBytes + nTransceiverDataBytes; @@ -575,6 +574,7 @@ void DataProcessor::Reorder(size_t &size, char *data) { } auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); + // TODO: leads to unaligned data const size_t numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); @@ -590,13 +590,6 @@ void DataProcessor::Reorder(size_t &size, char *data) { numBytesPerBit * 64; // number of bytes for digital data after reordering - LOG(logDEBUG1) << "totalNumBytes: " << totalNumBytes - << " nAnalogDataBytes:" << nAnalogDataBytes - << " nDigitalDataBytes: " << nDigitalDataBytes - << " ctbDbitOffset:" << ctbDbitOffset - << " nTransceiverDataBytes:" << nTransceiverDataBytes - << " size:" << size << " numsamples:" << numDigitalSamples; - std::vector result(totalNumBytes, 0); uint8_t *dest = &result[0]; @@ -666,8 +659,9 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { // store each selected bit from all samples consecutively if (reorder) { - int numBitsPerDbit = numDigitalSamples; // num bits per selected digital - // Bit for all samples + size_t numBitsPerDbit = + numDigitalSamples; // num bits per selected digital + // Bit for all samples if ((numBitsPerDbit % 8) != 0) numBitsPerDbit += (8 - (numDigitalSamples % 8)); totalNumBytes = (numBitsPerDbit / 8) * ctbDbitList.size(); diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 6febaedbf..3e0aa0b9d 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -177,11 +177,11 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { uint32_t streamingTimerInMs; uint32_t streamingStartFnum; uint32_t currentFreqCount{0}; - struct timespec timerbegin{}; + struct timespec timerbegin {}; bool framePadding; std::vector ctbDbitList; bool reorder{false}; // true if data should be reordered TODO: add as mode - int ctbDbitOffset; + int ctbDbitOffset{0}; std::atomic startedFlag{false}; std::atomic firstIndex{0}; bool quadEnable{false}; diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index 3012ddf64..ad5a8fbb3 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -2,7 +2,7 @@ // Copyright (C) 2025 Contributors to the SLS Detector Package /************************************************ * @file test-ArrangeDataBasedOnBitList.cpp - * @short test case for DataProcessor member function ArrangeDbitData, + * @short test case for DataProcessor rearrange functions, ***********************************************/ #include "DataProcessor.h" @@ -36,7 +36,7 @@ class GeneralDataTest : public GeneralData { int nTransceiverBytes; }; -// oke maybe just make it static +// dummy DataProcessor class for testing class DataProcessorTest : public DataProcessor { public: DataProcessorTest() : DataProcessor(0){}; @@ -44,91 +44,356 @@ class DataProcessorTest : public DataProcessor { void ArrangeDbitData(size_t &size, char *data) { DataProcessor::ArrangeDbitData(size, data); } -}; -TEST_CASE("Arrange with reorder false") { - DataProcessorTest dataprocessor; - - std::vector bitlist{1, 4, 5}; - dataprocessor.SetCtbDbitList(bitlist); - - size_t num_digital_samples = 5; // size_t or uint8_t ? - size_t num_digital_bytes = num_digital_samples * 8; - size_t num_analog_bytes = 1; - size_t num_transceiver_bytes = 2; - size_t random_offset_bytes = 0; - - size_t size = num_analog_bytes + num_digital_bytes + num_transceiver_bytes + - random_offset_bytes; - - char *data = new char[size]; - - char dummy_value = static_cast(125); - memset(data, dummy_value, num_analog_bytes); - memset(data + num_analog_bytes, 0xFF, - num_digital_bytes); // all digital bits are one - memset(data + num_digital_bytes + num_analog_bytes, dummy_value, - num_transceiver_bytes); - - GeneralDataTest *generaldata = new GeneralDataTest; - generaldata->SetNumberOfAnalogDatabytes(num_analog_bytes); - generaldata->SetNumberOfDigitalDatabytes(num_digital_bytes); - generaldata->SetNumberOfTransceiverDatabytes(num_transceiver_bytes); - - dataprocessor.SetGeneralData(generaldata); - - size_t new_num_digital_bytes = - (bitlist.size() / 8 + static_cast(bitlist.size() % 8 != 0)) * - num_digital_samples; - - size_t new_size = - num_analog_bytes + num_transceiver_bytes + new_num_digital_bytes; - - char *new_data = new char[new_size]; - - memset(new_data, dummy_value, num_analog_bytes); - - // TODO: Make test more explicit and less generic - size_t num_bytes_for_bitlist = - bitlist.size() / 8 + static_cast(bitlist.size() % 8 != 0); - - // 125 7 7 7 7 7 125 125 - for (size_t sample = 0; sample < num_digital_samples; ++sample) { - if (bitlist.size() / 8 != 0) { - memset(new_data + sample * num_bytes_for_bitlist + num_analog_bytes, - 0xFF, - bitlist.size() / 8); // set to 1 - } else if (bitlist.size() % 8 != 0) { - memset(new_data + sample * num_bytes_for_bitlist + - bitlist.size() / 8 + num_analog_bytes, - static_cast(pow(2, (bitlist.size() % 8)) - 1), - 1); // convert binary number to decimal - } + void Reorder(size_t &size, char *data) { + DataProcessor::Reorder(size, data); } - memset(new_data + new_num_digital_bytes + num_analog_bytes, dummy_value, - num_transceiver_bytes); + void RemoveTrailingBits(size_t &size, char *data) { + DataProcessor::RemoveTrailingBits(size, data); + } +}; - dataprocessor.ArrangeDbitData(size, data); +/** + * test fixture for Testing, + * num_analog_bytes = 1 byte has a value of 125 + * num_transceiver_bytes = 2 both bytes have a value of 125 + * num_digital_bytes is variable and is defined by number of samples + * default num sample is 5 + * all bytes in digital data take a value of 255 + */ +class DataProcessorTestFixture { + public: + DataProcessorTestFixture() { + // setup Test Fixture + dataprocessor = new DataProcessorTest; + generaldata = new GeneralDataTest; - CHECK(size == new_size); + // set_num_samples(num_samples); - CHECK(memcmp(data, new_data, size) == 0); + generaldata->SetNumberOfAnalogDatabytes(num_analog_bytes); + generaldata->SetNumberOfTransceiverDatabytes(num_transceiver_bytes); + generaldata->SetNumberOfDigitalDatabytes(num_digital_bytes + + num_random_offset_bytes); - // Free allocated memory - delete[] data; - delete[] new_data; - delete generaldata; + dataprocessor->SetGeneralData(generaldata); + } + + ~DataProcessorTestFixture() { + delete[] data; + delete dataprocessor; + delete generaldata; + } + + size_t get_size() const { + return num_analog_bytes + num_digital_bytes + num_transceiver_bytes + + num_random_offset_bytes; + } + + void set_num_samples(const size_t value) { + num_samples = value; + num_digital_bytes = num_samples * 8; // 64 (8 bytes) per sample + + generaldata->SetNumberOfDigitalDatabytes(num_digital_bytes + + num_random_offset_bytes); + } + + void set_random_offset_bytes(const size_t value) { + num_random_offset_bytes = value; + generaldata->SetNumberOfDigitalDatabytes(num_digital_bytes + + num_random_offset_bytes); + } + + void set_data() { + delete[] data; + data = new char[get_size()]; + + // set testing data + memset(data, dummy_value, num_analog_bytes); // set to dummy value + memset(data + num_analog_bytes, 0, + num_random_offset_bytes); // set to zero + memset(data + num_analog_bytes + num_random_offset_bytes, 0xFF, + num_digital_bytes); // all digital bits are one + memset(data + num_digital_bytes + num_analog_bytes + + num_random_offset_bytes, + dummy_value, + num_transceiver_bytes); // set to dummy value + } + + DataProcessorTest *dataprocessor; + GeneralDataTest *generaldata; + const size_t num_analog_bytes = 1; + const size_t num_transceiver_bytes = 2; + const char dummy_value = static_cast(125); + size_t num_digital_bytes = 40; // num_samples * 8 = 5 * 8 = 40 + size_t num_random_offset_bytes = 0; + size_t num_samples = 5; + char *data = nullptr; +}; + +TEST_CASE_METHOD(DataProcessorTestFixture, "Remove Trailing Bits", + "[.dataprocessor][.bitoffset]") { + + const size_t num_random_offset_bytes = 3; + set_random_offset_bytes(num_random_offset_bytes); + set_data(); + + dataprocessor->SetCtbDbitOffset(num_random_offset_bytes); + + size_t expected_size = get_size() - num_random_offset_bytes; + + char *expected_data = new char[expected_size]; + memset(expected_data, dummy_value, num_analog_bytes); // set to 125 + memset(expected_data + num_analog_bytes, 0xFF, + num_digital_bytes); // set to 1 + memset(expected_data + num_digital_bytes + num_analog_bytes, dummy_value, + num_transceiver_bytes); // set to 125 + + size_t size = get_size(); + dataprocessor->RemoveTrailingBits(size, data); + + CHECK(size == expected_size); + + CHECK(memcmp(data, expected_data, expected_size) == 0); + + delete[] expected_data; } -// TEST_CASE("Arrange with reorder on") { +// parametric test tested with num_samples = 5, num_samples = 10, num_samples = +// 8 +TEST_CASE_METHOD(DataProcessorTestFixture, "Reorder all", + "[.dataprocessor][.reorder]") { + // parameters: num_samples, expected_num_digital_bytes, + // expected_digital_part + auto parameters = GENERATE( + std::make_tuple(5, 64, std::vector{0b00011111}), + std::make_tuple(10, 2 * 64, std::vector{0xFF, 0b00000011}), + std::make_tuple(8, 64, std::vector{0xFF})); -//} + size_t num_samples, expected_num_digital_bytes; + std::vector expected_digital_part; + std::tie(num_samples, expected_num_digital_bytes, expected_digital_part) = + parameters; -// test case reorder on and bitoffset set + // set number of samples for test fixture -> create data + set_num_samples(num_samples); + set_data(); -// test with different samples + dataprocessor->SetReorder(true); // set reorder to true -// test with sample number not divisable and ctbitlist not divisable + const size_t expected_size = + num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; + + // create expected data + char *expected_data = new char[expected_size]; + + memset(expected_data, dummy_value, num_analog_bytes); // set to 125 + for (size_t bit = 0; bit < 64; ++bit) { + memcpy(expected_data + num_analog_bytes + + expected_digital_part.size() * bit, + expected_digital_part.data(), expected_digital_part.size()); + } + memset(expected_data + expected_num_digital_bytes + num_analog_bytes, + dummy_value, + num_transceiver_bytes); // set to 125 + + size_t size = get_size(); + dataprocessor->Reorder(size, data); // call reorder + + CHECK(size == expected_size); + CHECK(memcmp(data, expected_data, expected_size) == 0); + + delete[] expected_data; +} + +TEST_CASE_METHOD(DataProcessorTestFixture, + "Reorder all and remove trailing bits", + "[.dataprocessor][.reorder]") { + + // set number of samples for test fixture -> create data + const size_t num_random_offset_bytes = 3; + set_random_offset_bytes(num_random_offset_bytes); + set_data(); + + dataprocessor->SetCtbDbitOffset(num_random_offset_bytes); + dataprocessor->SetReorder(true); // set reorder to true + + const size_t expected_num_digital_bytes = 64; + std::vector expected_digital_part{0b00011111}; + + const size_t expected_size = + num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; + + // create expected data + char *expected_data = new char[expected_size]; + + memset(expected_data, dummy_value, num_analog_bytes); // set to 125 + for (size_t bit = 0; bit < 64; ++bit) { + memcpy(expected_data + num_analog_bytes + + expected_digital_part.size() * bit, + expected_digital_part.data(), expected_digital_part.size()); + } + memset(expected_data + expected_num_digital_bytes + num_analog_bytes, + dummy_value, + num_transceiver_bytes); // set to 125 + + size_t size = get_size(); + dataprocessor->Reorder(size, data); // call reorder + + CHECK(size == expected_size); + CHECK(memcmp(data, expected_data, expected_size) == 0); + + delete[] expected_data; +} + +TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder false", + "[.dataprocessor][.retrievebitlist]") { + // parameters: num_samples, bitlist, expected_num_digital_bytes, + // expected_digital_part + auto parameters = GENERATE( + std::make_tuple(5, std::vector{1, 4, 5}, 5, + std::vector{0b00000111}), + std::make_tuple(5, std::vector{1, 5, 3, 7, 8, 50, 42, 60, 39}, 10, + std::vector{0xFF, 0b00000001}), + std::make_tuple(5, std::vector{1, 5, 3, 7, 8, 50, 42, 60}, 5, + std::vector{0xFF})); + + size_t num_samples, expected_num_digital_bytes; + std::vector expected_digital_part; + std::vector bitlist; + std::tie(num_samples, bitlist, expected_num_digital_bytes, + expected_digital_part) = parameters; + + dataprocessor->SetCtbDbitList(bitlist); + + dataprocessor->SetReorder(false); + + set_num_samples(num_samples); + set_data(); + + size_t expected_size = + num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; + + // create expected data + char *expected_data = new char[expected_size]; + + memset(expected_data, dummy_value, num_analog_bytes); + + for (size_t sample = 0; sample < num_samples; ++sample) { + memcpy(expected_data + num_analog_bytes + + expected_digital_part.size() * sample, + expected_digital_part.data(), expected_digital_part.size()); + } + + memset(expected_data + expected_num_digital_bytes + num_analog_bytes, + dummy_value, num_transceiver_bytes); + + size_t size = get_size(); + dataprocessor->ArrangeDbitData(size, data); + + CHECK(size == expected_size); + + CHECK(memcmp(data, expected_data, expected_size) == 0); + + delete[] expected_data; +} + +TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true", + "[.dataprocessor][.retrievebitlist]") { + // parameters: num_samples, bitlist, expected_num_digital_bytes, + // expected_digital_part + auto parameters = GENERATE( + std::make_tuple(5, std::vector{1, 4, 5}, 3, + std::vector{0b00011111}), + std::make_tuple(10, std::vector{1, 4, 5}, 6, + std::vector{0xFF, 0b00000011}), + std::make_tuple(8, std::vector{1, 5, 3, 7, 8, 50, 42, 60, 39}, 9, + std::vector{0xFF})); + + size_t num_samples, expected_num_digital_bytes; + std::vector expected_digital_part; + std::vector bitlist; + std::tie(num_samples, bitlist, expected_num_digital_bytes, + expected_digital_part) = parameters; + + dataprocessor->SetCtbDbitList(bitlist); + + dataprocessor->SetReorder(true); + + set_num_samples(num_samples); + set_data(); + + size_t expected_size = + num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; + + // create expected data + char *expected_data = new char[expected_size]; + + memset(expected_data, dummy_value, num_analog_bytes); + + for (size_t sample = 0; sample < bitlist.size(); ++sample) { + memcpy(expected_data + num_analog_bytes + + expected_digital_part.size() * sample, + expected_digital_part.data(), expected_digital_part.size()); + } + + memset(expected_data + expected_num_digital_bytes + num_analog_bytes, + dummy_value, num_transceiver_bytes); + + size_t size = get_size(); + dataprocessor->ArrangeDbitData(size, data); + + CHECK(size == expected_size); + + CHECK(memcmp(data, expected_data, expected_size) == 0); + + delete[] expected_data; +} + +TEST_CASE_METHOD(DataProcessorTestFixture, + "Arrange bitlist and remove trailing bits", + "[.dataprocessor][.retrievebitlist]") { + + size_t num_random_offset_bytes = 3; + std::vector bitlist{1, 4, 5}; + + set_random_offset_bytes(num_random_offset_bytes); + set_data(); + + dataprocessor->SetCtbDbitList(bitlist); + + dataprocessor->SetReorder(false); + + dataprocessor->SetCtbDbitOffset(num_random_offset_bytes); + + std::vector expected_digital_part{0b00000111}; + const size_t expected_num_digital_bytes = 5; + + size_t expected_size = + num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; + + // create expected data + char *expected_data = new char[expected_size]; + + memset(expected_data, dummy_value, num_analog_bytes); + + for (size_t sample = 0; sample < num_samples; ++sample) { + memcpy(expected_data + num_analog_bytes + + expected_digital_part.size() * sample, + expected_digital_part.data(), expected_digital_part.size()); + } + + memset(expected_data + expected_num_digital_bytes + num_analog_bytes, + dummy_value, num_transceiver_bytes); + + size_t size = get_size(); + dataprocessor->ArrangeDbitData(size, data); + + CHECK(size == expected_size); + + CHECK(memcmp(data, expected_data, expected_size) == 0); + + delete[] expected_data; +} } // namespace sls From 13b2cada66491db82d2e3871ee314d26de207399 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Mon, 17 Mar 2025 15:20:40 +0100 Subject: [PATCH 12/38] ctb reorder default being true in dataprocessor --- slsReceiverSoftware/src/DataProcessor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 594cffaa8..fd5b9dc1f 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -181,7 +181,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { bool framePadding; std::vector ctbDbitList; int ctbDbitOffset{0}; - bool ctbDbitReorder{false}; + bool ctbDbitReorder{true}; std::atomic startedFlag{false}; std::atomic firstIndex{0}; bool quadEnable{false}; From 842b376801998d114b142c6e7a39202c84a3f187 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Mon, 17 Mar 2025 15:23:02 +0100 Subject: [PATCH 13/38] fixed rx_dbitreorder cmd line tests --- slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp index d04890b0a..508abc59d 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp @@ -963,11 +963,6 @@ TEST_CASE("rx_dbitreorder", "[.cmdcall][.rx]") { if (det_type == defs::CHIPTESTBOARD || det_type == defs::XILINX_CHIPTESTBOARD) { auto prev_val = det.getRxDbitReorder(); - { - std::ostringstream oss; - caller.call("rx_dbitreorder", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_dbitreorder 1\n"); - } { std::ostringstream oss; caller.call("rx_dbitreorder", {"0"}, -1, PUT, oss); @@ -988,7 +983,7 @@ TEST_CASE("rx_dbitreorder", "[.cmdcall][.rx]") { det.setRxDbitReorder(prev_val[i], {i}); } } else { - REQUIRE_THROWS(caller.call("rx_dbitoffset", {}, -1, GET)); + REQUIRE_THROWS(caller.call("rx_dbitreorder", {}, -1, GET)); } } From e0a48e1e7504b73f598c7b9451695c6c5d911b6a Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Mon, 17 Mar 2025 15:39:31 +0100 Subject: [PATCH 14/38] implemented proper alignment in reorder function before casting to uint64_t ptr --- slsReceiverSoftware/src/DataProcessor.cpp | 39 ++++++++++++++----- .../tests/test-ArrangeDataBasedOnBitList.cpp | 4 +- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 222917d4e..724c5758d 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -573,18 +573,35 @@ void DataProcessor::Reorder(size_t &size, char *data) { return; } - auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); - // TODO: leads to unaligned data + // make sure data is aligned to 8 bytes before casting to uint64_t + char *ptr = data + nAnalogDataBytes + ctbDbitOffset; + uint64_t *source = nullptr; + using AlignedBuffer = + std::aligned_storage::type; + std::unique_ptr tempbuffer; + + if (reinterpret_cast(ptr) % alignof(uint64_t) == 0) { + // If aligned, directly cast to uint64_t pointer + source = reinterpret_cast(ptr); + } else { + // Allocate a temporary buffer with proper alignment + tempbuffer = std::make_unique(ctbDigitalDataBytes / + sizeof(uint64_t)); + + std::memcpy(tempbuffer.get(), ptr, ctbDigitalDataBytes); + source = reinterpret_cast(tempbuffer.get()); + } + + // auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); + // TODO: leads to unaligned data const size_t numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); size_t numBytesPerBit = - 0; // number of bytes per bit in digital data after reordering - - if ((numDigitalSamples % 8) == 0) - numBytesPerBit = numDigitalSamples / 8; - else - numBytesPerBit = numDigitalSamples / 8 + 1; + (numDigitalSamples % 8 == 0) + ? numDigitalSamples / 8 + : numDigitalSamples / 8 + + 1; // number of bytes per bit in digital data after reordering size_t totalNumBytes = numBytesPerBit * @@ -595,10 +612,13 @@ void DataProcessor::Reorder(size_t &size, char *data) { int bitoffset = 0; // reorder + int count = 0; + int written = 0; for (size_t bi = 0; bi < 64; ++bi) { if (bitoffset != 0) { bitoffset = 0; + ++count; ++dest; } @@ -606,11 +626,12 @@ void DataProcessor::Reorder(size_t &size, char *data) { uint8_t bit = (*ptr >> bi) & 1; *dest |= bit << bitoffset; // most significant bits will be padded ++bitoffset; - if (bitoffset == 8) { bitoffset = 0; + ++count; ++dest; } + ++written; } } diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index ad5a8fbb3..1235daae1 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -39,8 +39,8 @@ class GeneralDataTest : public GeneralData { // dummy DataProcessor class for testing class DataProcessorTest : public DataProcessor { public: - DataProcessorTest() : DataProcessor(0){}; - ~DataProcessorTest(){}; + DataProcessorTest() : DataProcessor(0) {}; + ~DataProcessorTest() {}; void ArrangeDbitData(size_t &size, char *data) { DataProcessor::ArrangeDbitData(size, data); } From f4626c2c815d8efb337224d97b59b335651aafe4 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Mon, 17 Mar 2025 15:45:59 +0100 Subject: [PATCH 15/38] fix tests from merge --- .../tests/test-ArrangeDataBasedOnBitList.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index ad5a8fbb3..e556066bc 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -39,8 +39,8 @@ class GeneralDataTest : public GeneralData { // dummy DataProcessor class for testing class DataProcessorTest : public DataProcessor { public: - DataProcessorTest() : DataProcessor(0){}; - ~DataProcessorTest(){}; + DataProcessorTest() : DataProcessor(0) {}; + ~DataProcessorTest() {}; void ArrangeDbitData(size_t &size, char *data) { DataProcessor::ArrangeDbitData(size, data); } @@ -179,7 +179,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Reorder all", set_num_samples(num_samples); set_data(); - dataprocessor->SetReorder(true); // set reorder to true + dataprocessor->SetCtbDbitReorder(true); // set reorder to true const size_t expected_size = num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; @@ -216,7 +216,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, set_data(); dataprocessor->SetCtbDbitOffset(num_random_offset_bytes); - dataprocessor->SetReorder(true); // set reorder to true + dataprocessor->SetCtbDbitReorder(true); // set reorder to true const size_t expected_num_digital_bytes = 64; std::vector expected_digital_part{0b00011111}; @@ -266,7 +266,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder false", dataprocessor->SetCtbDbitList(bitlist); - dataprocessor->SetReorder(false); + dataprocessor->SetCtbDbitReorder(false); set_num_samples(num_samples); set_data(); @@ -318,7 +318,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true", dataprocessor->SetCtbDbitList(bitlist); - dataprocessor->SetReorder(true); + dataprocessor->SetCtbDbitReorder(true); set_num_samples(num_samples); set_data(); @@ -362,7 +362,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, dataprocessor->SetCtbDbitList(bitlist); - dataprocessor->SetReorder(false); + dataprocessor->SetCtbDbitReorder(false); dataprocessor->SetCtbDbitOffset(num_random_offset_bytes); From f056f9d31b304dda9dff2d723c95cc5d512a53f3 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Tue, 18 Mar 2025 21:42:34 +0100 Subject: [PATCH 16/38] reserved enough size in the fifo buffer to reorder all added proper 4 byte alignment --- slsReceiverSoftware/src/DataProcessor.cpp | 89 ++++++++++++------- slsReceiverSoftware/src/DataProcessor.h | 2 +- slsReceiverSoftware/src/GeneralData.h | 14 ++- .../tests/test-ArrangeDataBasedOnBitList.cpp | 6 +- 4 files changed, 75 insertions(+), 36 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 724c5758d..bd89784ff 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -26,6 +26,49 @@ namespace sls { +// TODO: move somewhere else +template struct AlignedData { + T *ptr; // Aligned data pointer + std::unique_ptr[]> buffer; + + AlignedData( + T *p, + std::unique_ptr[]> buf) + : ptr(p), buffer(std::move(buf)) {} +}; + +// TODO: should not be in this file any suggestions to move it to a more +// appropriate file? +// TODO: Add unit test +/* + * AlignData + * Aligns data to a given type T with proper alignment + * @param data: pointer to data + * @param size: size of data to align in bytes + * @return: aligned data + */ +template +void AlignData(AlignedData &aligneddata, char *data, size_t size) { + using AlignedBuffer = + typename std::aligned_storage::type; + std::unique_ptr tempbuffer; + + if (reinterpret_cast(data) % alignof(uint64_t) == 0) { + // If aligned directly cast to pointer + + aligneddata.ptr = reinterpret_cast(data); + + } else { + // Allocate a temporary buffer with proper alignment + tempbuffer = std::make_unique(size / sizeof(T)); + // size = ctbDigitaldbt; + + std::memcpy(tempbuffer.get(), data, size); + aligneddata.buffer = std::move(tempbuffer); + aligneddata.ptr = reinterpret_cast(aligneddata.buffer.get()); + } +} + const std::string DataProcessor::typeName = "DataProcessor"; DataProcessor::DataProcessor(int index) : ThreadObject(index, typeName) { @@ -574,26 +617,11 @@ void DataProcessor::Reorder(size_t &size, char *data) { } // make sure data is aligned to 8 bytes before casting to uint64_t - char *ptr = data + nAnalogDataBytes + ctbDbitOffset; - uint64_t *source = nullptr; - using AlignedBuffer = - std::aligned_storage::type; - std::unique_ptr tempbuffer; + AlignedData aligned_data(nullptr, nullptr); + AlignData(aligned_data, data + nAnalogDataBytes + ctbDbitOffset, + ctbDigitalDataBytes); - if (reinterpret_cast(ptr) % alignof(uint64_t) == 0) { - // If aligned, directly cast to uint64_t pointer - source = reinterpret_cast(ptr); - } else { - // Allocate a temporary buffer with proper alignment - tempbuffer = std::make_unique(ctbDigitalDataBytes / - sizeof(uint64_t)); - - std::memcpy(tempbuffer.get(), ptr, ctbDigitalDataBytes); - source = reinterpret_cast(tempbuffer.get()); - } - - // auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); - // TODO: leads to unaligned data + uint64_t *source = aligned_data.ptr; const size_t numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); @@ -612,13 +640,10 @@ void DataProcessor::Reorder(size_t &size, char *data) { int bitoffset = 0; // reorder - int count = 0; - int written = 0; for (size_t bi = 0; bi < 64; ++bi) { if (bitoffset != 0) { bitoffset = 0; - ++count; ++dest; } @@ -628,10 +653,8 @@ void DataProcessor::Reorder(size_t &size, char *data) { ++bitoffset; if (bitoffset == 8) { bitoffset = 0; - ++count; ++dest; } - ++written; } } @@ -671,7 +694,13 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { return; } - auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); + AlignedData aligned_data(nullptr, nullptr); + AlignData(aligned_data, data + nAnalogDataBytes + ctbDbitOffset, + ctbDigitalDataBytes); + + uint64_t *source = aligned_data.ptr; + + // auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); const int numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); @@ -747,19 +776,19 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { } } - // copy back to memory and update size - memcpy(data + nAnalogDataBytes, result.data(), - totalNumBytes * sizeof(uint8_t)); - size = totalNumBytes * sizeof(uint8_t) + nAnalogDataBytes + nTransceiverDataBytes; // check if size changed, if so move transceiver data to avoid gap in memory - if (size < nAnalogDataBytes + nDigitalDataBytes + nTransceiverDataBytes) + if (size != nAnalogDataBytes + nDigitalDataBytes + nTransceiverDataBytes) memmove(data + nAnalogDataBytes + totalNumBytes * sizeof(uint8_t), data + nAnalogDataBytes + nDigitalDataBytes, nTransceiverDataBytes); + // copy back to memory and update size + memcpy(data + nAnalogDataBytes, result.data(), + totalNumBytes * sizeof(uint8_t)); + LOG(logDEBUG1) << "totalNumBytes: " << totalNumBytes << " nAnalogDataBytes:" << nAnalogDataBytes << " ctbDbitOffset:" << ctbDbitOffset diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 3e0aa0b9d..ab58b2fe6 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -177,7 +177,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { uint32_t streamingTimerInMs; uint32_t streamingStartFnum; uint32_t currentFreqCount{0}; - struct timespec timerbegin {}; + struct timespec timerbegin{}; bool framePadding; std::vector ctbDbitList; bool reorder{false}; // true if data should be reordered TODO: add as mode diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index 0425815a3..6d9a5d626 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -60,8 +60,8 @@ class GeneralData { slsDetectorDefs::frameDiscardPolicy frameDiscardMode{ slsDetectorDefs::NO_DISCARD}; - GeneralData(){}; - virtual ~GeneralData(){}; + GeneralData() {}; + virtual ~GeneralData() {}; // Returns the pixel depth in byte, 4 bits being 0.5 byte float GetPixelDepth() { return float(dynamicRange) / 8; } @@ -443,6 +443,7 @@ class ChipTestBoardData : public GeneralData { nDigitalBytes = 0; nTransceiverBytes = 0; int nAnalogChans = 0, nDigitalChans = 0, nTransceiverChans = 0; + uint64_t digital_bytes_reserved = 0; // analog channels (normal, analog/digital readout) if (readoutType == slsDetectorDefs::ANALOG_ONLY || @@ -461,7 +462,12 @@ class ChipTestBoardData : public GeneralData { readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL || readoutType == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) { nDigitalChans = NCHAN_DIGITAL; - nDigitalBytes = (sizeof(uint64_t) * nDigitalSamples); + // allocate enough memory to support reordering of digital bits + uint32_t num_bytes_per_bit = (nDigitalSamples % 8 == 0) + ? nDigitalSamples / 8 + : nDigitalSamples / 8 + 1; + digital_bytes_reserved = 64 * num_bytes_per_bit; + nDigitalBytes = sizeof(uint64_t) * nDigitalSamples; LOG(logDEBUG1) << "Number of Digital Channels:" << nDigitalChans << " Databytes: " << nDigitalBytes; } @@ -480,7 +486,7 @@ class ChipTestBoardData : public GeneralData { nPixelsX = nAnalogChans + nDigitalChans + nTransceiverChans; dataSize = tengigaEnable ? 8144 : UDP_PACKET_DATA_BYTES; packetSize = headerSizeinPacket + dataSize; - imageSize = nAnalogBytes + nDigitalBytes + nTransceiverBytes; + imageSize = nAnalogBytes + digital_bytes_reserved + nTransceiverBytes; packetsPerFrame = ceil((double)imageSize / (double)dataSize); LOG(logDEBUG1) << "Total Number of Channels:" << nPixelsX diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index 1235daae1..3139e11e6 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -106,7 +106,11 @@ class DataProcessorTestFixture { void set_data() { delete[] data; - data = new char[get_size()]; + uint64_t max_bytes_per_bit = + num_samples % 8 == 0 ? num_samples / 8 : num_samples / 8 + 1; + uint64_t reserved_size = + get_size() - num_digital_bytes + max_bytes_per_bit * 64; + data = new char[reserved_size]; // set testing data memset(data, dummy_value, num_analog_bytes); // set to dummy value From c54b1cb6afe3182a8dff59f4b64c40b7a66436c9 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Wed, 19 Mar 2025 08:37:07 +0100 Subject: [PATCH 17/38] clang format --- slsReceiverSoftware/src/DataProcessor.h | 2 +- slsReceiverSoftware/src/GeneralData.h | 4 ++-- slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index fd5b9dc1f..eec4df506 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -177,7 +177,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { uint32_t streamingTimerInMs; uint32_t streamingStartFnum; uint32_t currentFreqCount{0}; - struct timespec timerbegin{}; + struct timespec timerbegin {}; bool framePadding; std::vector ctbDbitList; int ctbDbitOffset{0}; diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index 6d9a5d626..9f3b43429 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -60,8 +60,8 @@ class GeneralData { slsDetectorDefs::frameDiscardPolicy frameDiscardMode{ slsDetectorDefs::NO_DISCARD}; - GeneralData() {}; - virtual ~GeneralData() {}; + GeneralData(){}; + virtual ~GeneralData(){}; // Returns the pixel depth in byte, 4 bits being 0.5 byte float GetPixelDepth() { return float(dynamicRange) / 8; } diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index c651de594..af75c3b54 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -39,8 +39,8 @@ class GeneralDataTest : public GeneralData { // dummy DataProcessor class for testing class DataProcessorTest : public DataProcessor { public: - DataProcessorTest() : DataProcessor(0) {}; - ~DataProcessorTest() {}; + DataProcessorTest() : DataProcessor(0){}; + ~DataProcessorTest(){}; void ArrangeDbitData(size_t &size, char *data) { DataProcessor::ArrangeDbitData(size, data); } From b7e17d1320b3cc48c5b56f3671cc65f7a1f473d9 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Wed, 19 Mar 2025 11:51:28 +0100 Subject: [PATCH 18/38] added reorder to documentation, added flag to master binary and hdf5 file --- docs/src/binaryfileformat.rst | 1 + docs/src/masterfileattributes.rst | 3 +++ slsReceiverSoftware/src/ClientInterface.cpp | 2 +- slsReceiverSoftware/src/DataProcessor.h | 2 +- slsReceiverSoftware/src/Implementation.cpp | 2 ++ slsReceiverSoftware/src/MasterAttributes.cpp | 13 +++++++++++++ slsReceiverSoftware/src/MasterAttributes.h | 2 ++ slsReceiverSoftware/src/receiver_defs.h | 4 ++-- 8 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/src/binaryfileformat.rst b/docs/src/binaryfileformat.rst index 42b2a5657..e3657f246 100644 --- a/docs/src/binaryfileformat.rst +++ b/docs/src/binaryfileformat.rst @@ -359,6 +359,7 @@ Chip Test Board "Digital Flag": 0, "Digital Samples": 1000, "Dbit Offset": 0, + "Dbit Reorder": 1, "Dbit Bitset": 0, "Transceiver Mask": "0x3", "Transceiver Flag": 0, diff --git a/docs/src/masterfileattributes.rst b/docs/src/masterfileattributes.rst index cc1355553..777c930ff 100644 --- a/docs/src/masterfileattributes.rst +++ b/docs/src/masterfileattributes.rst @@ -345,6 +345,9 @@ Chip Test Board +-----------------------+-------------------------------------------------+ | Dbit Offset | Digital offset of valid data in bytes | +-----------------------+-------------------------------------------------+ + | Dbit Reorder | Group bits of all samples together to have them | + | | contiguous in the file | + +-----------------------+-------------------------------------------------+ | Dbit Bitset | Digital 64 bit mask of bits enabled in receiver | +-----------------------+-------------------------------------------------+ | Transceiver Mask | Mask of channels enabled in Transceiver | diff --git a/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index 0180af8fb..f3de129b5 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -1807,7 +1807,7 @@ int ClientInterface::set_dbit_reorder(Interface &socket) { throw RuntimeError("Invalid dbit reorder: " + std::to_string(arg)); } verifyIdle(socket); - LOG(logDEBUG1) << "Setting Dbit offset: " << arg; + LOG(logDEBUG1) << "Setting Dbit reorder: " << arg; impl()->setDbitReorder(arg); return socket.Send(OK); } diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index eec4df506..fd5b9dc1f 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -177,7 +177,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { uint32_t streamingTimerInMs; uint32_t streamingStartFnum; uint32_t currentFreqCount{0}; - struct timespec timerbegin {}; + struct timespec timerbegin{}; bool framePadding; std::vector ctbDbitList; int ctbDbitOffset{0}; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index ea636258c..e4385d9c0 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -992,7 +992,9 @@ void Implementation::StartMasterWriter() { : 0; masterAttributes.digitalSamples = generalData->nDigitalSamples; masterAttributes.dbitoffset = ctbDbitOffset; + masterAttributes.dbitreorder = ctbDbitReorder; masterAttributes.dbitlist = 0; + for (auto &i : ctbDbitList) { masterAttributes.dbitlist |= (static_cast(1) << i); } diff --git a/slsReceiverSoftware/src/MasterAttributes.cpp b/slsReceiverSoftware/src/MasterAttributes.cpp index dd85a0381..8420e31ad 100644 --- a/slsReceiverSoftware/src/MasterAttributes.cpp +++ b/slsReceiverSoftware/src/MasterAttributes.cpp @@ -551,6 +551,13 @@ void MasterAttributes::WriteHDF5DbitOffset(H5::H5File *fd, H5::Group *group) { dataset.write(&dbitoffset, H5::PredType::NATIVE_INT); } +void MasterAttributes::WriteHDF5DbitReorder(H5::H5File *fd, H5::Group *group) { + H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); + H5::DataSet dataset = group->createDataSet( + "Dbit Reorder", H5::PredType::NATIVE_INT, dataspace); + dataset.write(&dbitreorder, H5::PredType::NATIVE_INT); +} + void MasterAttributes::WriteHDF5DbitList(H5::H5File *fd, H5::Group *group) { H5::DataSpace dataspace = H5::DataSpace(H5S_SCALAR); H5::DataSet dataset = group->createDataSet( @@ -744,6 +751,8 @@ void MasterAttributes::GetCtbBinaryAttributes( w->Uint(digitalSamples); w->Key("Dbit Offset"); w->Uint(dbitoffset); + w->Key("Dbit Reorder"); + w->Uint(dbitreorder); w->Key("Dbit Bitset"); w->Uint64(dbitlist); w->Key("Transceiver Mask"); @@ -766,6 +775,7 @@ void MasterAttributes::WriteCtbHDF5Attributes(H5::H5File *fd, MasterAttributes::WriteHDF5DigitalFlag(fd, group); MasterAttributes::WriteHDF5DigitalSamples(fd, group); MasterAttributes::WriteHDF5DbitOffset(fd, group); + MasterAttributes::WriteHDF5DbitReorder(fd, group); MasterAttributes::WriteHDF5DbitList(fd, group); MasterAttributes::WriteHDF5TransceiverMask(fd, group); MasterAttributes::WriteHDF5TransceiverFlag(fd, group); @@ -791,6 +801,8 @@ void MasterAttributes::GetXilinxCtbBinaryAttributes( w->Uint(digitalSamples); w->Key("Dbit Offset"); w->Uint(dbitoffset); + w->Key("Dbit Reorder"); + w->Uint(dbitreorder); w->Key("Dbit Bitset"); w->Uint64(dbitlist); w->Key("Transceiver Mask"); @@ -812,6 +824,7 @@ void MasterAttributes::WriteXilinxCtbHDF5Attributes(H5::H5File *fd, MasterAttributes::WriteHDF5DigitalFlag(fd, group); MasterAttributes::WriteHDF5DigitalSamples(fd, group); MasterAttributes::WriteHDF5DbitOffset(fd, group); + MasterAttributes::WriteHDF5DbitReorder(fd, group); MasterAttributes::WriteHDF5DbitList(fd, group); MasterAttributes::WriteHDF5TransceiverMask(fd, group); MasterAttributes::WriteHDF5TransceiverFlag(fd, group); diff --git a/slsReceiverSoftware/src/MasterAttributes.h b/slsReceiverSoftware/src/MasterAttributes.h index 015c632c4..0e3c168ae 100644 --- a/slsReceiverSoftware/src/MasterAttributes.h +++ b/slsReceiverSoftware/src/MasterAttributes.h @@ -51,6 +51,7 @@ class MasterAttributes { uint32_t analogSamples{0}; uint32_t digital{0}; uint32_t digitalSamples{0}; + uint32_t dbitreorder{1}; uint32_t dbitoffset{0}; uint64_t dbitlist{0}; uint32_t transceiverMask{0}; @@ -104,6 +105,7 @@ class MasterAttributes { void WriteHDF5DigitalSamples(H5::H5File *fd, H5::Group *group); void WriteHDF5DbitOffset(H5::H5File *fd, H5::Group *group); void WriteHDF5DbitList(H5::H5File *fd, H5::Group *group); + void WriteHDF5DbitReorder(H5::H5File *fd, H5::Group *group); void WriteHDF5TransceiverMask(H5::H5File *fd, H5::Group *group); void WriteHDF5TransceiverFlag(H5::H5File *fd, H5::Group *group); void WriteHDF5TransceiverSamples(H5::H5File *fd, H5::Group *group); diff --git a/slsReceiverSoftware/src/receiver_defs.h b/slsReceiverSoftware/src/receiver_defs.h index ba9697706..ade363e79 100644 --- a/slsReceiverSoftware/src/receiver_defs.h +++ b/slsReceiverSoftware/src/receiver_defs.h @@ -19,8 +19,8 @@ namespace sls { // files // versions -#define HDF5_WRITER_VERSION (6.6) // 1 decimal places -#define BINARY_WRITER_VERSION (7.2) // 1 decimal places +#define HDF5_WRITER_VERSION (6.7) // 1 decimal places +#define BINARY_WRITER_VERSION (7.3) // 1 decimal places #define MAX_FRAMES_PER_FILE 20000 #define SHORT_MAX_FRAMES_PER_FILE 100000 From 8b3625fc011ac4694d959fefae24225942329088 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Thu, 20 Mar 2025 11:00:40 +0100 Subject: [PATCH 19/38] added dbitreorder flag to chip test board gui --- pyctbgui/pyctbgui/services/Signals.py | 118 ++++++++++++++++---------- pyctbgui/pyctbgui/ui/signals.ui | 102 +++++++++++++--------- 2 files changed, 135 insertions(+), 85 deletions(-) diff --git a/pyctbgui/pyctbgui/services/Signals.py b/pyctbgui/pyctbgui/services/Signals.py index a06b9a412..edd8d7e05 100644 --- a/pyctbgui/pyctbgui/services/Signals.py +++ b/pyctbgui/pyctbgui/services/Signals.py @@ -22,6 +22,7 @@ class SignalsTab(QtWidgets.QWidget): self.plotTab = None self.legend: LegendItem | None = None self.rx_dbitoffset = None + self.rx_dbitreorder = None self.rx_dbitlist = None def refresh(self): @@ -29,6 +30,7 @@ class SignalsTab(QtWidgets.QWidget): self.updateDigitalBitEnable() self.updateIOOut() self.getDBitOffset() + self.getDBitReorder() def connect_ui(self): for i in range(Defines.signals.count): @@ -49,6 +51,7 @@ class SignalsTab(QtWidgets.QWidget): partial(self.setIOOutRange, Defines.signals.half, Defines.signals.count)) self.view.lineEditPatIOCtrl.editingFinished.connect(self.setIOOutReg) self.view.spinBoxDBitOffset.editingFinished.connect(self.setDbitOffset) + self.view.checkBoxDBitReorder.stateChanged.connect(self.setDbitReorder) def setup_ui(self): self.plotTab = self.mainWindow.plotTab @@ -87,60 +90,74 @@ class SignalsTab(QtWidgets.QWidget): self.legend.addItem(plot, name) @recordOrApplyPedestal - def _processWaveformData(self, data, aSamples, dSamples, rx_dbitlist, isPlottedArray, rx_dbitoffset, romode, + def _processWaveformData(self, data, aSamples, dSamples, rx_reorder, rx_dbitlist, isPlottedArray, romode, nADCEnabled): - """ - transform raw waveform data into a processed numpy array - @param data: raw waveform data - """ - dbitoffset = rx_dbitoffset + + #transform raw waveform data into a processed numpy array + #@param data: raw waveform data + + start_digital_data = 0 if romode == 2: - dbitoffset += nADCEnabled * 2 * aSamples - digital_array = np.array(np.frombuffer(data, offset=dbitoffset, dtype=np.uint8)) - nbitsPerDBit = dSamples - if nbitsPerDBit % 8 != 0: - nbitsPerDBit += (8 - (dSamples % 8)) - offset = 0 - arr = [] - for i in rx_dbitlist: - # where numbits * numsamples is not a multiple of 8 - if offset % 8 != 0: - offset += (8 - (offset % 8)) - if not isPlottedArray[i]: - offset += nbitsPerDBit - return None - waveform = np.zeros(dSamples) - for iSample in range(dSamples): - # all samples for digital bit together from slsReceiver - index = int(offset / 8) - iBit = offset % 8 - bit = (digital_array[index] >> iBit) & 1 - waveform[iSample] = bit - offset += 1 - arr.append(waveform) - - return np.array(arr) - + start_digital_data += nADCEnabled * 2 * aSamples + digital_array = np.array(np.frombuffer(data, offset=start_digital_data, dtype=np.uint8)) + if rx_reorder: + nbitsPerDBit = dSamples + arr = np.empty((rx_dbitlist.size, dSamples), dtype=np.uint8) + if nbitsPerDBit % 8 != 0: + nbitsPerDBit += (8 - (dSamples % 8)) + offset = 0 + for i in rx_dbitlist: + # where numbits * numsamples is not a multiple of 8 + if offset % 8 != 0: + offset += (8 - (offset % 8)) + if not isPlottedArray[i]: + offset += nbitsPerDBit + arr[i, :] = np.nan + continue + for iSample in range(dSamples): + # all samples for digital bit together from slsReceiver + index = int(offset / 8) + iBit = offset % 8 + bit = (digital_array[index] >> iBit) & 1 + arr[i,iSample] = bit + offset += 1 + return arr + else: + nbitsPerSample = int(rx_dbitlist.size) if rx_dbitlist.size % 8 == 0 else int(rx_dbitlist.size + (8 - (rx_dbitlist.size % 8))) + arr = np.empty((dSamples, rx_dbitlist.size), dtype=np.uint8) #store all samples + for iSample in range(dSamples): + offset = nbitsPerSample * iSample + for i in range(rx_dbitlist): #TODO i think ctBitlist is reordered CHECK!!! + if not isPlottedArray[i]: + offset += 1 + arr[iSample, i] = np.nan + index = int(offset/8) + iBit = i % 8 + bit = (digital_array[index] >> iBit) & 1 + arr[iSample, i] = bit + offset += 1 + return arr.T.copy() + def processWaveformData(self, data, aSamples, dSamples): - """ - view function - plots processed waveform data - data: raw waveform data - dsamples: digital samples - asamples: analog samples - """ + + #view function + #plots processed waveform data + #data: raw waveform data + #dsamples: digital samples + #asamples: analog samples + waveforms = {} isPlottedArray = {i: getattr(self.view, f"checkBoxBIT{i}Plot").isChecked() for i in self.rx_dbitlist} - digital_array = self._processWaveformData(data, aSamples, dSamples, self.rx_dbitlist, isPlottedArray, - self.rx_dbitoffset, self.mainWindow.romode.value, + digital_array = self._processWaveformData(data, aSamples, dSamples, self.rx_dbitreorder, self.rx_dbitlist, isPlottedArray, + self.mainWindow.romode.value, self.mainWindow.nADCEnabled) irow = 0 - for idx, i in enumerate(self.rx_dbitlist): + for idx, i in enumerate(self.rx_dbitlist): #TODO i think ctBitlist is reordered CHECK!!! # bits enabled but not plotting - waveform = digital_array[idx] - if waveform is None: + waveform = digital_array[idx, :] + if np.isnan(waveform[0]): continue self.mainWindow.digitalPlots[i].setData(waveform) plotName = getattr(self.view, f"labelBIT{i}").text() @@ -151,8 +168,10 @@ class SignalsTab(QtWidgets.QWidget): irow += 1 else: self.mainWindow.digitalPlots[i].setY(0) + return waveforms + def initializeAllDigitalPlots(self): self.mainWindow.plotDigitalWaveform = pg.plot() self.mainWindow.plotDigitalWaveform.addLegend(colCount=Defines.colCount) @@ -360,14 +379,25 @@ class SignalsTab(QtWidgets.QWidget): self.view.spinBoxDBitOffset.setValue(self.rx_dbitoffset) self.view.spinBoxDBitOffset.editingFinished.connect(self.setDbitOffset) + def getDBitReorder(self): + self.view.checkBoxDBitReorder.stateChanged.disconnect() + self.rx_dbitreorder = self.det.rx_dbitreorder + self.view.checkBoxDBitReorder.setChecked(self.rx_dbitreorder) + self.view.checkBoxDBitReorder.stateChanged.connect(self.setDbitReorder) + + def setDbitOffset(self): self.det.rx_dbitoffset = self.view.spinBoxDBitOffset.value() + def setDbitReorder(self): + self.det.rx_dbitreorder = self.view.checkBoxDBitReorder.isChecked() + def saveParameters(self) -> list: commands = [] dblist = [str(i) for i in range(Defines.signals.count) if getattr(self.view, f"checkBoxBIT{i}DB").isChecked()] if len(dblist) > 0: commands.append(f"rx_dbitlist {', '.join(dblist)}") commands.append(f"rx_dbitoffset {self.view.spinBoxDBitOffset.value()}") + commands.append(f"rx_dbitreorder {self.view.checkBoxDBitReorder.isChecked()}") commands.append(f"patioctrl {self.view.lineEditPatIOCtrl.text()}") return commands diff --git a/pyctbgui/pyctbgui/ui/signals.ui b/pyctbgui/pyctbgui/ui/signals.ui index 231c0b92f..d3f1022e9 100644 --- a/pyctbgui/pyctbgui/ui/signals.ui +++ b/pyctbgui/pyctbgui/ui/signals.ui @@ -6074,6 +6074,33 @@ QFrame::Raised + + + + + 150 + 32 + + + + + 150 + 32 + + + + + 10 + + + + background-color: rgb(255, 255, 255); + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + @@ -6086,6 +6113,31 @@ + + + + DBit Reorder + + + + + + + + 50 + 0 + + + + + 10 + + + + IO Control Register: + + + @@ -6133,50 +6185,18 @@ - - - + + + + Qt::Horizontal + + - 150 - 32 + 40 + 20 - - - 150 - 32 - - - - - 10 - - - - background-color: rgb(255, 255, 255); - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - 0 - - - - - 10 - - - - IO Control Register: - - + From 713e4f6822283fe26ae6a664b5e0c4f56a5701fc Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Thu, 20 Mar 2025 11:00:40 +0100 Subject: [PATCH 20/38] added dbitreorder flag to chip test board gui --- pyctbgui/pyctbgui/services/Signals.py | 118 +++++++++++------- pyctbgui/pyctbgui/ui/signals.ui | 102 +++++++++------ .../slsDetectorFunctionList.c | 8 +- 3 files changed, 142 insertions(+), 86 deletions(-) diff --git a/pyctbgui/pyctbgui/services/Signals.py b/pyctbgui/pyctbgui/services/Signals.py index a06b9a412..d03cdc373 100644 --- a/pyctbgui/pyctbgui/services/Signals.py +++ b/pyctbgui/pyctbgui/services/Signals.py @@ -22,6 +22,7 @@ class SignalsTab(QtWidgets.QWidget): self.plotTab = None self.legend: LegendItem | None = None self.rx_dbitoffset = None + self.rx_dbitreorder = None self.rx_dbitlist = None def refresh(self): @@ -29,6 +30,7 @@ class SignalsTab(QtWidgets.QWidget): self.updateDigitalBitEnable() self.updateIOOut() self.getDBitOffset() + self.getDBitReorder() def connect_ui(self): for i in range(Defines.signals.count): @@ -49,6 +51,7 @@ class SignalsTab(QtWidgets.QWidget): partial(self.setIOOutRange, Defines.signals.half, Defines.signals.count)) self.view.lineEditPatIOCtrl.editingFinished.connect(self.setIOOutReg) self.view.spinBoxDBitOffset.editingFinished.connect(self.setDbitOffset) + self.view.checkBoxDBitReorder.stateChanged.connect(self.setDbitReorder) def setup_ui(self): self.plotTab = self.mainWindow.plotTab @@ -87,60 +90,74 @@ class SignalsTab(QtWidgets.QWidget): self.legend.addItem(plot, name) @recordOrApplyPedestal - def _processWaveformData(self, data, aSamples, dSamples, rx_dbitlist, isPlottedArray, rx_dbitoffset, romode, + def _processWaveformData(self, data, aSamples, dSamples, rx_reorder, rx_dbitlist, isPlottedArray, romode, nADCEnabled): - """ - transform raw waveform data into a processed numpy array - @param data: raw waveform data - """ - dbitoffset = rx_dbitoffset + + #transform raw waveform data into a processed numpy array + #@param data: raw waveform data + + start_digital_data = 0 if romode == 2: - dbitoffset += nADCEnabled * 2 * aSamples - digital_array = np.array(np.frombuffer(data, offset=dbitoffset, dtype=np.uint8)) - nbitsPerDBit = dSamples - if nbitsPerDBit % 8 != 0: - nbitsPerDBit += (8 - (dSamples % 8)) - offset = 0 - arr = [] - for i in rx_dbitlist: - # where numbits * numsamples is not a multiple of 8 - if offset % 8 != 0: - offset += (8 - (offset % 8)) - if not isPlottedArray[i]: - offset += nbitsPerDBit - return None - waveform = np.zeros(dSamples) - for iSample in range(dSamples): - # all samples for digital bit together from slsReceiver - index = int(offset / 8) - iBit = offset % 8 - bit = (digital_array[index] >> iBit) & 1 - waveform[iSample] = bit - offset += 1 - arr.append(waveform) - - return np.array(arr) - + start_digital_data += nADCEnabled * 2 * aSamples + digital_array = np.array(np.frombuffer(data, offset=start_digital_data, dtype=np.uint8)) + if rx_reorder: + arr = np.empty((len(rx_dbitlist), dSamples), dtype=np.uint8) + nbitsPerDBit = dSamples + if nbitsPerDBit % 8 != 0: + nbitsPerDBit += (8 - (dSamples % 8)) + offset = 0 + for idx, i in enumerate(rx_dbitlist): + # where numbits * numsamples is not a multiple of 8 + if offset % 8 != 0: + offset += (8 - (offset % 8)) + if not isPlottedArray[i]: + offset += nbitsPerDBit + arr[idx, :] = np.nan + continue + for iSample in range(dSamples): + # all samples for digital bit together from slsReceiver + index = int(offset / 8) + iBit = offset % 8 + bit = (digital_array[index] >> iBit) & 1 + arr[idx,iSample] = bit + offset += 1 + return arr + else: + nbitsPerSample = len(rx_dbitlist) if len(rx_dbitlist) % 8 == 0 else len(rx_dbitlist) + (8 - (len(rx_dbitlist) % 8)) + arr = np.empty((dSamples, len(rx_dbitlist)), dtype=np.uint8) #store all samples + for iSample in range(dSamples): + offset = nbitsPerSample * iSample + for idx, i in enumerate(rx_dbitlist): #TODO i think ctBitlist is reordered CHECK!!! + if not isPlottedArray[i]: + offset += 1 + arr[iSample, idx] = np.nan + index = int(offset/8) + iBit = idx % 8 + bit = (digital_array[index] >> iBit) & 1 + arr[iSample, idx] = bit + offset += 1 + return arr.T.copy() + def processWaveformData(self, data, aSamples, dSamples): - """ - view function - plots processed waveform data - data: raw waveform data - dsamples: digital samples - asamples: analog samples - """ + + #view function + #plots processed waveform data + #data: raw waveform data + #dsamples: digital samples + #asamples: analog samples + waveforms = {} isPlottedArray = {i: getattr(self.view, f"checkBoxBIT{i}Plot").isChecked() for i in self.rx_dbitlist} - digital_array = self._processWaveformData(data, aSamples, dSamples, self.rx_dbitlist, isPlottedArray, - self.rx_dbitoffset, self.mainWindow.romode.value, + digital_array = self._processWaveformData(data, aSamples, dSamples, self.rx_dbitreorder, self.rx_dbitlist, isPlottedArray, + self.mainWindow.romode.value, self.mainWindow.nADCEnabled) irow = 0 - for idx, i in enumerate(self.rx_dbitlist): + for idx, i in enumerate(self.rx_dbitlist): #TODO i think ctBitlist is reordered CHECK!!! # bits enabled but not plotting - waveform = digital_array[idx] - if waveform is None: + waveform = digital_array[idx, :] + if np.isnan(waveform[0]): continue self.mainWindow.digitalPlots[i].setData(waveform) plotName = getattr(self.view, f"labelBIT{i}").text() @@ -151,8 +168,10 @@ class SignalsTab(QtWidgets.QWidget): irow += 1 else: self.mainWindow.digitalPlots[i].setY(0) + return waveforms + def initializeAllDigitalPlots(self): self.mainWindow.plotDigitalWaveform = pg.plot() self.mainWindow.plotDigitalWaveform.addLegend(colCount=Defines.colCount) @@ -360,14 +379,25 @@ class SignalsTab(QtWidgets.QWidget): self.view.spinBoxDBitOffset.setValue(self.rx_dbitoffset) self.view.spinBoxDBitOffset.editingFinished.connect(self.setDbitOffset) + def getDBitReorder(self): + self.view.checkBoxDBitReorder.stateChanged.disconnect() + self.rx_dbitreorder = self.det.rx_dbitreorder + self.view.checkBoxDBitReorder.setChecked(self.rx_dbitreorder) + self.view.checkBoxDBitReorder.stateChanged.connect(self.setDbitReorder) + + def setDbitOffset(self): self.det.rx_dbitoffset = self.view.spinBoxDBitOffset.value() + def setDbitReorder(self): + self.det.rx_dbitreorder = self.view.checkBoxDBitReorder.isChecked() + def saveParameters(self) -> list: commands = [] dblist = [str(i) for i in range(Defines.signals.count) if getattr(self.view, f"checkBoxBIT{i}DB").isChecked()] if len(dblist) > 0: commands.append(f"rx_dbitlist {', '.join(dblist)}") commands.append(f"rx_dbitoffset {self.view.spinBoxDBitOffset.value()}") + commands.append(f"rx_dbitreorder {self.view.checkBoxDBitReorder.isChecked()}") commands.append(f"patioctrl {self.view.lineEditPatIOCtrl.text()}") return commands diff --git a/pyctbgui/pyctbgui/ui/signals.ui b/pyctbgui/pyctbgui/ui/signals.ui index 231c0b92f..d3f1022e9 100644 --- a/pyctbgui/pyctbgui/ui/signals.ui +++ b/pyctbgui/pyctbgui/ui/signals.ui @@ -6074,6 +6074,33 @@ QFrame::Raised + + + + + 150 + 32 + + + + + 150 + 32 + + + + + 10 + + + + background-color: rgb(255, 255, 255); + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + @@ -6086,6 +6113,31 @@ + + + + DBit Reorder + + + + + + + + 50 + 0 + + + + + 10 + + + + IO Control Register: + + + @@ -6133,50 +6185,18 @@ - - - + + + + Qt::Horizontal + + - 150 - 32 + 40 + 20 - - - 150 - 32 - - - - - 10 - - - - background-color: rgb(255, 255, 255); - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 50 - 0 - - - - - 10 - - - - IO Control Register: - - + diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index bf9773e71..f1f33cb84 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -2258,11 +2258,17 @@ void *start_timer(void *arg) { int packetsPerFrame = ceil((double)imageSize / (double)dataSize); // Generate Data - char imageData[imageSize]; + char imageData[imageSize]; // memset(imageData, 0, imageSize); + /* for (int i = 0; i < imageSize; i += sizeof(uint16_t)) { *((uint16_t *)(imageData + i)) = i; } + */ + + for (int i = 0; i < imageSize; i += 2 * sizeof(uint64_t)) { + *((uint64_t *)(imageData + i)) = 0xffffffffffffffff; + } // Send data uint64_t frameNr = 0; From 96ae1a1cca865ab0e7083cd7ccafa43de1d2b53a Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Thu, 20 Mar 2025 16:47:42 +0100 Subject: [PATCH 21/38] found bug needed to refresh member variables --- pyctbgui/pyctbgui/services/Signals.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyctbgui/pyctbgui/services/Signals.py b/pyctbgui/pyctbgui/services/Signals.py index b48581a68..4f27ab886 100644 --- a/pyctbgui/pyctbgui/services/Signals.py +++ b/pyctbgui/pyctbgui/services/Signals.py @@ -113,7 +113,6 @@ class SignalsTab(QtWidgets.QWidget): if not isPlottedArray[i]: offset += nbitsPerDBit arr[idx, :] = np.nan - continue for iSample in range(dSamples): # all samples for digital bit together from slsReceiver @@ -128,10 +127,11 @@ class SignalsTab(QtWidgets.QWidget): arr = np.empty((dSamples, len(rx_dbitlist)), dtype=np.uint8) #store all samples for iSample in range(dSamples): offset = nbitsPerSample * iSample - for idx, i in enumerate(rx_dbitlist): #TODO i think ctBitlist is reordered CHECK!!! + for idx, i in enumerate(rx_dbitlist): if not isPlottedArray[i]: offset += 1 arr[iSample, idx] = np.nan + index = int(offset/8) iBit = idx % 8 bit = (digital_array[index] >> iBit) & 1 @@ -146,6 +146,8 @@ class SignalsTab(QtWidgets.QWidget): #data: raw waveform data #dsamples: digital samples #asamples: analog samples + + self.refresh() waveforms = {} isPlottedArray = {i: getattr(self.view, f"checkBoxBIT{i}Plot").isChecked() for i in self.rx_dbitlist} From 1d1b55b864e24eb3e75b2f13c4c205f700e6db57 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Tue, 8 Apr 2025 15:57:11 +0200 Subject: [PATCH 22/38] changed documentation --- docs/src/masterfileattributes.rst | 4 ++-- slsDetectorSoftware/generator/commands.yaml | 2 +- slsDetectorSoftware/include/sls/Detector.h | 3 ++- slsDetectorSoftware/src/Caller.cpp | 2 +- slsReceiverSoftware/src/DataProcessor.h | 8 ++++---- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/src/masterfileattributes.rst b/docs/src/masterfileattributes.rst index 777c930ff..5190ee647 100644 --- a/docs/src/masterfileattributes.rst +++ b/docs/src/masterfileattributes.rst @@ -345,8 +345,8 @@ Chip Test Board +-----------------------+-------------------------------------------------+ | Dbit Offset | Digital offset of valid data in bytes | +-----------------------+-------------------------------------------------+ - | Dbit Reorder | Group bits of all samples together to have them | - | | contiguous in the file | + | Dbit Reorder | Reorder such that it groups each signal (0-63) | + | | from all the different samples together | +-----------------------+-------------------------------------------------+ | Dbit Bitset | Digital 64 bit mask of bits enabled in receiver | +-----------------------+-------------------------------------------------+ diff --git a/slsDetectorSoftware/generator/commands.yaml b/slsDetectorSoftware/generator/commands.yaml index 47e2e1898..f33cf7be2 100644 --- a/slsDetectorSoftware/generator/commands.yaml +++ b/slsDetectorSoftware/generator/commands.yaml @@ -1414,7 +1414,7 @@ lock: rx_dbitreorder: - help: "[0, 1]\n\t[Ctb] Reorder digital data to group together all samples per signal. Default is 1. Setting to 0 means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together." + help: "[0, 1]\n\t[Ctb] Reorder digital data such that it groups each signal (0-63) from all the different samples together . Default is 1. Setting to 0 means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together." inherit_actions: INTEGER_COMMAND_VEC_ID actions: GET: diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 8096f75a7..eb679a578 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1732,7 +1732,8 @@ class Detector { /** [CTB] */ Result getRxDbitReorder(Positions pos = {}) const; - /** [CTB] Reorder digital data to group together all samples per signal. + /** [CTB] Reorder digital data such that it groups each signal (0-63) + * from all the different samples together. * Default is true. Setting to false means 'do not reorder' and to keep what * the board spits out, which is that all signals in a sample are grouped * together */ diff --git a/slsDetectorSoftware/src/Caller.cpp b/slsDetectorSoftware/src/Caller.cpp index c284b1957..78a6f79d7 100644 --- a/slsDetectorSoftware/src/Caller.cpp +++ b/slsDetectorSoftware/src/Caller.cpp @@ -10706,7 +10706,7 @@ std::string Caller::rx_dbitreorder(int action) { // print help if (action == slsDetectorDefs::HELP_ACTION) { os << R"V0G0N([0, 1] - [Ctb] Reorder digital data to group together all samples per signal. Default is 1. Setting to 0 means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together. )V0G0N" + [Ctb] Reorder digital data such that it groups each signal (0-63) from all the different samples together . Default is 1. Setting to 0 means 'do not reorder' and to keep what the board spits out, which is that all signals in a sample are grouped together. )V0G0N" << std::endl; return os.str(); } diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index fd5b9dc1f..6e70072cd 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -96,14 +96,14 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { /** * Align corresponding digital bits together (CTB only if ctbDbitlist is not * empty) - * set variable reorder to true if, data should be rearranged such that - * individual digital bits from all samples are consecutive in memory + * set variable reorder to true if data should be rearranged such that + * it groups each signal (0-63) from all the different samples together */ void ArrangeDbitData(size_t &size, char *data); /** - * reorder datastream such that individual digital bits from all samples are - * stored consecutively in memory + * reorder datastream such that each signal (0-63) from all the different + * samples are grouped together and stored consecutively in memory */ void Reorder(size_t &size, char *data); From 6740d9b36354b799dd3a8d29801628960b9043ab Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Wed, 9 Apr 2025 09:20:05 +0200 Subject: [PATCH 23/38] alignedData now uses std::align_alloc --- pyctbgui/pyctbgui/services/Signals.py | 46 +++++++++-------- slsReceiverSoftware/CMakeLists.txt | 1 + slsReceiverSoftware/include/sls/utils.h | 36 +++++++++++++ slsReceiverSoftware/src/DataProcessor.cpp | 62 ++++------------------- 4 files changed, 70 insertions(+), 75 deletions(-) create mode 100644 slsReceiverSoftware/include/sls/utils.h diff --git a/pyctbgui/pyctbgui/services/Signals.py b/pyctbgui/pyctbgui/services/Signals.py index 4f27ab886..856571e22 100644 --- a/pyctbgui/pyctbgui/services/Signals.py +++ b/pyctbgui/pyctbgui/services/Signals.py @@ -90,7 +90,7 @@ class SignalsTab(QtWidgets.QWidget): self.legend.addItem(plot, name) @recordOrApplyPedestal - def _processWaveformData(self, data, aSamples, dSamples, rx_reorder, rx_dbitlist, isPlottedArray, romode, + def _processWaveformData(self, data, aSamples, dSamples, rx_dbitreorder, rx_dbitlist, isPlottedArray, romode, nADCEnabled): #transform raw waveform data into a processed numpy array @@ -100,44 +100,46 @@ class SignalsTab(QtWidgets.QWidget): if romode == 2: start_digital_data += nADCEnabled * 2 * aSamples digital_array = np.array(np.frombuffer(data, offset=start_digital_data, dtype=np.uint8)) - if rx_reorder: - arr = np.empty((len(rx_dbitlist), dSamples), dtype=np.uint8) + if rx_dbitreorder: + samples_per_bit = np.empty((len(rx_dbitlist), dSamples), dtype=np.uint8) #stored per row all the corresponding signals of all samples nbitsPerDBit = dSamples if nbitsPerDBit % 8 != 0: nbitsPerDBit += (8 - (dSamples % 8)) - offset = 0 + bit_index = 0 for idx, i in enumerate(rx_dbitlist): # where numbits * numsamples is not a multiple of 8 - if offset % 8 != 0: - offset += (8 - (offset % 8)) + if bit_index % 8 != 0: + bit_index += (8 - (bit_index % 8)) if not isPlottedArray[i]: - offset += nbitsPerDBit - arr[idx, :] = np.nan + bit_index += nbitsPerDBit + samples_per_bit[idx, :] = np.nan continue for iSample in range(dSamples): # all samples for digital bit together from slsReceiver - index = int(offset / 8) - iBit = offset % 8 + index = int(bit_index / 8) + iBit = bit_index % 8 bit = (digital_array[index] >> iBit) & 1 - arr[idx,iSample] = bit - offset += 1 - return arr + samples_per_bit[idx,iSample] = bit + bit_index += 1 + return samples_per_bit else: nbitsPerSample = len(rx_dbitlist) if len(rx_dbitlist) % 8 == 0 else len(rx_dbitlist) + (8 - (len(rx_dbitlist) % 8)) - arr = np.empty((dSamples, len(rx_dbitlist)), dtype=np.uint8) #store all samples + bits_per_sample = np.empty((dSamples, len(rx_dbitlist)), dtype=np.uint8) #store per row all selected bits of a sample for iSample in range(dSamples): - offset = nbitsPerSample * iSample + bit_index = nbitsPerSample * iSample for idx, i in enumerate(rx_dbitlist): if not isPlottedArray[i]: - offset += 1 - arr[iSample, idx] = np.nan + bit_index += 1 + bits_per_sample[iSample, idx] = np.nan - index = int(offset/8) + index = int(bit_index/8) iBit = idx % 8 bit = (digital_array[index] >> iBit) & 1 - arr[iSample, idx] = bit - offset += 1 - return arr.T.copy() + bits_per_sample[iSample, idx] = bit + bit_index += 1 + return bits_per_sample.T.copy() + + def processWaveformData(self, data, aSamples, dSamples): @@ -157,7 +159,7 @@ class SignalsTab(QtWidgets.QWidget): self.mainWindow.nADCEnabled) irow = 0 - for idx, i in enumerate(self.rx_dbitlist): #TODO i think ctBitlist is reordered CHECK!!! + for idx, i in enumerate(self.rx_dbitlist): # bits enabled but not plotting waveform = digital_array[idx, :] if np.isnan(waveform[0]): diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt index 543ff7467..9e6ad75c3 100755 --- a/slsReceiverSoftware/CMakeLists.txt +++ b/slsReceiverSoftware/CMakeLists.txt @@ -17,6 +17,7 @@ set(SOURCES set(PUBLICHEADERS include/sls/Receiver.h + include/sls/utils.h ) # HDF5 file writing diff --git a/slsReceiverSoftware/include/sls/utils.h b/slsReceiverSoftware/include/sls/utils.h new file mode 100644 index 000000000..3aa76456c --- /dev/null +++ b/slsReceiverSoftware/include/sls/utils.h @@ -0,0 +1,36 @@ +/** + * @file utils.cpp + * @short utility objects for Receiver + */ + +#include +#include + +namespace sls { + +/* + * AlignedData + * Aligns data to a given type T with proper alignment + * @param data: pointer to data + * @param size: size of data to align in bytes + */ +template struct AlignedData { + T *aligned_ptr; // aligned data pointer + + AlignedData(char *data, size_t size) { + if (reinterpret_cast(data) % alignof(uint64_t) == 0) { + // If aligned directly cast to pointer + aligned_ptr = reinterpret_cast(data); + + } else { + + auto alignedbuffer = std::aligned_alloc(alignof(T), size); + std::memcpy(alignedbuffer, data, size); + aligned_ptr = reinterpret_cast(alignedbuffer); + } + } + + ~AlignedData() { std::free(aligned_ptr); } +}; + +} // namespace sls \ No newline at end of file diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index b96f5042a..6a16284dd 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -24,51 +24,10 @@ #include #include +#include "sls/utils.h" + namespace sls { -// TODO: move somewhere else -template struct AlignedData { - T *ptr; // Aligned data pointer - std::unique_ptr[]> buffer; - - AlignedData( - T *p, - std::unique_ptr[]> buf) - : ptr(p), buffer(std::move(buf)) {} -}; - -// TODO: should not be in this file any suggestions to move it to a more -// appropriate file? -// TODO: Add unit test -/* - * AlignData - * Aligns data to a given type T with proper alignment - * @param data: pointer to data - * @param size: size of data to align in bytes - * @return: aligned data - */ -template -void AlignData(AlignedData &aligneddata, char *data, size_t size) { - using AlignedBuffer = - typename std::aligned_storage::type; - std::unique_ptr tempbuffer; - - if (reinterpret_cast(data) % alignof(uint64_t) == 0) { - // If aligned directly cast to pointer - - aligneddata.ptr = reinterpret_cast(data); - - } else { - // Allocate a temporary buffer with proper alignment - tempbuffer = std::make_unique(size / sizeof(T)); - // size = ctbDigitaldbt; - - std::memcpy(tempbuffer.get(), data, size); - aligneddata.buffer = std::move(tempbuffer); - aligneddata.ptr = reinterpret_cast(aligneddata.buffer.get()); - } -} - const std::string DataProcessor::typeName = "DataProcessor"; DataProcessor::DataProcessor(int index) : ThreadObject(index, typeName) { @@ -617,11 +576,10 @@ void DataProcessor::Reorder(size_t &size, char *data) { } // make sure data is aligned to 8 bytes before casting to uint64_t - AlignedData aligned_data(nullptr, nullptr); - AlignData(aligned_data, data + nAnalogDataBytes + ctbDbitOffset, - ctbDigitalDataBytes); + AlignedData aligned_data(data + nAnalogDataBytes + ctbDbitOffset, + ctbDigitalDataBytes); - uint64_t *source = aligned_data.ptr; + uint64_t *source = aligned_data.aligned_ptr; const size_t numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); @@ -694,13 +652,11 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { return; } - AlignedData aligned_data(nullptr, nullptr); - AlignData(aligned_data, data + nAnalogDataBytes + ctbDbitOffset, - ctbDigitalDataBytes); + // make sure data is aligned to 8 bytes before casting to uint64_t + AlignedData aligned_data(data + nAnalogDataBytes + ctbDbitOffset, + ctbDigitalDataBytes); - uint64_t *source = aligned_data.ptr; - - // auto *source = (uint64_t *)(data + nAnalogDataBytes + ctbDbitOffset); + uint64_t *source = aligned_data.aligned_ptr; const int numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); From 29fe988583d23fce8acf630c3bcd4ee366770735 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Wed, 9 Apr 2025 09:31:38 +0200 Subject: [PATCH 24/38] imagedata is now allocated on the heap --- .../ctbDetectorServer/slsDetectorFunctionList.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index f1f33cb84..8e32f3b63 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -15,6 +15,7 @@ #include "loadPattern.h" #include +#include #include #include // usleep #ifdef VIRTUAL @@ -2258,8 +2259,9 @@ void *start_timer(void *arg) { int packetsPerFrame = ceil((double)imageSize / (double)dataSize); // Generate Data - char imageData[imageSize]; // + char *imageData = (char *)malloc(imageSize); memset(imageData, 0, imageSize); + /* for (int i = 0; i < imageSize; i += sizeof(uint16_t)) { *((uint16_t *)(imageData + i)) = i; @@ -2325,6 +2327,8 @@ void *start_timer(void *arg) { setNextFrameNumber(frameNr + numFrames); } + free(imageData); + closeUDPSocket(0); sharedMemory_setStatus(IDLE); From a138b5b3650dd1cb86c2b15bdb4cbe9378b32e9e Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 9 Apr 2025 17:52:23 +0200 Subject: [PATCH 25/38] m3 server fix for trimbits and badchannels that are shifted by 1 --- slsDetectorServers/mythen3DetectorServer/mythen3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsDetectorServers/mythen3DetectorServer/mythen3.c b/slsDetectorServers/mythen3DetectorServer/mythen3.c index f4dc01871..a03fd736d 100644 --- a/slsDetectorServers/mythen3DetectorServer/mythen3.c +++ b/slsDetectorServers/mythen3DetectorServer/mythen3.c @@ -304,7 +304,7 @@ patternParameters *setChannelRegisterChip(int ichip, char *mask, chanReg |= (0x1 << (3 + icounter)); } } - + chanReg /= 2; // deserialize if (chanReg & CHAN_REG_BAD_CHANNEL_MSK) { LOG(logINFOBLUE, From f8b12201f861327c6ff651c57ba2dcafeddfde29 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 9 Apr 2025 18:21:54 +0200 Subject: [PATCH 26/38] binary in --- .../bin/mythen3DetectorServer_developer | Bin 305788 -> 305788 bytes slsSupportLib/include/sls/versionAPI.h | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 0ac0007c5d0c7bf4e7e220c11c1e77fbf4094157..bc4c3055261aeeb31032107294784e2efff275e8 100755 GIT binary patch delta 19030 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 diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index f37cd7b42..b9a1d824d 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -5,8 +5,8 @@ #define APIRECEIVER "developer 0x241122" #define APICTB "developer 0x250310" #define APIGOTTHARD2 "developer 0x250310" -#define APIMYTHEN3 "developer 0x250310" #define APIMOENCH "developer 0x250310" #define APIEIGER "developer 0x250310" #define APIXILINXCTB "developer 0x250311" #define APIJUNGFRAU "developer 0x250318" +#define APIMYTHEN3 "developer 0x250409" From f119d14e7c0dc1e809e7894744e0ee72d7e17a5b Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Thu, 10 Apr 2025 11:29:01 +0200 Subject: [PATCH 27/38] added check for proper memory allocation --- .../ctbDetectorServer/slsDetectorFunctionList.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 8e32f3b63..83d7a111c 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -2262,6 +2262,11 @@ void *start_timer(void *arg) { char *imageData = (char *)malloc(imageSize); memset(imageData, 0, imageSize); + if (imageData == NULL) { + LOG(logERROR, ("Can not allocate image Data RAM." + "Probable cause: Memory Leak.\n")); + return FAIL; + } /* for (int i = 0; i < imageSize; i += sizeof(uint16_t)) { *((uint16_t *)(imageData + i)) = i; From 361437428dc7110cfa26f301ae0f7f452b55483e Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 10 Apr 2025 13:11:16 +0200 Subject: [PATCH 28/38] commenting out the example in receiver data call back changing size as it affects users using debugging mode to print out headers --- slsReceiverSoftware/src/MultiReceiverApp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/slsReceiverSoftware/src/MultiReceiverApp.cpp b/slsReceiverSoftware/src/MultiReceiverApp.cpp index 061c9a441..e66e8a90c 100644 --- a/slsReceiverSoftware/src/MultiReceiverApp.cpp +++ b/slsReceiverSoftware/src/MultiReceiverApp.cpp @@ -146,8 +146,9 @@ void GetData(slsDetectorDefs::sls_receiver_header &header, // header->packetsMask.to_string().c_str(), ((uint8_t)(*((uint8_t *)(dataPointer)))), imageSize); - // if data is modified, eg ROI and size is reduced - imageSize = 26000; + // if data is modified, can affect size + // only reduction in size allowed, not increase + // imageSize = 26000; } /** From 721d5363501832b2ec82158d50d90d1bba9e1cd5 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Thu, 10 Apr 2025 13:31:47 +0200 Subject: [PATCH 29/38] fixed warnings --- slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 83d7a111c..d7f9e4f56 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -2265,7 +2265,7 @@ void *start_timer(void *arg) { if (imageData == NULL) { LOG(logERROR, ("Can not allocate image Data RAM." "Probable cause: Memory Leak.\n")); - return FAIL; + return NULL; } /* for (int i = 0; i < imageSize; i += sizeof(uint16_t)) { From 7c652498e4a93fbc9b4d8cfb5d349718ad314710 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Thu, 10 Apr 2025 17:34:39 +0200 Subject: [PATCH 30/38] got rid of cast to uint64 --- slsReceiverSoftware/CMakeLists.txt | 1 - slsReceiverSoftware/include/sls/utils.h | 36 ----------------------- slsReceiverSoftware/src/DataProcessor.cpp | 29 +++++++++--------- 3 files changed, 15 insertions(+), 51 deletions(-) delete mode 100644 slsReceiverSoftware/include/sls/utils.h diff --git a/slsReceiverSoftware/CMakeLists.txt b/slsReceiverSoftware/CMakeLists.txt index 9e6ad75c3..543ff7467 100755 --- a/slsReceiverSoftware/CMakeLists.txt +++ b/slsReceiverSoftware/CMakeLists.txt @@ -17,7 +17,6 @@ set(SOURCES set(PUBLICHEADERS include/sls/Receiver.h - include/sls/utils.h ) # HDF5 file writing diff --git a/slsReceiverSoftware/include/sls/utils.h b/slsReceiverSoftware/include/sls/utils.h deleted file mode 100644 index 3aa76456c..000000000 --- a/slsReceiverSoftware/include/sls/utils.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file utils.cpp - * @short utility objects for Receiver - */ - -#include -#include - -namespace sls { - -/* - * AlignedData - * Aligns data to a given type T with proper alignment - * @param data: pointer to data - * @param size: size of data to align in bytes - */ -template struct AlignedData { - T *aligned_ptr; // aligned data pointer - - AlignedData(char *data, size_t size) { - if (reinterpret_cast(data) % alignof(uint64_t) == 0) { - // If aligned directly cast to pointer - aligned_ptr = reinterpret_cast(data); - - } else { - - auto alignedbuffer = std::aligned_alloc(alignof(T), size); - std::memcpy(alignedbuffer, data, size); - aligned_ptr = reinterpret_cast(alignedbuffer); - } - } - - ~AlignedData() { std::free(aligned_ptr); } -}; - -} // namespace sls \ No newline at end of file diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 6a16284dd..6870442a1 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -24,8 +24,6 @@ #include #include -#include "sls/utils.h" - namespace sls { const std::string DataProcessor::typeName = "DataProcessor"; @@ -576,10 +574,11 @@ void DataProcessor::Reorder(size_t &size, char *data) { } // make sure data is aligned to 8 bytes before casting to uint64_t - AlignedData aligned_data(data + nAnalogDataBytes + ctbDbitOffset, - ctbDigitalDataBytes); + // AlignedData aligned_data(data + nAnalogDataBytes + + // ctbDbitOffset, ctbDigitalDataBytes); - uint64_t *source = aligned_data.aligned_ptr; + char *source = + data + nAnalogDataBytes + ctbDbitOffset; // aligned_data.aligned_ptr; const size_t numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); @@ -652,11 +651,7 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { return; } - // make sure data is aligned to 8 bytes before casting to uint64_t - AlignedData aligned_data(data + nAnalogDataBytes + ctbDbitOffset, - ctbDigitalDataBytes); - - uint64_t *source = aligned_data.aligned_ptr; + char *source = (data + nAnalogDataBytes + ctbDbitOffset); const int numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); @@ -694,10 +689,13 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { ++dest; } + uint8_t byte_index = bi / 8; + // loop through the frame digital data - for (auto *ptr = source; ptr < (source + numDigitalSamples);) { + for (auto *ptr = source + byte_index; + ptr < (source + 8 * numDigitalSamples); ptr += 8) { // get selected bit from each 8 bit - uint8_t bit = (*ptr++ >> bi) & 1; + uint8_t bit = (*ptr >> bi % 8) & 1; *dest |= bit << bitoffset; // stored as least significant ++bitoffset; // extract destination in 8 bit batches @@ -710,7 +708,8 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { } else { // loop through the digital data int bitoffset = 0; - for (auto *ptr = source; ptr < (source + numDigitalSamples); ++ptr) { + for (auto *ptr = source; ptr < (source + 8 * numDigitalSamples); + ptr += 8) { // where bit enable vector size is not a multiple of 8 if (bitoffset != 0) { bitoffset = 0; @@ -720,7 +719,9 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { // loop through digital bit enable vector for (auto bi : ctbDbitList) { // get selected bit from each 64 bit - uint8_t bit = (*ptr >> bi) & 1; + uint8_t byte_index = bi / 8; + + uint8_t bit = (*(ptr + byte_index) >> (bi % 8)) & 1; *dest |= bit << bitoffset; ++bitoffset; // extract destination in 8 bit batches From 5be0724f821d6cc8473496aacf2c69116edeaf53 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Thu, 10 Apr 2025 17:52:16 +0200 Subject: [PATCH 31/38] got rid of Reorder function --- slsReceiverSoftware/src/DataProcessor.cpp | 82 +------------------ slsReceiverSoftware/src/DataProcessor.h | 8 +- .../tests/test-ArrangeDataBasedOnBitList.cpp | 18 ++-- 3 files changed, 15 insertions(+), 93 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 6870442a1..b70199672 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace sls { @@ -362,7 +363,9 @@ void DataProcessor::ProcessAnImage(sls_receiver_header &header, size_t &size, if (!ctbDbitList.empty()) { ArrangeDbitData(size, data); } else if (ctbDbitReorder) { - Reorder(size, data); + ctbDbitList.resize(64); + std::iota(ctbDbitList.begin(), ctbDbitList.end(), 0); + ArrangeDbitData(size, data); } else if (ctbDbitOffset > 0) { RemoveTrailingBits(size, data); } @@ -558,83 +561,6 @@ void DataProcessor::RemoveTrailingBits(size_t &size, char *data) { size = nAnalogDataBytes + ctbDigitalDataBytes + nTransceiverDataBytes; } -void DataProcessor::Reorder(size_t &size, char *data) { - const size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); - const size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); - const size_t nTransceiverDataBytes = - generalData->GetNumberOfTransceiverDatabytes(); - - const size_t ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset; - - // no digital data - if (ctbDigitalDataBytes == 0) { - LOG(logWARNING) - << "No digital data for call back, yet reorder is set to 1."; - return; - } - - // make sure data is aligned to 8 bytes before casting to uint64_t - // AlignedData aligned_data(data + nAnalogDataBytes + - // ctbDbitOffset, ctbDigitalDataBytes); - - char *source = - data + nAnalogDataBytes + ctbDbitOffset; // aligned_data.aligned_ptr; - - const size_t numDigitalSamples = (ctbDigitalDataBytes / sizeof(uint64_t)); - - size_t numBytesPerBit = - (numDigitalSamples % 8 == 0) - ? numDigitalSamples / 8 - : numDigitalSamples / 8 + - 1; // number of bytes per bit in digital data after reordering - - size_t totalNumBytes = - numBytesPerBit * - 64; // number of bytes for digital data after reordering - - std::vector result(totalNumBytes, 0); - uint8_t *dest = &result[0]; - - int bitoffset = 0; - // reorder - for (size_t bi = 0; bi < 64; ++bi) { - - if (bitoffset != 0) { - bitoffset = 0; - ++dest; - } - - for (auto *ptr = source; ptr < (source + numDigitalSamples); ++ptr) { - uint8_t bit = (*ptr >> bi) & 1; - *dest |= bit << bitoffset; // most significant bits will be padded - ++bitoffset; - if (bitoffset == 8) { - bitoffset = 0; - ++dest; - } - } - } - - // move transceiver data to not overwrite and avoid gap in memory - if (totalNumBytes != nDigitalDataBytes) - memmove(data + nAnalogDataBytes + totalNumBytes * sizeof(uint8_t), - data + nAnalogDataBytes + nDigitalDataBytes, - nTransceiverDataBytes); - - // copy back to memory and update size - size = totalNumBytes * sizeof(uint8_t) + nAnalogDataBytes + - nTransceiverDataBytes; - - memcpy(data + nAnalogDataBytes, result.data(), - totalNumBytes * sizeof(uint8_t)); - - LOG(logDEBUG1) << "totalNumBytes: " << totalNumBytes - << " nAnalogDataBytes:" << nAnalogDataBytes - << " ctbDbitOffset:" << ctbDbitOffset - << " nTransceiverDataBytes:" << nTransceiverDataBytes - << " size:" << size; -} - /** ctb specific */ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 6e70072cd..6d66646e8 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -101,12 +101,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { */ void ArrangeDbitData(size_t &size, char *data); - /** - * reorder datastream such that each signal (0-63) from all the different - * samples are grouped together and stored consecutively in memory - */ - void Reorder(size_t &size, char *data); - /** * remove trailing bits in digital data stream */ @@ -179,7 +173,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { uint32_t currentFreqCount{0}; struct timespec timerbegin{}; bool framePadding; - std::vector ctbDbitList; + std::vector ctbDbitList{}; int ctbDbitOffset{0}; bool ctbDbitReorder{true}; std::atomic startedFlag{false}; diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index af75c3b54..a2909db25 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -39,16 +39,12 @@ class GeneralDataTest : public GeneralData { // dummy DataProcessor class for testing class DataProcessorTest : public DataProcessor { public: - DataProcessorTest() : DataProcessor(0){}; - ~DataProcessorTest(){}; + DataProcessorTest() : DataProcessor(0) {}; + ~DataProcessorTest() {}; void ArrangeDbitData(size_t &size, char *data) { DataProcessor::ArrangeDbitData(size, data); } - void Reorder(size_t &size, char *data) { - DataProcessor::Reorder(size, data); - } - void RemoveTrailingBits(size_t &size, char *data) { DataProcessor::RemoveTrailingBits(size, data); } @@ -183,6 +179,9 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Reorder all", set_num_samples(num_samples); set_data(); + std::vector bitlist(64); + std::iota(bitlist.begin(), bitlist.end(), 0); + dataprocessor->SetCtbDbitList(bitlist); dataprocessor->SetCtbDbitReorder(true); // set reorder to true const size_t expected_size = @@ -202,7 +201,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Reorder all", num_transceiver_bytes); // set to 125 size_t size = get_size(); - dataprocessor->Reorder(size, data); // call reorder + dataprocessor->ArrangeDbitData(size, data); // call reorder CHECK(size == expected_size); CHECK(memcmp(data, expected_data, expected_size) == 0); @@ -219,6 +218,9 @@ TEST_CASE_METHOD(DataProcessorTestFixture, set_random_offset_bytes(num_random_offset_bytes); set_data(); + std::vector bitlist(64); + std::iota(bitlist.begin(), bitlist.end(), 0); + dataprocessor->SetCtbDbitList(bitlist); dataprocessor->SetCtbDbitOffset(num_random_offset_bytes); dataprocessor->SetCtbDbitReorder(true); // set reorder to true @@ -242,7 +244,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, num_transceiver_bytes); // set to 125 size_t size = get_size(); - dataprocessor->Reorder(size, data); // call reorder + dataprocessor->ArrangeDbitData(size, data); // call reorder CHECK(size == expected_size); CHECK(memcmp(data, expected_data, expected_size) == 0); From 4c86ad3198142db144de8ea70e408a2587754c6a Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Fri, 11 Apr 2025 10:27:26 +0200 Subject: [PATCH 32/38] added sanity check to only enable for chipttestboard and xilinx --- slsReceiverSoftware/src/DataProcessor.cpp | 15 +++++++++++++++ .../tests/test-ArrangeDataBasedOnBitList.cpp | 2 ++ 2 files changed, 17 insertions(+) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index b70199672..7a69e3f41 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -336,6 +336,7 @@ void DataProcessor::StopProcessing(char *buf) { void DataProcessor::ProcessAnImage(sls_receiver_header &header, size_t &size, size_t &firstImageIndex, char *data) { + uint64_t fnum = header.detHeader.frameNumber; LOG(logDEBUG1) << "DataProcessing " << index << ": fnum:" << fnum; currentFrameIndex = fnum; @@ -540,6 +541,13 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) { } void DataProcessor::RemoveTrailingBits(size_t &size, char *data) { + + if (!(generalData->detType == slsDetectorDefs::CHIPTESTBOARD || + generalData->detType == slsDetectorDefs::XILINX_CHIPTESTBOARD)) { + throw std::runtime_error("behavior undefined for detector " + + std::to_string(generalData->detType)); + } + const size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); const size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); const size_t nTransceiverDataBytes = @@ -563,6 +571,13 @@ void DataProcessor::RemoveTrailingBits(size_t &size, char *data) { /** ctb specific */ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { + + if (!(generalData->detType == slsDetectorDefs::CHIPTESTBOARD || + generalData->detType == slsDetectorDefs::XILINX_CHIPTESTBOARD)) { + throw std::runtime_error("behavior undefined for detector " + + std::to_string(generalData->detType)); + } + size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); size_t nTransceiverDataBytes = diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index a2909db25..0b5ef3bd0 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -16,6 +16,8 @@ namespace sls { class GeneralDataTest : public GeneralData { public: + GeneralDataTest() { detType = slsDetectorDefs::CHIPTESTBOARD; } + int GetNumberOfAnalogDatabytes() { return nAnalogBytes; }; int GetNumberOfDigitalDatabytes() { return nDigitalBytes; }; From f9bc2eb1269872e8c4cd380d1290304be65e92d6 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Fri, 11 Apr 2025 10:32:31 +0200 Subject: [PATCH 33/38] removed Gotthard stuff --- slsReceiverSoftware/src/DataProcessor.cpp | 10 ---------- slsReceiverSoftware/src/GeneralData.h | 4 ++-- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 7a69e3f41..1956d3578 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -515,16 +515,6 @@ void DataProcessor::PadMissingPackets(sls_receiver_header header, char *data) { // missing packet switch (generalData->detType) { - // for gotthard, 1st packet: 4 bytes fnum, CACA + CACA, 639*2 bytes - // data - // 2nd packet: 4 bytes fnum, previous 1*2 bytes data + - // 640*2 bytes data !! - case GOTTHARD: - if (pnum == 0u) - memset(data + (pnum * dsize), 0xFF, dsize - 2); - else - memset(data + (pnum * dsize), 0xFF, dsize + 2); - break; case CHIPTESTBOARD: case XILINX_CHIPTESTBOARD: if (pnum == (pperFrame - 1)) diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index 9f3b43429..6d9a5d626 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -60,8 +60,8 @@ class GeneralData { slsDetectorDefs::frameDiscardPolicy frameDiscardMode{ slsDetectorDefs::NO_DISCARD}; - GeneralData(){}; - virtual ~GeneralData(){}; + GeneralData() {}; + virtual ~GeneralData() {}; // Returns the pixel depth in byte, 4 bits being 0.5 byte float GetPixelDepth() { return float(dynamicRange) / 8; } From 01cc745787e7336693d62430f650d395ebd47ba0 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Fri, 11 Apr 2025 10:30:28 +0200 Subject: [PATCH 34/38] update the comment about how to modify data on a data call back from the receiver --- slsReceiverSoftware/src/MultiReceiverApp.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/slsReceiverSoftware/src/MultiReceiverApp.cpp b/slsReceiverSoftware/src/MultiReceiverApp.cpp index e66e8a90c..44284281c 100644 --- a/slsReceiverSoftware/src/MultiReceiverApp.cpp +++ b/slsReceiverSoftware/src/MultiReceiverApp.cpp @@ -146,9 +146,21 @@ void GetData(slsDetectorDefs::sls_receiver_header &header, // header->packetsMask.to_string().c_str(), ((uint8_t)(*((uint8_t *)(dataPointer)))), imageSize); - // if data is modified, can affect size - // only reduction in size allowed, not increase - // imageSize = 26000; + // // example of how to use roi or modify data that is later written to file + // slsDetectorDefs::ROI roi{0, 10, 0, 20}; + // int width = roi.xmax - roi.xmin; + // int height = roi.ymax - roi.ymin; + // uint8_t *destPtr = (uint8_t *)dataPointer; + // for (int irow = roi.ymin; irow < roi.ymax; ++irow) { + // memcpy(destPtr, + // ((uint8_t *)(dataPointer + irow * callbackHeader.shape.x + + // roi.xmin)), + // width); + // destPtr += width; + // } + // memcpy((uint8_t*)dataPointer, (uint8_t*)dataPointer + // // setting roi for eg. changes size + // imageSize = width * height; } /** From 9d8f9a9ba92a7e407a71b437f2a58e6d1708664a Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Fri, 11 Apr 2025 10:45:02 +0200 Subject: [PATCH 35/38] autogenerated commands and make format --- slsDetectorGui/include/qDefs.h | 2 +- .../slsDetectorServer_defs.h | 8 +++----- .../eigerDetectorServer/FebControl.c | 6 +++--- .../slsDetectorServer_defs.h | 3 +-- .../slsDetectorServer_defs.h | 3 +-- .../slsDetectorServer_defs.h | 20 ++++++++----------- .../slsDetectorServer_defs.h | 8 +++----- .../slsDetectorServer_defs.h | 18 +++++++---------- .../generator/extended_commands.yaml | 7 ++++--- slsDetectorSoftware/include/sls/Result.h | 2 +- .../include/sls/detectorData.h | 6 +++--- slsReceiverSoftware/src/DataProcessor.h | 2 +- slsReceiverSoftware/src/File.h | 4 ++-- slsSupportLib/include/sls/ClientSocket.h | 12 +++++------ slsSupportLib/include/sls/Timer.h | 2 +- slsSupportLib/include/sls/logger.h | 2 +- slsSupportLib/include/sls/sls_detector_defs.h | 6 +++--- slsSupportLib/src/ZmqSocket.cpp | 2 +- 18 files changed, 50 insertions(+), 63 deletions(-) diff --git a/slsDetectorGui/include/qDefs.h b/slsDetectorGui/include/qDefs.h index 375d62d6c..018790c46 100644 --- a/slsDetectorGui/include/qDefs.h +++ b/slsDetectorGui/include/qDefs.h @@ -39,7 +39,7 @@ class qDefs : public QWidget { /** * Empty Constructor */ - qDefs(){}; + qDefs() {}; static QFont GetDefaultFont() { return QFont("Cantarell", 10, QFont::Normal); diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h index 683338861..103502f1f 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h @@ -7,11 +7,9 @@ #define MIN_REQRD_VRSN_T_RD_API 0x181130 #define REQRD_FRMWR_VRSN 0x230705 -#define NUM_HARDWARE_VERSIONS (1) -#define HARDWARE_VERSION_NUMBERS \ - { 0x3f } -#define HARDWARE_VERSION_NAMES \ - { "5.1" } +#define NUM_HARDWARE_VERSIONS (1) +#define HARDWARE_VERSION_NUMBERS {0x3f} +#define HARDWARE_VERSION_NAMES {"5.1"} #define LINKED_SERVER_NAME "ctbDetectorServer" diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.c b/slsDetectorServers/eigerDetectorServer/FebControl.c index f0b96d487..d3750259a 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.c +++ b/slsDetectorServers/eigerDetectorServer/FebControl.c @@ -634,8 +634,8 @@ int Feb_Control_SetTrimbits(unsigned int *trimbits, int top) { << ((7 - i) * 4); // upper } } // end column loop i - } // end supercolumn loop sc - } // end row loop + } // end supercolumn loop sc + } // end row loop if (Feb_Control_activated) { if (!Feb_Interface_WriteMemoryInLoops(Feb_Control_leftAddress, @@ -652,7 +652,7 @@ int Feb_Control_SetTrimbits(unsigned int *trimbits, int top) { } } // end row_set loop (groups of 16 rows) - } // end l_r loop + } // end l_r loop memcpy(Feb_Control_last_downloaded_trimbits, trimbits, Feb_Control_trimbit_size * sizeof(unsigned int)); diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h index 5e4a62f1b..aa87505b3 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h @@ -7,8 +7,7 @@ #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS {0x0, 0x1}; -#define HARDWARE_VERSION_NAMES \ - { "FX70T", "FX30T" } +#define HARDWARE_VERSION_NAMES {"FX70T", "FX30T"} #define REQUIRED_FIRMWARE_VERSION (32) // virtual ones renamed for consistency diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index d275cb400..a696221c9 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -9,8 +9,7 @@ #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS {0x0, 0x2}; -#define HARDWARE_VERSION_NAMES \ - { "1.0", "1.2" } +#define HARDWARE_VERSION_NAMES {"1.0", "1.2"} #define LINKED_SERVER_NAME "gotthard2DetectorServer" diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h index cc2b0928b..88e30f1c4 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h @@ -8,11 +8,9 @@ #define REQRD_FRMWRE_VRSN_BOARD2 0x250209 // 1.0 pcb (version = 010) #define REQRD_FRMWRE_VRSN 0x250208 // 2.0 pcb (version = 011) -#define NUM_HARDWARE_VERSIONS (2) -#define HARDWARE_VERSION_NUMBERS \ - { 0x2, 0x3 } -#define HARDWARE_VERSION_NAMES \ - { "1.0", "2.0" } +#define NUM_HARDWARE_VERSIONS (2) +#define HARDWARE_VERSION_NUMBERS {0x2, 0x3} +#define HARDWARE_VERSION_NAMES {"1.0", "2.0"} #define ID_FILE "detid_jungfrau.txt" #define LINKED_SERVER_NAME "jungfrauDetectorServer" @@ -214,13 +212,11 @@ enum DACINDEX { enum MASTERINDEX { MASTER_HARDWARE, OW_MASTER, OW_SLAVE }; #define MASTER_NAMES "hardware", "master", "slave" -#define NUMSETTINGS (2) -#define NSPECIALDACS (3) -#define SPECIALDACINDEX {J_VREF_PRECH, J_VREF_DS, J_VREF_COMP}; -#define SPECIAL_DEFAULT_DYNAMIC_GAIN_VALS \ - { 1450, 480, 420 } -#define SPECIAL_DEFAULT_DYNAMICHG0_GAIN_VALS \ - { 1550, 450, 620 } +#define NUMSETTINGS (2) +#define NSPECIALDACS (3) +#define SPECIALDACINDEX {J_VREF_PRECH, J_VREF_DS, J_VREF_COMP}; +#define SPECIAL_DEFAULT_DYNAMIC_GAIN_VALS {1450, 480, 420} +#define SPECIAL_DEFAULT_DYNAMICHG0_GAIN_VALS {1550, 450, 620} enum NETWORKINDEX { TXN_FRAME, FLOWCTRL_10G }; enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS }; diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/moenchDetectorServer/slsDetectorServer_defs.h index aa4133d7a..22d8e68ba 100644 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorServer_defs.h @@ -7,11 +7,9 @@ #define REQRD_FRMWRE_VRSN_BOARD2 0x444445 // 1.0 pcb (version = 010) #define REQRD_FRMWRE_VRSN 0x231026 // 2.0 pcb (version = 011) -#define NUM_HARDWARE_VERSIONS (2) -#define HARDWARE_VERSION_NUMBERS \ - { 0x2, 0x3 } -#define HARDWARE_VERSION_NAMES \ - { "1.0", "2.0" } +#define NUM_HARDWARE_VERSIONS (2) +#define HARDWARE_VERSION_NUMBERS {0x2, 0x3} +#define HARDWARE_VERSION_NAMES {"1.0", "2.0"} #define ID_FILE ("detid_moench.txt") #define LINKED_SERVER_NAME "moenchDetectorServer" diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h index b0d8c1ea5..80abbd126 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h @@ -9,8 +9,7 @@ #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS {0x0, 0x2}; -#define HARDWARE_VERSION_NAMES \ - { "1.0", "1.2" } +#define HARDWARE_VERSION_NAMES {"1.0", "1.2"} #define LINKED_SERVER_NAME "mythen3DetectorServer" @@ -130,15 +129,12 @@ enum DACINDEX { enum ADCINDEX { TEMP_FPGA }; -#define NUMSETTINGS (3) -#define NSPECIALDACS (2) -#define SPECIALDACINDEX {M_VRPREAMP, M_VRSHAPER}; -#define SPECIAL_DEFAULT_STANDARD_DAC_VALS \ - { 1100, 1280 } -#define SPECIAL_DEFAULT_FAST_DAC_VALS \ - { 300, 1500 } -#define SPECIAL_DEFAULT_HIGHGAIN_DAC_VALS \ - { 1300, 1100 } +#define NUMSETTINGS (3) +#define NSPECIALDACS (2) +#define SPECIALDACINDEX {M_VRPREAMP, M_VRSHAPER}; +#define SPECIAL_DEFAULT_STANDARD_DAC_VALS {1100, 1280} +#define SPECIAL_DEFAULT_FAST_DAC_VALS {300, 1500} +#define SPECIAL_DEFAULT_HIGHGAIN_DAC_VALS {1300, 1100} enum CLKINDEX { SYSTEM_C0, SYSTEM_C1, SYSTEM_C2, NUM_CLOCKS }; #define NUM_CLOCKS_TO_SET (1) diff --git a/slsDetectorSoftware/generator/extended_commands.yaml b/slsDetectorSoftware/generator/extended_commands.yaml index 4e4b52a72..6b9f72577 100644 --- a/slsDetectorSoftware/generator/extended_commands.yaml +++ b/slsDetectorSoftware/generator/extended_commands.yaml @@ -8341,9 +8341,10 @@ rx_dbitreorder: store_result_in_t: false command_name: rx_dbitreorder function_alias: rx_dbitreorder - help: "[0, 1]\n\t[Ctb] Reorder digital data to group together all samples per signal.\ - \ Default is 1. Setting to 0 means 'do not reorder' and to keep what the board\ - \ spits out, which is that all signals in a sample are grouped together." + help: "[0, 1]\n\t[Ctb] Reorder digital data such that it groups each signal (0-63)\ + \ from all the different samples together . Default is 1. Setting to 0 means 'do\ + \ not reorder' and to keep what the board spits out, which is that all signals\ + \ in a sample are grouped together." infer_action: true template: true rx_discardpolicy: diff --git a/slsDetectorSoftware/include/sls/Result.h b/slsDetectorSoftware/include/sls/Result.h index 0cb937408..479eae047 100644 --- a/slsDetectorSoftware/include/sls/Result.h +++ b/slsDetectorSoftware/include/sls/Result.h @@ -32,7 +32,7 @@ template > class Result { public: Result() = default; - Result(std::initializer_list list) : vec(list){}; + Result(std::initializer_list list) : vec(list) {}; /** Custom constructor from integer type to Result or Result */ template ctbDbitList{}; int ctbDbitOffset{0}; diff --git a/slsReceiverSoftware/src/File.h b/slsReceiverSoftware/src/File.h index c30a86238..70a3de224 100644 --- a/slsReceiverSoftware/src/File.h +++ b/slsReceiverSoftware/src/File.h @@ -16,8 +16,8 @@ namespace sls { class File : private virtual slsDetectorDefs { public: - File(){}; - virtual ~File(){}; + File() {}; + virtual ~File() {}; virtual fileFormat GetFileFormat() const = 0; virtual void CloseFile() = 0; diff --git a/slsSupportLib/include/sls/ClientSocket.h b/slsSupportLib/include/sls/ClientSocket.h index dcfc02b25..607f1f507 100644 --- a/slsSupportLib/include/sls/ClientSocket.h +++ b/slsSupportLib/include/sls/ClientSocket.h @@ -28,22 +28,22 @@ class ClientSocket : public DataSocket { class ReceiverSocket : public ClientSocket { public: ReceiverSocket(const std::string &hostname, uint16_t port_number) - : ClientSocket("Receiver", hostname, port_number){}; - ReceiverSocket(struct sockaddr_in addr) : ClientSocket("Receiver", addr){}; + : ClientSocket("Receiver", hostname, port_number) {}; + ReceiverSocket(struct sockaddr_in addr) : ClientSocket("Receiver", addr) {}; }; class DetectorSocket : public ClientSocket { public: DetectorSocket(const std::string &hostname, uint16_t port_number) - : ClientSocket("Detector", hostname, port_number){}; - DetectorSocket(struct sockaddr_in addr) : ClientSocket("Detector", addr){}; + : ClientSocket("Detector", hostname, port_number) {}; + DetectorSocket(struct sockaddr_in addr) : ClientSocket("Detector", addr) {}; }; class GuiSocket : public ClientSocket { public: GuiSocket(const std::string &hostname, uint16_t port_number) - : ClientSocket("Gui", hostname, port_number){}; - GuiSocket(struct sockaddr_in addr) : ClientSocket("Gui", addr){}; + : ClientSocket("Gui", hostname, port_number) {}; + GuiSocket(struct sockaddr_in addr) : ClientSocket("Gui", addr) {}; }; }; // namespace sls diff --git a/slsSupportLib/include/sls/Timer.h b/slsSupportLib/include/sls/Timer.h index b22909b33..7409bb8fe 100644 --- a/slsSupportLib/include/sls/Timer.h +++ b/slsSupportLib/include/sls/Timer.h @@ -33,5 +33,5 @@ class Timer { std::string name_; }; -}; // namespace sls +}; // namespace sls #endif // TIMER_H diff --git a/slsSupportLib/include/sls/logger.h b/slsSupportLib/include/sls/logger.h index 9b949d802..2f94c28dc 100644 --- a/slsSupportLib/include/sls/logger.h +++ b/slsSupportLib/include/sls/logger.h @@ -47,7 +47,7 @@ class Logger { public: Logger() = default; - explicit Logger(TLogLevel level) : level(level){}; + explicit Logger(TLogLevel level) : level(level) {}; ~Logger() { // output in the destructor to allow for << syntax os << RESET << '\n'; diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index 9a010ba4c..1fe0d9617 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -125,7 +125,7 @@ class slsDetectorDefs { int x{0}; int y{0}; xy() = default; - xy(int x, int y) : x(x), y(y){}; + xy(int x, int y) : x(x), y(y) {}; } __attribute__((packed)); #endif @@ -227,9 +227,9 @@ class slsDetectorDefs { int ymin{-1}; int ymax{-1}; ROI() = default; - ROI(int xmin, int xmax) : xmin(xmin), xmax(xmax){}; + ROI(int xmin, int xmax) : xmin(xmin), xmax(xmax) {}; ROI(int xmin, int xmax, int ymin, int ymax) - : xmin(xmin), xmax(xmax), ymin(ymin), ymax(ymax){}; + : xmin(xmin), xmax(xmax), ymin(ymin), ymax(ymax) {}; constexpr std::array getIntArray() const { return std::array({xmin, xmax, ymin, ymax}); } diff --git a/slsSupportLib/src/ZmqSocket.cpp b/slsSupportLib/src/ZmqSocket.cpp index 2fafe4799..eed0c7221 100644 --- a/slsSupportLib/src/ZmqSocket.cpp +++ b/slsSupportLib/src/ZmqSocket.cpp @@ -531,7 +531,7 @@ void ZmqSocket::PrintError() { // Nested class to do RAII handling of socket descriptors ZmqSocket::mySocketDescriptors::mySocketDescriptors(bool server) - : server(server), contextDescriptor(nullptr), socketDescriptor(nullptr){}; + : server(server), contextDescriptor(nullptr), socketDescriptor(nullptr) {}; ZmqSocket::mySocketDescriptors::~mySocketDescriptors() { Disconnect(); Close(); From 598154645c40e94b5cd1addd47ef311c39e38330 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Fri, 11 Apr 2025 11:03:52 +0200 Subject: [PATCH 36/38] changed font size in GUI --- pyctbgui/pyctbgui/ui/signals.ui | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyctbgui/pyctbgui/ui/signals.ui b/pyctbgui/pyctbgui/ui/signals.ui index d3f1022e9..f34e357cb 100644 --- a/pyctbgui/pyctbgui/ui/signals.ui +++ b/pyctbgui/pyctbgui/ui/signals.ui @@ -6115,6 +6115,11 @@ + + + 10 + + DBit Reorder From 3297707ab7e35ace347eece2ef11b12d7d6acf56 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Fri, 11 Apr 2025 11:38:56 +0200 Subject: [PATCH 37/38] clang-format with clang-format version 17 --- slsDetectorGui/include/qDefs.h | 2 +- .../slsDetectorServer_defs.h | 8 +++++--- .../eigerDetectorServer/FebControl.c | 6 +++--- .../slsDetectorServer_defs.h | 3 ++- .../slsDetectorServer_defs.h | 3 ++- .../slsDetectorServer_defs.h | 20 +++++++++++-------- .../slsDetectorServer_defs.h | 8 +++++--- .../slsDetectorServer_defs.h | 18 ++++++++++------- slsDetectorSoftware/include/sls/Result.h | 2 +- .../include/sls/detectorData.h | 6 +++--- slsReceiverSoftware/src/File.h | 4 ++-- slsReceiverSoftware/src/GeneralData.h | 4 ++-- .../tests/test-ArrangeDataBasedOnBitList.cpp | 4 ++-- slsSupportLib/include/sls/ClientSocket.h | 12 +++++------ slsSupportLib/include/sls/Timer.h | 2 +- slsSupportLib/include/sls/logger.h | 2 +- slsSupportLib/include/sls/sls_detector_defs.h | 6 +++--- slsSupportLib/src/ZmqSocket.cpp | 2 +- 18 files changed, 63 insertions(+), 49 deletions(-) diff --git a/slsDetectorGui/include/qDefs.h b/slsDetectorGui/include/qDefs.h index 018790c46..375d62d6c 100644 --- a/slsDetectorGui/include/qDefs.h +++ b/slsDetectorGui/include/qDefs.h @@ -39,7 +39,7 @@ class qDefs : public QWidget { /** * Empty Constructor */ - qDefs() {}; + qDefs(){}; static QFont GetDefaultFont() { return QFont("Cantarell", 10, QFont::Normal); diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h index 103502f1f..683338861 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h @@ -7,9 +7,11 @@ #define MIN_REQRD_VRSN_T_RD_API 0x181130 #define REQRD_FRMWR_VRSN 0x230705 -#define NUM_HARDWARE_VERSIONS (1) -#define HARDWARE_VERSION_NUMBERS {0x3f} -#define HARDWARE_VERSION_NAMES {"5.1"} +#define NUM_HARDWARE_VERSIONS (1) +#define HARDWARE_VERSION_NUMBERS \ + { 0x3f } +#define HARDWARE_VERSION_NAMES \ + { "5.1" } #define LINKED_SERVER_NAME "ctbDetectorServer" diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.c b/slsDetectorServers/eigerDetectorServer/FebControl.c index d3750259a..f0b96d487 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.c +++ b/slsDetectorServers/eigerDetectorServer/FebControl.c @@ -634,8 +634,8 @@ int Feb_Control_SetTrimbits(unsigned int *trimbits, int top) { << ((7 - i) * 4); // upper } } // end column loop i - } // end supercolumn loop sc - } // end row loop + } // end supercolumn loop sc + } // end row loop if (Feb_Control_activated) { if (!Feb_Interface_WriteMemoryInLoops(Feb_Control_leftAddress, @@ -652,7 +652,7 @@ int Feb_Control_SetTrimbits(unsigned int *trimbits, int top) { } } // end row_set loop (groups of 16 rows) - } // end l_r loop + } // end l_r loop memcpy(Feb_Control_last_downloaded_trimbits, trimbits, Feb_Control_trimbit_size * sizeof(unsigned int)); diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h index aa87505b3..5e4a62f1b 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h @@ -7,7 +7,8 @@ #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS {0x0, 0x1}; -#define HARDWARE_VERSION_NAMES {"FX70T", "FX30T"} +#define HARDWARE_VERSION_NAMES \ + { "FX70T", "FX30T" } #define REQUIRED_FIRMWARE_VERSION (32) // virtual ones renamed for consistency diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index a696221c9..d275cb400 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -9,7 +9,8 @@ #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS {0x0, 0x2}; -#define HARDWARE_VERSION_NAMES {"1.0", "1.2"} +#define HARDWARE_VERSION_NAMES \ + { "1.0", "1.2" } #define LINKED_SERVER_NAME "gotthard2DetectorServer" diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h index 88e30f1c4..cc2b0928b 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h @@ -8,9 +8,11 @@ #define REQRD_FRMWRE_VRSN_BOARD2 0x250209 // 1.0 pcb (version = 010) #define REQRD_FRMWRE_VRSN 0x250208 // 2.0 pcb (version = 011) -#define NUM_HARDWARE_VERSIONS (2) -#define HARDWARE_VERSION_NUMBERS {0x2, 0x3} -#define HARDWARE_VERSION_NAMES {"1.0", "2.0"} +#define NUM_HARDWARE_VERSIONS (2) +#define HARDWARE_VERSION_NUMBERS \ + { 0x2, 0x3 } +#define HARDWARE_VERSION_NAMES \ + { "1.0", "2.0" } #define ID_FILE "detid_jungfrau.txt" #define LINKED_SERVER_NAME "jungfrauDetectorServer" @@ -212,11 +214,13 @@ enum DACINDEX { enum MASTERINDEX { MASTER_HARDWARE, OW_MASTER, OW_SLAVE }; #define MASTER_NAMES "hardware", "master", "slave" -#define NUMSETTINGS (2) -#define NSPECIALDACS (3) -#define SPECIALDACINDEX {J_VREF_PRECH, J_VREF_DS, J_VREF_COMP}; -#define SPECIAL_DEFAULT_DYNAMIC_GAIN_VALS {1450, 480, 420} -#define SPECIAL_DEFAULT_DYNAMICHG0_GAIN_VALS {1550, 450, 620} +#define NUMSETTINGS (2) +#define NSPECIALDACS (3) +#define SPECIALDACINDEX {J_VREF_PRECH, J_VREF_DS, J_VREF_COMP}; +#define SPECIAL_DEFAULT_DYNAMIC_GAIN_VALS \ + { 1450, 480, 420 } +#define SPECIAL_DEFAULT_DYNAMICHG0_GAIN_VALS \ + { 1550, 450, 620 } enum NETWORKINDEX { TXN_FRAME, FLOWCTRL_10G }; enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS }; diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/moenchDetectorServer/slsDetectorServer_defs.h index 22d8e68ba..aa4133d7a 100644 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorServer_defs.h @@ -7,9 +7,11 @@ #define REQRD_FRMWRE_VRSN_BOARD2 0x444445 // 1.0 pcb (version = 010) #define REQRD_FRMWRE_VRSN 0x231026 // 2.0 pcb (version = 011) -#define NUM_HARDWARE_VERSIONS (2) -#define HARDWARE_VERSION_NUMBERS {0x2, 0x3} -#define HARDWARE_VERSION_NAMES {"1.0", "2.0"} +#define NUM_HARDWARE_VERSIONS (2) +#define HARDWARE_VERSION_NUMBERS \ + { 0x2, 0x3 } +#define HARDWARE_VERSION_NAMES \ + { "1.0", "2.0" } #define ID_FILE ("detid_moench.txt") #define LINKED_SERVER_NAME "moenchDetectorServer" diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h index 80abbd126..b0d8c1ea5 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h @@ -9,7 +9,8 @@ #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS {0x0, 0x2}; -#define HARDWARE_VERSION_NAMES {"1.0", "1.2"} +#define HARDWARE_VERSION_NAMES \ + { "1.0", "1.2" } #define LINKED_SERVER_NAME "mythen3DetectorServer" @@ -129,12 +130,15 @@ enum DACINDEX { enum ADCINDEX { TEMP_FPGA }; -#define NUMSETTINGS (3) -#define NSPECIALDACS (2) -#define SPECIALDACINDEX {M_VRPREAMP, M_VRSHAPER}; -#define SPECIAL_DEFAULT_STANDARD_DAC_VALS {1100, 1280} -#define SPECIAL_DEFAULT_FAST_DAC_VALS {300, 1500} -#define SPECIAL_DEFAULT_HIGHGAIN_DAC_VALS {1300, 1100} +#define NUMSETTINGS (3) +#define NSPECIALDACS (2) +#define SPECIALDACINDEX {M_VRPREAMP, M_VRSHAPER}; +#define SPECIAL_DEFAULT_STANDARD_DAC_VALS \ + { 1100, 1280 } +#define SPECIAL_DEFAULT_FAST_DAC_VALS \ + { 300, 1500 } +#define SPECIAL_DEFAULT_HIGHGAIN_DAC_VALS \ + { 1300, 1100 } enum CLKINDEX { SYSTEM_C0, SYSTEM_C1, SYSTEM_C2, NUM_CLOCKS }; #define NUM_CLOCKS_TO_SET (1) diff --git a/slsDetectorSoftware/include/sls/Result.h b/slsDetectorSoftware/include/sls/Result.h index 479eae047..0cb937408 100644 --- a/slsDetectorSoftware/include/sls/Result.h +++ b/slsDetectorSoftware/include/sls/Result.h @@ -32,7 +32,7 @@ template > class Result { public: Result() = default; - Result(std::initializer_list list) : vec(list) {}; + Result(std::initializer_list list) : vec(list){}; /** Custom constructor from integer type to Result or Result */ template getIntArray() const { return std::array({xmin, xmax, ymin, ymax}); } diff --git a/slsSupportLib/src/ZmqSocket.cpp b/slsSupportLib/src/ZmqSocket.cpp index eed0c7221..2fafe4799 100644 --- a/slsSupportLib/src/ZmqSocket.cpp +++ b/slsSupportLib/src/ZmqSocket.cpp @@ -531,7 +531,7 @@ void ZmqSocket::PrintError() { // Nested class to do RAII handling of socket descriptors ZmqSocket::mySocketDescriptors::mySocketDescriptors(bool server) - : server(server), contextDescriptor(nullptr), socketDescriptor(nullptr) {}; + : server(server), contextDescriptor(nullptr), socketDescriptor(nullptr){}; ZmqSocket::mySocketDescriptors::~mySocketDescriptors() { Disconnect(); Close(); From 4d8bdae8363ca2a51e01be03307e8ea3a13466a7 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Fri, 11 Apr 2025 12:38:28 +0200 Subject: [PATCH 38/38] updated update_image_size in xilinx --- slsReceiverSoftware/src/GeneralData.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index 9f3b43429..17a4ea7e5 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -60,8 +60,8 @@ class GeneralData { slsDetectorDefs::frameDiscardPolicy frameDiscardMode{ slsDetectorDefs::NO_DISCARD}; - GeneralData(){}; - virtual ~GeneralData(){}; + GeneralData() {}; + virtual ~GeneralData() {}; // Returns the pixel depth in byte, 4 bits being 0.5 byte float GetPixelDepth() { return float(dynamicRange) / 8; } @@ -569,6 +569,7 @@ class XilinxChipTestBoardData : public GeneralData { nDigitalBytes = 0; nTransceiverBytes = 0; int nAnalogChans = 0, nDigitalChans = 0, nTransceiverChans = 0; + uint64_t digital_bytes_reserved = 0; // analog channels (normal, analog/digital readout) if (readoutType == slsDetectorDefs::ANALOG_ONLY || @@ -586,7 +587,11 @@ class XilinxChipTestBoardData : public GeneralData { readoutType == slsDetectorDefs::ANALOG_AND_DIGITAL || readoutType == slsDetectorDefs::DIGITAL_AND_TRANSCEIVER) { nDigitalChans = NCHAN_DIGITAL; - nDigitalBytes = (sizeof(uint64_t) * nDigitalSamples); + uint32_t num_bytes_per_bit = (nDigitalSamples % 8 == 0) + ? nDigitalSamples / 8 + : nDigitalSamples / 8 + 1; + digital_bytes_reserved = 64 * num_bytes_per_bit; + nDigitalBytes = sizeof(uint64_t) * nDigitalSamples; LOG(logDEBUG1) << "Number of Digital Channels:" << nDigitalChans << " Databytes: " << nDigitalBytes; } @@ -604,7 +609,7 @@ class XilinxChipTestBoardData : public GeneralData { } nPixelsX = nAnalogChans + nDigitalChans + nTransceiverChans; - imageSize = nAnalogBytes + nDigitalBytes + nTransceiverBytes; + imageSize = nAnalogBytes + digital_bytes_reserved + nTransceiverBytes; packetsPerFrame = ceil((double)imageSize / (double)dataSize); LOG(logDEBUG1) << "Total Number of Channels:" << nPixelsX