From 23aa9c2814de02411c5e9b2b1696f5ef9927794e Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Tue, 11 Mar 2025 12:07:10 +0100 Subject: [PATCH 01/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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/82] 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 eb8c34f53b09cf9198d3c81c686c5cfe00c82b1b Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Tue, 18 Mar 2025 10:33:51 +0100 Subject: [PATCH 16/82] skeleton pyproject.toml --- CMakeLists.txt | 6 +++++- pyproject.toml | 22 ++++++++++++++++++++++ python/CMakeLists.txt | 15 ++++++++++++--- 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 pyproject.toml diff --git a/CMakeLists.txt b/CMakeLists.txt index 5676ec92d..c15f1fcb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: LGPL-3.0-or-other # Copyright (C) 2021 Contributors to the SLS Detector Package -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.15) project(slsDetectorPackage) # Read VERSION file into project version @@ -29,6 +29,10 @@ include(FetchContent) option(SLS_FETCH_ZMQ_FROM_GITHUB "Fetch zmq from github" OFF) option(SLS_FETCH_PYBIND11_FROM_GITHUB "Fetch pybind11 from github" OFF) +if(${SKBUILD}) + message(STATUS "Building with scikit-build") +endif() + if(SLS_FETCH_ZMQ_FROM_GITHUB) # Opt in to pull down a zmq version from github instead of # using the bundled verison diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..e626be8c0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[build-system] +requires = ["scikit-build-core>=0.10", "pybind11", "numpy"] +build-backend = "scikit_build_core.build" + +[project] +name = "slsDetectorPackage" +version = "2025.2.18" + + +[tool.scikit-build] +cmake.verbose = true +cmake.build-type = "Release" +install.components = ["python"] + + +[tool.scikit-build.cmake.define] +SLS_USE_RECEIVER = "OFF" +SLS_USE_RECEIVER_BINARIES = "OFF" +SLS_USE_TEXTCLIENT = "OFF" +SLS_USE_PYTHON = "ON" +SLS_INSTALL_PYTHONEXT = "ON" +SLS_BUILD_SHARED_LIBRARIES = "OFF" \ No newline at end of file diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 0ae86941f..80a107ff4 100755 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -72,9 +72,18 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../VERSION if(SLS_INSTALL_PYTHONEXT) install(TARGETS _slsdet EXPORT "${TARGETS_EXPORT_NAME}" - LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/python + LIBRARY DESTINATION slsdet + COMPONENT python ) + install( + FILES ${PYTHON_FILES} + DESTINATION slsdet + COMPONENT python + ) + install( + FILES ../VERSION + DESTINATION slsdet + COMPONENT python + ) - install(FILES ${PYTHON_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/python/slsdet) - install(FILES ../VERSION DESTINATION ${CMAKE_INSTALL_PREFIX}/python/slsdet) endif() \ No newline at end of file From bc187bb19842a53d6e98204b30b4b0e8b835a56d Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Tue, 18 Mar 2025 10:56:03 +0100 Subject: [PATCH 17/82] moved compiled extension into slsdet --- pyproject.toml | 8 +++++--- python/CMakeLists.txt | 2 +- python/slsdet/__init__.py | 2 +- python/slsdet/ctb.py | 2 +- python/slsdet/dacs.py | 2 +- python/slsdet/detector.py | 8 ++++---- python/slsdet/eiger.py | 2 +- python/slsdet/enums.py | 4 ++-- python/slsdet/gaincaps.py | 2 +- python/slsdet/gotthard2.py | 2 +- python/slsdet/jungfrau.py | 2 +- python/slsdet/moench.py | 2 +- python/slsdet/mythen3.py | 2 +- python/slsdet/pattern.py | 4 ++-- python/slsdet/powers.py | 2 +- python/slsdet/proxy.py | 2 +- python/slsdet/utils.py | 2 +- 17 files changed, 26 insertions(+), 24 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e626be8c0..df5a2a852 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["scikit-build-core>=0.10", "pybind11", "numpy"] build-backend = "scikit_build_core.build" [project] -name = "slsDetectorPackage" +name = "slsdet" version = "2025.2.18" @@ -14,9 +14,11 @@ install.components = ["python"] [tool.scikit-build.cmake.define] +#Only build the control software and python ext SLS_USE_RECEIVER = "OFF" SLS_USE_RECEIVER_BINARIES = "OFF" SLS_USE_TEXTCLIENT = "OFF" +SLS_BUILD_SHARED_LIBRARIES = "OFF" + SLS_USE_PYTHON = "ON" -SLS_INSTALL_PYTHONEXT = "ON" -SLS_BUILD_SHARED_LIBRARIES = "OFF" \ No newline at end of file +SLS_INSTALL_PYTHONEXT = "ON" \ No newline at end of file diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 80a107ff4..48a2d004f 100755 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -20,7 +20,7 @@ target_link_libraries(_slsdet PUBLIC set_target_properties(_slsdet PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/slsdet ) #Copy Python code diff --git a/python/slsdet/__init__.py b/python/slsdet/__init__.py index d46354351..4b216ee62 100755 --- a/python/slsdet/__init__.py +++ b/python/slsdet/__init__.py @@ -14,7 +14,7 @@ from .pattern import Pattern, patternParameters from .gaincaps import Mythen3GainCapsWrapper from .PatternGenerator import PatternGenerator -import _slsdet +from . import _slsdet xy = _slsdet.xy defs = _slsdet.slsDetectorDefs diff --git a/python/slsdet/ctb.py b/python/slsdet/ctb.py index ad671a93e..1295af9cb 100644 --- a/python/slsdet/ctb.py +++ b/python/slsdet/ctb.py @@ -4,7 +4,7 @@ from .detector import Detector, freeze from .utils import element_if_equal from .dacs import DetectorDacs, NamedDacs from .powers import DetectorPowers, NamedPowers -import _slsdet +from . import _slsdet dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty diff --git a/python/slsdet/dacs.py b/python/slsdet/dacs.py index 961d0bebe..547a43277 100755 --- a/python/slsdet/dacs.py +++ b/python/slsdet/dacs.py @@ -3,7 +3,7 @@ from .detector_property import DetectorProperty from functools import partial import numpy as np -import _slsdet +from . import _slsdet from .detector import freeze dacIndex = _slsdet.slsDetectorDefs.dacIndex class Dac(DetectorProperty): diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 459e4a25c..873485c88 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -1,8 +1,8 @@ # SPDX-License-Identifier: LGPL-3.0-or-other # Copyright (C) 2021 Contributors to the SLS Detector Package -from _slsdet import CppDetectorApi -from _slsdet import slsDetectorDefs -from _slsdet import IpAddr, MacAddr +from ._slsdet import CppDetectorApi +from ._slsdet import slsDetectorDefs +from ._slsdet import IpAddr, MacAddr runStatus = slsDetectorDefs.runStatus timingMode = slsDetectorDefs.timingMode @@ -15,7 +15,7 @@ defs = slsDetectorDefs from .utils import element_if_equal, all_equal, get_set_bits, list_to_bitmask from .utils import Geometry, to_geo, element, reduce_time, is_iterable, hostname_list -from _slsdet import xy +from ._slsdet import xy from .gaincaps import Mythen3GainCapsWrapper from . import utils as ut from .proxy import JsonProxy, SlowAdcProxy, ClkDivProxy, MaxPhaseProxy, ClkFreqProxy, PatLoopProxy, PatNLoopProxy, PatWaitProxy, PatWaitTimeProxy diff --git a/python/slsdet/eiger.py b/python/slsdet/eiger.py index a65532677..db12b7909 100755 --- a/python/slsdet/eiger.py +++ b/python/slsdet/eiger.py @@ -11,7 +11,7 @@ Created on Wed Dec 6 11:51:18 2017 from .detector import Detector from .temperature import Temperature, DetectorTemperature from .dacs import DetectorDacs -import _slsdet +from . import _slsdet dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty diff --git a/python/slsdet/enums.py b/python/slsdet/enums.py index 02e3c5126..41dcd5dec 100644 --- a/python/slsdet/enums.py +++ b/python/slsdet/enums.py @@ -15,8 +15,8 @@ if dt === detectorType.EIGER: """ -import _slsdet +from . import _slsdet for name, cls in _slsdet.slsDetectorDefs.__dict__.items(): if isinstance(cls, type): - exec(f'{name} = {cls.__module__}.{cls.__qualname__}') + exec(f'{name} = _slsdet.{cls.__qualname__}') diff --git a/python/slsdet/gaincaps.py b/python/slsdet/gaincaps.py index ab3acd381..900503624 100644 --- a/python/slsdet/gaincaps.py +++ b/python/slsdet/gaincaps.py @@ -1,6 +1,6 @@ -import _slsdet +from . import _slsdet gc = _slsdet.slsDetectorDefs.M3_GainCaps diff --git a/python/slsdet/gotthard2.py b/python/slsdet/gotthard2.py index bdb36097f..fb2786faf 100644 --- a/python/slsdet/gotthard2.py +++ b/python/slsdet/gotthard2.py @@ -11,7 +11,7 @@ from .detector import Detector, freeze # from .adcs import Adc, DetectorAdcs from .dacs import DetectorDacs -import _slsdet +from . import _slsdet dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty diff --git a/python/slsdet/jungfrau.py b/python/slsdet/jungfrau.py index c8e3f43f9..1021a55f1 100644 --- a/python/slsdet/jungfrau.py +++ b/python/slsdet/jungfrau.py @@ -11,7 +11,7 @@ from .detector import Detector, freeze # from .adcs import Adc, DetectorAdcs from .dacs import DetectorDacs -import _slsdet +from . import _slsdet dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty diff --git a/python/slsdet/moench.py b/python/slsdet/moench.py index 6ed49a43d..7e93bee65 100644 --- a/python/slsdet/moench.py +++ b/python/slsdet/moench.py @@ -9,7 +9,7 @@ This file contains the specialization for the Moench detector from .detector import Detector, freeze from .dacs import DetectorDacs -import _slsdet +from . import _slsdet dacIndex = _slsdet.slsDetectorDefs.dacIndex from .detector_property import DetectorProperty diff --git a/python/slsdet/mythen3.py b/python/slsdet/mythen3.py index 369d6ac99..14e1294ea 100644 --- a/python/slsdet/mythen3.py +++ b/python/slsdet/mythen3.py @@ -11,7 +11,7 @@ from .detector import Detector, freeze # from .adcs import Adc, DetectorAdcs from .dacs import DetectorDacs -import _slsdet +from . import _slsdet dacIndex = _slsdet.slsDetectorDefs.dacIndex gc_enums = _slsdet.slsDetectorDefs.M3_GainCaps from .detector_property import DetectorProperty diff --git a/python/slsdet/pattern.py b/python/slsdet/pattern.py index a2d80fdfe..273865c65 100644 --- a/python/slsdet/pattern.py +++ b/python/slsdet/pattern.py @@ -1,8 +1,8 @@ # SPDX-License-Identifier: LGPL-3.0-or-other # Copyright (C) 2021 Contributors to the SLS Detector Package -import _slsdet +from . import _slsdet -from _slsdet import Pattern +from ._slsdet import Pattern class patternParameters(_slsdet.patternParameters): diff --git a/python/slsdet/powers.py b/python/slsdet/powers.py index 8de1781c7..a513eedbe 100755 --- a/python/slsdet/powers.py +++ b/python/slsdet/powers.py @@ -3,7 +3,7 @@ from .detector_property import DetectorProperty from functools import partial import numpy as np -import _slsdet +from . import _slsdet from .detector import freeze dacIndex = _slsdet.slsDetectorDefs.dacIndex class Power(DetectorProperty): diff --git a/python/slsdet/proxy.py b/python/slsdet/proxy.py index f3e7ad71b..c0aa57900 100644 --- a/python/slsdet/proxy.py +++ b/python/slsdet/proxy.py @@ -3,7 +3,7 @@ from .utils import element_if_equal from .enums import dacIndex from .defines import M3_MAX_PATTERN_LEVELS, MAX_PATTERN_LEVELS -from _slsdet import slsDetectorDefs +from ._slsdet import slsDetectorDefs detectorType = slsDetectorDefs.detectorType diff --git a/python/slsdet/utils.py b/python/slsdet/utils.py index 89a7651bc..4648abd5a 100755 --- a/python/slsdet/utils.py +++ b/python/slsdet/utils.py @@ -6,7 +6,7 @@ but not directly used in controlling the detector """ from collections import namedtuple -import _slsdet #C++ lib +from . import _slsdet #C++ lib import functools import datetime as dt import pathlib From d9a50ad9f4bdc661a77c679bb746e1fc339a14b4 Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Tue, 18 Mar 2025 13:21:46 +0100 Subject: [PATCH 18/82] WIP --- conda-recipe/conda_build_config.yaml | 10 ++-- conda-recipe/meta.yaml | 24 +++++---- python/setup.py | 77 ---------------------------- 3 files changed, 18 insertions(+), 93 deletions(-) delete mode 100755 python/setup.py diff --git a/conda-recipe/conda_build_config.yaml b/conda-recipe/conda_build_config.yaml index 0f51da017..991a0644d 100644 --- a/conda-recipe/conda_build_config.yaml +++ b/conda-recipe/conda_build_config.yaml @@ -1,8 +1,8 @@ python: - - 3.8 - - 3.9 - - 3.10 - - 3.11 - - 3.12 + # - 3.8 + # - 3.9 + # - 3.10 + # - 3.11 + # - 3.12 - 3.13 diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 076e37ebc..7f78b180e 100755 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -66,30 +66,32 @@ outputs: - libgcc-ng - name: slsdet - script: build_pylib.sh + script: + - unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv # [not win] requirements: build: - - python + - python {{python}} - {{ compiler('c') }} - {{compiler('cxx')}} - - {{ pin_subpackage('slsdetlib', exact=True) }} - - setuptools - - pybind11=2.13 + # - {{ pin_subpackage('slsdetlib', exact=True) }} #discuss keeping pinning for simplicity? + - pybind11>=2.13 host: - - python - - {{ pin_subpackage('slsdetlib', exact=True) }} + - cmake + - ninja + - python {{python}} + - pip - setuptools - - pybind11=2.13 + - pybind11>=2.13 + - scikit-build-core run: - libstdcxx-ng - libgcc-ng - - python - - numpy - - {{ pin_subpackage('slsdetlib', exact=True) }} + - python {{python}} + test: imports: diff --git a/python/setup.py b/python/setup.py deleted file mode 100755 index 1be1ac809..000000000 --- a/python/setup.py +++ /dev/null @@ -1,77 +0,0 @@ -# SPDX-License-Identifier: LGPL-3.0-or-other -# Copyright (C) 2021 Contributors to the SLS Detector Package -""" -Setup file for slsdet -Build upon the pybind11 example found here: https://github.com/pybind/python_example -""" - -import os -import sys -from setuptools import setup, find_packages -from pybind11.setup_helpers import Pybind11Extension, build_ext - -def read_version(): - try: - version_file = os.path.join(os.path.dirname(__file__), 'slsdet', 'VERSION') - with open(version_file, "r") as f: - return f.read().strip() - except: - raise RuntimeError("VERSION file not found in slsdet package from setup.py.") - -__version__ = read_version() - - -def get_conda_path(): - """ - Keep this a function if we need some fancier logic later - """ - print('Prefix: ', os.environ['CONDA_PREFIX']) - return os.environ['CONDA_PREFIX'] - - -#TODO migrate to CMake build or fetch files from cmake? -ext_modules = [ - Pybind11Extension( - '_slsdet', - ['src/main.cpp', - 'src/enums.cpp', - 'src/current.cpp', - 'src/detector.cpp', - 'src/network.cpp', - 'src/pattern.cpp', - 'src/scan.cpp', - 'src/duration.cpp', - 'src/DurationWrapper.cpp', - 'src/pedestal.cpp', - ] - - - , - include_dirs=[ - os.path.join(get_conda_path(), 'include'), - - ], - libraries=['SlsDetector', 'SlsSupport', 'SlsReceiver'], - library_dirs=[ - os.path.join(get_conda_path(), 'lib'), - ], - language='c++' - ), -] - -setup( - name='slsdet', - version=__version__, - author='Erik Frojdh', - author_email='erik.frojdh@psi.ch', - url='https://github.com/slsdetectorgroup/slsDetectorPackage', - description='Detector API for SLS Detector Group detectors', - long_description='', - packages=find_packages(exclude=['contrib', 'docs', 'tests']), - package_data={ - 'slsdet': ['VERSION'], - }, - ext_modules=ext_modules, - cmdclass={"build_ext": build_ext}, - zip_safe=False, -) From f056f9d31b304dda9dff2d723c95cc5d512a53f3 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Tue, 18 Mar 2025 21:42:34 +0100 Subject: [PATCH 19/82] 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 20/82] 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 21/82] 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 2f390971e6dc755a1812bf80053998880c76e751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Wed, 19 Mar 2025 16:37:37 +0100 Subject: [PATCH 22/82] WI{ --- CMakeLists.txt | 9 +- conda-recipe/build.sh | 5 +- conda-recipe/conda_build_config.yaml | 8 + conda-recipe/meta.yaml | 123 ++++----- .../tests/test-SharedMemory.cpp | 236 +++++++++--------- 5 files changed, 199 insertions(+), 182 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c15f1fcb4..f3055e34f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,8 @@ set(PROJECT_VERSION ${PROJECT_VERSION_STRING}) add_compile_definitions(SLS_DET_VERSION="${PROJECT_VERSION}") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) cmake_policy(SET CMP0074 NEW) @@ -58,6 +60,11 @@ set(ENABLE_CPACK OFF CACHE BOOL "") set(ENABLE_CLANG OFF CACHE BOOL "") set(ENABLE_CURVE OFF CACHE BOOL "") set(ENABLE_DRAFTS OFF CACHE BOOL "") +set(ENABLE_PRECOMPILED OFF CACHE BOOL "") +set(WITH_DOC OFF CACHE BOOL "") +set(WITH_DOCS OFF CACHE BOOL "") + + # Using GetProperties and Populate to be able to exclude zmq # from install (not possible with FetchContent_MakeAvailable(libzmq)) @@ -195,7 +202,7 @@ endif() # to control options for the libraries if(NOT TARGET slsProjectOptions) add_library(slsProjectOptions INTERFACE) - target_compile_features(slsProjectOptions INTERFACE cxx_std_11) +# target_compile_features(slsProjectOptions INTERFACE cxx_std_11) endif() if (NOT TARGET slsProjectWarnings) diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh index 251b04477..5c3995d91 100755 --- a/conda-recipe/build.sh +++ b/conda-recipe/build.sh @@ -8,12 +8,12 @@ if [ ! -d "install" ]; then mkdir install fi cd build -cmake .. \ +cmake .. -G Ninja \ -DCMAKE_PREFIX_PATH=$CONDA_PREFIX \ -DCMAKE_INSTALL_PREFIX=install \ -DSLS_USE_TEXTCLIENT=ON \ -DSLS_USE_RECEIVER=ON \ - -DSLS_USE_GUI=ON \ + -DSLS_USE_GUI=OFF \ -DSLS_USE_MOENCH=ON\ -DSLS_USE_TESTS=ON \ -DSLS_USE_PYTHON=OFF \ @@ -25,4 +25,5 @@ echo "Building using: ${NCORES} cores" cmake --build . -- -j${NCORES} cmake --build . --target install +export SLSDETNAME=automated_tests CTEST_OUTPUT_ON_FAILURE=1 ctest -j 1 diff --git a/conda-recipe/conda_build_config.yaml b/conda-recipe/conda_build_config.yaml index 991a0644d..c953a95ed 100644 --- a/conda-recipe/conda_build_config.yaml +++ b/conda-recipe/conda_build_config.yaml @@ -6,3 +6,11 @@ python: # - 3.12 - 3.13 +c_compiler_version: # [unix] + - 11 # [linux] + +cxx_compiler_version: + - 11 # [linux] + +c_stdlib_version: # [linux] + - 2.17 # [linux] \ No newline at end of file diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 7f78b180e..a83d42fa2 100755 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -15,8 +15,9 @@ build: requirements: build: - {{ compiler('c') }} - - {{compiler('cxx')}} + - {{ compiler('cxx') }} - cmake + - ninja - qt 5.* - xorg-libx11 - xorg-libice @@ -34,8 +35,8 @@ requirements: - expat host: - - libstdcxx-ng - - libgcc-ng + # - libstdcxx-ng + # - libgcc-ng - xorg-libx11 - xorg-libice - xorg-libxext @@ -44,10 +45,12 @@ requirements: - xorg-libxrender - xorg-libxfixes - expat + - libtiff + - libpng run: - - libstdcxx-ng - - libgcc-ng + # - libstdcxx-ng + # - libgcc-ng outputs: @@ -58,70 +61,68 @@ outputs: build: - {{ compiler('c') }} - {{compiler('cxx')}} - - libstdcxx-ng - - libgcc-ng + # - libstdcxx-ng + # - libgcc-ng run: - - libstdcxx-ng - - libgcc-ng + # - libstdcxx-ng + # - libgcc-ng - - name: slsdet - script: - - unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv # [not win] + # - name: slsdet + # script: build_pylib.sh - requirements: - build: - - python {{python}} - - {{ compiler('c') }} - - {{compiler('cxx')}} - # - {{ pin_subpackage('slsdetlib', exact=True) }} #discuss keeping pinning for simplicity? - - pybind11>=2.13 + # requirements: + # build: + # - python + # - {{ compiler('c') }} + # - {{compiler('cxx')}} + # - {{ pin_subpackage('slsdetlib', exact=True) }} + # - setuptools + # - pybind11=2.13 - host: - - cmake - - ninja - - python {{python}} - - pip - - setuptools - - pybind11>=2.13 - - scikit-build-core + # host: + # - python + # - {{ pin_subpackage('slsdetlib', exact=True) }} + # - setuptools + # - pybind11=2.13 - run: - - libstdcxx-ng - - libgcc-ng - - python {{python}} + # run: + # - libstdcxx-ng + # - libgcc-ng + # - python + # - numpy + # - {{ pin_subpackage('slsdetlib', exact=True) }} + + # test: + # imports: + # - slsdet - test: - imports: - - slsdet + # - name: slsdetgui + # script: copy_gui.sh + # requirements: + + # build: + # - {{ compiler('c') }} + # - {{compiler('cxx')}} + # - {{ pin_subpackage('slsdetlib', exact=True) }} + + # run: + # - {{ pin_subpackage('slsdetlib', exact=True) }} + # - qt 5.* + # - expat + + # - name: moenchzmq + # script: copy_moench.sh + # requirements: + + # build: + # - {{ compiler('c') }} + # - {{compiler('cxx')}} + # - {{ pin_subpackage('slsdetlib', exact=True) }} - - name: slsdetgui - script: copy_gui.sh - requirements: - - build: - - {{ compiler('c') }} - - {{compiler('cxx')}} - - {{ pin_subpackage('slsdetlib', exact=True) }} - - run: - - {{ pin_subpackage('slsdetlib', exact=True) }} - - qt 5.* - - expat - - - name: moenchzmq - script: copy_moench.sh - requirements: - - build: - - {{ compiler('c') }} - - {{compiler('cxx')}} - - {{ pin_subpackage('slsdetlib', exact=True) }} - - - run: - - {{ pin_subpackage('slsdetlib', exact=True) }} - - expat + # run: + # - {{ pin_subpackage('slsdetlib', exact=True) }} + # - expat \ No newline at end of file diff --git a/slsDetectorSoftware/tests/test-SharedMemory.cpp b/slsDetectorSoftware/tests/test-SharedMemory.cpp index 5ba3c20a2..b16a41b25 100644 --- a/slsDetectorSoftware/tests/test-SharedMemory.cpp +++ b/slsDetectorSoftware/tests/test-SharedMemory.cpp @@ -17,155 +17,155 @@ struct Data { constexpr int shm_id = 10; -TEST_CASE("Create SharedMemory read and write", "[detector]") { +// TEST_CASE("Create SharedMemory read and write", "[detector]") { - SharedMemory shm(shm_id, -1); - shm.createSharedMemory(); - CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + - std::to_string(shm_id)); +// SharedMemory shm(shm_id, -1); +// shm.createSharedMemory(); +// CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + +// std::to_string(shm_id)); - shm()->x = 3; - shm()->y = 5.7; - strcpy_safe(shm()->mess, "Some string"); +// shm()->x = 3; +// shm()->y = 5.7; +// strcpy_safe(shm()->mess, "Some string"); - CHECK(shm()->x == 3); - CHECK(shm()->y == 5.7); - CHECK(std::string(shm()->mess) == "Some string"); +// CHECK(shm()->x == 3); +// CHECK(shm()->y == 5.7); +// CHECK(std::string(shm()->mess) == "Some string"); - shm.unmapSharedMemory(); - shm.removeSharedMemory(); +// shm.unmapSharedMemory(); +// shm.removeSharedMemory(); - CHECK(shm.exists() == false); -} +// CHECK(shm.exists() == false); +// } -TEST_CASE("Open existing SharedMemory and read", "[detector]") { +// TEST_CASE("Open existing SharedMemory and read", "[detector]") { - { - SharedMemory shm(shm_id, -1); - shm.createSharedMemory(); - *shm() = 5.3; - } +// { +// SharedMemory shm(shm_id, -1); +// shm.createSharedMemory(); +// *shm() = 5.3; +// } - SharedMemory shm2(shm_id, -1); - shm2.openSharedMemory(true); - CHECK(*shm2() == 5.3); +// SharedMemory shm2(shm_id, -1); +// shm2.openSharedMemory(true); +// CHECK(*shm2() == 5.3); - shm2.removeSharedMemory(); -} +// shm2.removeSharedMemory(); +// } -TEST_CASE("Creating a second shared memory with the same name throws", - "[detector]") { +// TEST_CASE("Creating a second shared memory with the same name throws", +// "[detector]") { - SharedMemory shm0(shm_id, -1); - SharedMemory shm1(shm_id, -1); +// SharedMemory shm0(shm_id, -1); +// SharedMemory shm1(shm_id, -1); - shm0.createSharedMemory(); - CHECK_THROWS(shm1.createSharedMemory()); - shm0.removeSharedMemory(); -} +// shm0.createSharedMemory(); +// CHECK_THROWS(shm1.createSharedMemory()); +// shm0.removeSharedMemory(); +// } -TEST_CASE("Open two shared memories to the same place", "[detector]") { +// TEST_CASE("Open two shared memories to the same place", "[detector]") { - // Create the first shared memory - SharedMemory shm(shm_id, -1); - shm.createSharedMemory(); - shm()->x = 5; - CHECK(shm()->x == 5); +// // Create the first shared memory +// SharedMemory shm(shm_id, -1); +// shm.createSharedMemory(); +// shm()->x = 5; +// CHECK(shm()->x == 5); - // Open the second shared memory with the same name - SharedMemory shm2(shm_id, -1); - shm2.openSharedMemory(true); - CHECK(shm2()->x == 5); - CHECK(shm.getName() == shm2.getName()); +// // Open the second shared memory with the same name +// SharedMemory shm2(shm_id, -1); +// shm2.openSharedMemory(true); +// CHECK(shm2()->x == 5); +// CHECK(shm.getName() == shm2.getName()); - // Check that they still point to the same place - shm2()->x = 7; - CHECK(shm()->x == 7); +// // Check that they still point to the same place +// shm2()->x = 7; +// CHECK(shm()->x == 7); - // Remove only needs to be done once since they refer - // to the same memory - shm2.removeSharedMemory(); - CHECK(shm.exists() == false); - CHECK(shm2.exists() == false); -} +// // Remove only needs to be done once since they refer +// // to the same memory +// shm2.removeSharedMemory(); +// CHECK(shm.exists() == false); +// CHECK(shm2.exists() == false); +// } -TEST_CASE("Move SharedMemory", "[detector]") { +// TEST_CASE("Move SharedMemory", "[detector]") { - SharedMemory shm(shm_id, -1); - CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + - std::to_string(shm_id)); - shm.createSharedMemory(); - shm()->x = 9; +// SharedMemory shm(shm_id, -1); +// CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + +// std::to_string(shm_id)); +// shm.createSharedMemory(); +// shm()->x = 9; - SharedMemory shm2(shm_id + 1, -1); - shm2 = std::move(shm); // shm is now a moved from object! +// SharedMemory shm2(shm_id + 1, -1); +// shm2 = std::move(shm); // shm is now a moved from object! - CHECK(shm2()->x == 9); - REQUIRE_THROWS( - shm()); // trying to access should throw instead of returning a nullptr - CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") + - std::to_string(shm_id)); - shm2.removeSharedMemory(); -} +// CHECK(shm2()->x == 9); +// REQUIRE_THROWS( +// shm()); // trying to access should throw instead of returning a nullptr +// CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") + +// std::to_string(shm_id)); +// shm2.removeSharedMemory(); +// } -TEST_CASE("Create several shared memories", "[detector]") { - constexpr int N = 5; - std::vector> v; - v.reserve(N); - for (int i = 0; i != N; ++i) { - v.emplace_back(shm_id + i, -1); - CHECK(v[i].exists() == false); - v[i].createSharedMemory(); - *v[i]() = i; - CHECK(*v[i]() == i); - } +// TEST_CASE("Create several shared memories", "[detector]") { +// constexpr int N = 5; +// std::vector> v; +// v.reserve(N); +// for (int i = 0; i != N; ++i) { +// v.emplace_back(shm_id + i, -1); +// CHECK(v[i].exists() == false); +// v[i].createSharedMemory(); +// *v[i]() = i; +// CHECK(*v[i]() == i); +// } - for (int i = 0; i != N; ++i) { - CHECK(*v[i]() == i); - CHECK(v[i].getName() == std::string("/slsDetectorPackage_detector_") + - std::to_string(i + shm_id)); - } +// for (int i = 0; i != N; ++i) { +// CHECK(*v[i]() == i); +// CHECK(v[i].getName() == std::string("/slsDetectorPackage_detector_") + +// std::to_string(i + shm_id)); +// } - for (int i = 0; i != N; ++i) { - v[i].removeSharedMemory(); - CHECK(v[i].exists() == false); - } -} +// for (int i = 0; i != N; ++i) { +// v[i].removeSharedMemory(); +// CHECK(v[i].exists() == false); +// } +// } -TEST_CASE("Create create a shared memory with a tag") { - SharedMemory shm(0, -1, "ctbdacs"); - REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_ctbdacs"); -} +// TEST_CASE("Create create a shared memory with a tag") { +// SharedMemory shm(0, -1, "ctbdacs"); +// REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_ctbdacs"); +// } -TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set") { +// TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set") { - // if SLSDETNAME is already set we unset it but - // save the value - std::string old_slsdetname; - if (getenv(SHM_ENV_NAME)) - old_slsdetname = getenv(SHM_ENV_NAME); - unsetenv(SHM_ENV_NAME); - setenv(SHM_ENV_NAME, "myprefix", 1); +// // if SLSDETNAME is already set we unset it but +// // save the value +// std::string old_slsdetname; +// if (getenv(SHM_ENV_NAME)) +// old_slsdetname = getenv(SHM_ENV_NAME); +// unsetenv(SHM_ENV_NAME); +// setenv(SHM_ENV_NAME, "myprefix", 1); - SharedMemory shm(0, -1, "ctbdacs"); - REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_myprefix_ctbdacs"); +// SharedMemory shm(0, -1, "ctbdacs"); +// REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_myprefix_ctbdacs"); - // Clean up after us - if (old_slsdetname.empty()) - unsetenv(SHM_ENV_NAME); - else - setenv(SHM_ENV_NAME, old_slsdetname.c_str(), 1); -} +// // Clean up after us +// if (old_slsdetname.empty()) +// unsetenv(SHM_ENV_NAME); +// else +// setenv(SHM_ENV_NAME, old_slsdetname.c_str(), 1); +// } -TEST_CASE("map int64 to int32 throws") { - SharedMemory shm(shm_id, -1); - shm.createSharedMemory(); - *shm() = 7; +// TEST_CASE("map int64 to int32 throws") { +// SharedMemory shm(shm_id, -1); +// shm.createSharedMemory(); +// *shm() = 7; - SharedMemory shm2(shm_id, -1); - REQUIRE_THROWS(shm2.openSharedMemory(true)); +// SharedMemory shm2(shm_id, -1); +// REQUIRE_THROWS(shm2.openSharedMemory(true)); - shm.removeSharedMemory(); -} +// shm.removeSharedMemory(); +// } } // namespace sls From e8e84a4e72383ad13a6b008eb31a654cb2142d61 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 19 Mar 2025 17:11:05 +0100 Subject: [PATCH 23/82] fixed tests for real gotthard2. change in reg address to test --- slsDetectorSoftware/tests/Caller/test-Caller.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/slsDetectorSoftware/tests/Caller/test-Caller.cpp b/slsDetectorSoftware/tests/Caller/test-Caller.cpp index c2235d81e..ae21ed945 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller.cpp @@ -3236,7 +3236,7 @@ TEST_CASE("reg", "[.cmdcall]") { addr = 0x80; } if (det_type == defs::GOTTHARD2) { - addr = 0x20; + addr = 0x298; } std::string saddr = ToStringHex(addr); auto prev_val = det.readRegister(addr); @@ -3292,7 +3292,7 @@ TEST_CASE("setbit", "[.cmdcall]") { addr = 0x80; } if (det_type == defs::GOTTHARD2) { - addr = 0x20; + addr = 0x298; } std::string saddr = ToStringHex(addr); auto prev_val = det.readRegister(addr); @@ -3322,7 +3322,7 @@ TEST_CASE("clearbit", "[.cmdcall]") { addr = 0x80; } if (det_type == defs::GOTTHARD2) { - addr = 0x20; + addr = 0x298; } std::string saddr = ToStringHex(addr); auto prev_val = det.readRegister(addr); @@ -3352,7 +3352,7 @@ TEST_CASE("getbit", "[.cmdcall]") { addr = 0x80; } if (det_type == defs::GOTTHARD2) { - addr = 0x20; + addr = 0x298; } std::string saddr = ToStringHex(addr); auto prev_val = det.readRegister(addr); From 4f62b1a05ccf24aafd202e2a984d2467afbbd5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Wed, 19 Mar 2025 21:49:12 +0100 Subject: [PATCH 24/82] separated the recipes --- conda-recipe/build_pylib.sh | 11 -- conda-recipe/conda_build_config.yaml | 16 --- conda-recipe/copy_ctbgui.sh | 11 -- conda-recipe/copy_lib.sh | 23 ---- conda-recipe/meta.yaml | 128 ------------------ conda-recipe/run_test.sh | 3 - .../main-library}/build.sh | 2 +- .../main-library/conda_build_config.yaml | 26 ++++ .../main-library}/copy_gui.sh | 0 conda-recipes/main-library/copy_lib.sh | 23 ++++ .../main-library}/copy_moench.sh | 0 conda-recipes/main-library/meta.yaml | 104 ++++++++++++++ .../python-client/conda_build_config.yaml | 26 ++++ conda-recipes/python-client/meta.yaml | 46 +++++++ pyproject.toml | 2 +- 15 files changed, 227 insertions(+), 194 deletions(-) delete mode 100755 conda-recipe/build_pylib.sh delete mode 100644 conda-recipe/conda_build_config.yaml delete mode 100644 conda-recipe/copy_ctbgui.sh delete mode 100755 conda-recipe/copy_lib.sh delete mode 100755 conda-recipe/meta.yaml delete mode 100755 conda-recipe/run_test.sh rename {conda-recipe => conda-recipes/main-library}/build.sh (96%) create mode 100644 conda-recipes/main-library/conda_build_config.yaml rename {conda-recipe => conda-recipes/main-library}/copy_gui.sh (100%) create mode 100755 conda-recipes/main-library/copy_lib.sh rename {conda-recipe => conda-recipes/main-library}/copy_moench.sh (100%) create mode 100755 conda-recipes/main-library/meta.yaml create mode 100644 conda-recipes/python-client/conda_build_config.yaml create mode 100644 conda-recipes/python-client/meta.yaml diff --git a/conda-recipe/build_pylib.sh b/conda-recipe/build_pylib.sh deleted file mode 100755 index 18b0615ab..000000000 --- a/conda-recipe/build_pylib.sh +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: LGPL-3.0-or-other -# Copyright (C) 2021 Contributors to the SLS Detector Package - -echo "|<-------- starting python build" - -cd python - -# copy VERSION into slsdet for installation -cp ../VERSION slsdet/VERSION - -${PYTHON} setup.py install diff --git a/conda-recipe/conda_build_config.yaml b/conda-recipe/conda_build_config.yaml deleted file mode 100644 index c953a95ed..000000000 --- a/conda-recipe/conda_build_config.yaml +++ /dev/null @@ -1,16 +0,0 @@ -python: - # - 3.8 - # - 3.9 - # - 3.10 - # - 3.11 - # - 3.12 - - 3.13 - -c_compiler_version: # [unix] - - 11 # [linux] - -cxx_compiler_version: - - 11 # [linux] - -c_stdlib_version: # [linux] - - 2.17 # [linux] \ No newline at end of file diff --git a/conda-recipe/copy_ctbgui.sh b/conda-recipe/copy_ctbgui.sh deleted file mode 100644 index b4f52efce..000000000 --- a/conda-recipe/copy_ctbgui.sh +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: LGPL-3.0-or-other -# Copyright (C) 2021 Contributors to the SLS Detector Package -mkdir $PREFIX/lib -mkdir $PREFIX/bin -mkdir $PREFIX/include - - - -cp build/bin/ctbGui $PREFIX/bin/. -cp build/bin/libctbRootLib.so $PREFIX/lib/. - diff --git a/conda-recipe/copy_lib.sh b/conda-recipe/copy_lib.sh deleted file mode 100755 index 5836146f6..000000000 --- a/conda-recipe/copy_lib.sh +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-License-Identifier: LGPL-3.0-or-other -# Copyright (C) 2021 Contributors to the SLS Detector Package - -mkdir -p $PREFIX/lib -mkdir -p $PREFIX/bin -mkdir -p $PREFIX/include/sls -# mkdir $PREFIX/include/slsDetectorPackage - -#Shared and static libraries -cp build/install/lib/* $PREFIX/lib/ - -#Binaries -cp build/install/bin/sls_detector_acquire $PREFIX/bin/. -cp build/install/bin/sls_detector_acquire_zmq $PREFIX/bin/. -cp build/install/bin/sls_detector_get $PREFIX/bin/. -cp build/install/bin/sls_detector_put $PREFIX/bin/. -cp build/install/bin/sls_detector_help $PREFIX/bin/. -cp build/install/bin/slsReceiver $PREFIX/bin/. -cp build/install/bin/slsMultiReceiver $PREFIX/bin/. - - -cp build/install/include/sls/* $PREFIX/include/sls -cp -rv build/install/share $PREFIX diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml deleted file mode 100755 index a83d42fa2..000000000 --- a/conda-recipe/meta.yaml +++ /dev/null @@ -1,128 +0,0 @@ -package: - name: sls_detector_software - version: {{ environ.get('GIT_DESCRIBE_TAG', '') }} - - -source: - path: .. - -build: - number: 0 - binary_relocation: True - rpaths: - - lib/ - -requirements: - build: - - {{ compiler('c') }} - - {{ compiler('cxx') }} - - cmake - - ninja - - qt 5.* - - xorg-libx11 - - xorg-libice - - xorg-libxext - - xorg-libsm - - xorg-libxau - - xorg-libxrender - - xorg-libxfixes - - {{ cdt('mesa-libgl-devel') }} # [linux] - - {{ cdt('mesa-libegl-devel') }} # [linux] - - {{ cdt('mesa-dri-drivers') }} # [linux] - - {{ cdt('libselinux') }} # [linux] - - {{ cdt('libxdamage') }} # [linux] - - {{ cdt('libxxf86vm') }} # [linux] - - expat - - host: - # - libstdcxx-ng - # - libgcc-ng - - xorg-libx11 - - xorg-libice - - xorg-libxext - - xorg-libsm - - xorg-libxau - - xorg-libxrender - - xorg-libxfixes - - expat - - libtiff - - libpng - - run: - # - libstdcxx-ng - # - libgcc-ng - - -outputs: - - name: slsdetlib - script: copy_lib.sh - - requirements: - build: - - {{ compiler('c') }} - - {{compiler('cxx')}} - # - libstdcxx-ng - # - libgcc-ng - - run: - # - libstdcxx-ng - # - libgcc-ng - - # - name: slsdet - # script: build_pylib.sh - - # requirements: - # build: - # - python - # - {{ compiler('c') }} - # - {{compiler('cxx')}} - # - {{ pin_subpackage('slsdetlib', exact=True) }} - # - setuptools - # - pybind11=2.13 - - # host: - # - python - # - {{ pin_subpackage('slsdetlib', exact=True) }} - # - setuptools - # - pybind11=2.13 - - - # run: - # - libstdcxx-ng - # - libgcc-ng - # - python - # - numpy - # - {{ pin_subpackage('slsdetlib', exact=True) }} - - # test: - # imports: - # - slsdet - - - # - name: slsdetgui - # script: copy_gui.sh - # requirements: - - # build: - # - {{ compiler('c') }} - # - {{compiler('cxx')}} - # - {{ pin_subpackage('slsdetlib', exact=True) }} - - # run: - # - {{ pin_subpackage('slsdetlib', exact=True) }} - # - qt 5.* - # - expat - - # - name: moenchzmq - # script: copy_moench.sh - # requirements: - - # build: - # - {{ compiler('c') }} - # - {{compiler('cxx')}} - # - {{ pin_subpackage('slsdetlib', exact=True) }} - - - # run: - # - {{ pin_subpackage('slsdetlib', exact=True) }} - # - expat \ No newline at end of file diff --git a/conda-recipe/run_test.sh b/conda-recipe/run_test.sh deleted file mode 100755 index 24068d625..000000000 --- a/conda-recipe/run_test.sh +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: LGPL-3.0-or-other -# Copyright (C) 2021 Contributors to the SLS Detector Package -ctest -j2 \ No newline at end of file diff --git a/conda-recipe/build.sh b/conda-recipes/main-library/build.sh similarity index 96% rename from conda-recipe/build.sh rename to conda-recipes/main-library/build.sh index 5c3995d91..f2505361a 100755 --- a/conda-recipe/build.sh +++ b/conda-recipes/main-library/build.sh @@ -13,7 +13,7 @@ cmake .. -G Ninja \ -DCMAKE_INSTALL_PREFIX=install \ -DSLS_USE_TEXTCLIENT=ON \ -DSLS_USE_RECEIVER=ON \ - -DSLS_USE_GUI=OFF \ + -DSLS_USE_GUI=ON \ -DSLS_USE_MOENCH=ON\ -DSLS_USE_TESTS=ON \ -DSLS_USE_PYTHON=OFF \ diff --git a/conda-recipes/main-library/conda_build_config.yaml b/conda-recipes/main-library/conda_build_config.yaml new file mode 100644 index 000000000..46fa5230e --- /dev/null +++ b/conda-recipes/main-library/conda_build_config.yaml @@ -0,0 +1,26 @@ +python: + # - 3.8 + # - 3.9 + # - 3.10 + # - 3.11 + # - 3.12 + - 3.13 + +c_compiler: + - gcc # [linux] + +c_compiler_version: + - 13 # [linux] + +c_stdlib: + - sysroot # [linux] + +cxx_compiler: + - gxx # [linux] + + +cxx_compiler_version: + - 13 # [linux] + +c_stdlib_version: # [linux] + - 2.17 # [linux] \ No newline at end of file diff --git a/conda-recipe/copy_gui.sh b/conda-recipes/main-library/copy_gui.sh similarity index 100% rename from conda-recipe/copy_gui.sh rename to conda-recipes/main-library/copy_gui.sh diff --git a/conda-recipes/main-library/copy_lib.sh b/conda-recipes/main-library/copy_lib.sh new file mode 100755 index 000000000..ad5de9f47 --- /dev/null +++ b/conda-recipes/main-library/copy_lib.sh @@ -0,0 +1,23 @@ +# # SPDX-License-Identifier: LGPL-3.0-or-other +# # Copyright (C) 2021 Contributors to the SLS Detector Package + +# mkdir -p $PREFIX/lib +# mkdir -p $PREFIX/bin +# mkdir -p $PREFIX/include/sls +# # mkdir $PREFIX/include/slsDetectorPackage + +# #Shared and static libraries +# cp build/install/lib/* $PREFIX/lib/ + +# #Binaries +# cp build/install/bin/sls_detector_acquire $PREFIX/bin/. +# cp build/install/bin/sls_detector_acquire_zmq $PREFIX/bin/. +# cp build/install/bin/sls_detector_get $PREFIX/bin/. +# cp build/install/bin/sls_detector_put $PREFIX/bin/. +# cp build/install/bin/sls_detector_help $PREFIX/bin/. +# cp build/install/bin/slsReceiver $PREFIX/bin/. +# cp build/install/bin/slsMultiReceiver $PREFIX/bin/. + + +# cp build/install/include/sls/* $PREFIX/include/sls +# cp -rv build/install/share $PREFIX diff --git a/conda-recipe/copy_moench.sh b/conda-recipes/main-library/copy_moench.sh similarity index 100% rename from conda-recipe/copy_moench.sh rename to conda-recipes/main-library/copy_moench.sh diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml new file mode 100755 index 000000000..762ce7d9f --- /dev/null +++ b/conda-recipes/main-library/meta.yaml @@ -0,0 +1,104 @@ +package: + name: sls_detector_software + version: 2025.3.19 + + +source: + path: ../.. + +build: + number: 0 + binary_relocation: True + rpaths: + - lib/ + +requirements: + build: + - {{ compiler('c') }} + - {{ stdlib("c") }} + - {{ compiler('cxx') }} + + - cmake + - ninja + - qt 5.* + # - xorg-libx11 + # - xorg-libice + # - xorg-libxext + # - xorg-libsm + # - xorg-libxau + # - xorg-libxrender + # - xorg-libxfixes + # - {{ cdt('mesa-libgl-devel') }} # [linux] + # - {{ cdt('mesa-libegl-devel') }} # [linux] + # - {{ cdt('mesa-dri-drivers') }} # [linux] + # - {{ cdt('libselinux') }} # [linux] + # - {{ cdt('libxdamage') }} # [linux] + # - {{ cdt('libxxf86vm') }} # [linux] + # - expat + + host: + - libstdcxx-ng + - libgcc-ng + - libgl-devel # [linux] + # - xorg-libx11 + # - xorg-libice + # - xorg-libxext + # - xorg-libsm + # - xorg-libxau + # - xorg-libxrender + # - xorg-libxfixes + # - expat + - libtiff + # - libpng + + run: + # - libstdcxx-ng + # - libgcc-ng + + +outputs: + - name: slsdetlib + script: copy_lib.sh + + requirements: + build: + - {{ compiler('c') }} + - {{ stdlib("c") }} + - {{ compiler('cxx') }} + # - libstdcxx-ng + # - libgcc-ng + + run: + # - libstdcxx-ng + # - libgcc-ng + + + + + - name: slsdetgui + script: copy_gui.sh + requirements: + + build: + - {{ compiler('c') }} + - {{compiler('cxx')}} + - {{ pin_subpackage('slsdetlib', exact=True) }} + + run: + - {{ pin_subpackage('slsdetlib', exact=True) }} + - qt 5.* + - expat + + - name: moenchzmq + script: copy_moench.sh + requirements: + + build: + - {{ compiler('c') }} + - {{compiler('cxx')}} + - {{ pin_subpackage('slsdetlib', exact=True) }} + + + run: + - {{ pin_subpackage('slsdetlib', exact=True) }} + - expat \ No newline at end of file diff --git a/conda-recipes/python-client/conda_build_config.yaml b/conda-recipes/python-client/conda_build_config.yaml new file mode 100644 index 000000000..46fa5230e --- /dev/null +++ b/conda-recipes/python-client/conda_build_config.yaml @@ -0,0 +1,26 @@ +python: + # - 3.8 + # - 3.9 + # - 3.10 + # - 3.11 + # - 3.12 + - 3.13 + +c_compiler: + - gcc # [linux] + +c_compiler_version: + - 13 # [linux] + +c_stdlib: + - sysroot # [linux] + +cxx_compiler: + - gxx # [linux] + + +cxx_compiler_version: + - 13 # [linux] + +c_stdlib_version: # [linux] + - 2.17 # [linux] \ No newline at end of file diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml new file mode 100644 index 000000000..9add4b13b --- /dev/null +++ b/conda-recipes/python-client/meta.yaml @@ -0,0 +1,46 @@ +package: + name: slsdet + version: 2025.2.18 #TODO! how to not duplicate this? + +source: + path: ../.. + +build: + number: 0 + script: + - unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv # [not win] + - {{ PYTHON }} -m pip install . -vv # [win] + +requirements: + build: + - python {{python}} + - {{ compiler('c') }} + - {{ stdlib("c") }} + - {{ compiler('cxx') }} + + + host: + - cmake + - ninja + - python {{python}} + - pip + - scikit-build-core + - pybind11 >=2.13.0 + - fmt + - zeromq + - nlohmann_json + - catch2 + + run: + - python {{python}} + - numpy + + +test: + imports: + - slsdet + + +about: + summary: An example project built with pybind11 and scikit-build. + # license_file: LICENSE \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index df5a2a852..35709dae1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build" [project] name = "slsdet" -version = "2025.2.18" +version = "2025.3.19" [tool.scikit-build] From a0d540fd72c6af1b2ff985a9b22fafdbe76364bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Wed, 19 Mar 2025 21:59:30 +0100 Subject: [PATCH 25/82] restored comments, cleanup --- CMakeLists.txt | 7 +- conda-recipes/main-library/build.sh | 1 - conda-recipes/main-library/copy_lib.sh | 35 ++- .../tests/test-SharedMemory.cpp | 236 +++++++++--------- 4 files changed, 136 insertions(+), 143 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f3055e34f..0aa6dcd5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,6 @@ set(PROJECT_VERSION ${PROJECT_VERSION_STRING}) add_compile_definitions(SLS_DET_VERSION="${PROJECT_VERSION}") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) cmake_policy(SET CMP0074 NEW) @@ -31,9 +29,6 @@ include(FetchContent) option(SLS_FETCH_ZMQ_FROM_GITHUB "Fetch zmq from github" OFF) option(SLS_FETCH_PYBIND11_FROM_GITHUB "Fetch pybind11 from github" OFF) -if(${SKBUILD}) - message(STATUS "Building with scikit-build") -endif() if(SLS_FETCH_ZMQ_FROM_GITHUB) # Opt in to pull down a zmq version from github instead of @@ -202,7 +197,7 @@ endif() # to control options for the libraries if(NOT TARGET slsProjectOptions) add_library(slsProjectOptions INTERFACE) -# target_compile_features(slsProjectOptions INTERFACE cxx_std_11) + target_compile_features(slsProjectOptions INTERFACE cxx_std_11) endif() if (NOT TARGET slsProjectWarnings) diff --git a/conda-recipes/main-library/build.sh b/conda-recipes/main-library/build.sh index f2505361a..730271b6e 100755 --- a/conda-recipes/main-library/build.sh +++ b/conda-recipes/main-library/build.sh @@ -25,5 +25,4 @@ echo "Building using: ${NCORES} cores" cmake --build . -- -j${NCORES} cmake --build . --target install -export SLSDETNAME=automated_tests CTEST_OUTPUT_ON_FAILURE=1 ctest -j 1 diff --git a/conda-recipes/main-library/copy_lib.sh b/conda-recipes/main-library/copy_lib.sh index ad5de9f47..72343b565 100755 --- a/conda-recipes/main-library/copy_lib.sh +++ b/conda-recipes/main-library/copy_lib.sh @@ -1,23 +1,22 @@ -# # SPDX-License-Identifier: LGPL-3.0-or-other -# # Copyright (C) 2021 Contributors to the SLS Detector Package +# SPDX-License-Identifier: LGPL-3.0-or-other +# Copyright (C) 2021 Contributors to the SLS Detector Package -# mkdir -p $PREFIX/lib -# mkdir -p $PREFIX/bin -# mkdir -p $PREFIX/include/sls -# # mkdir $PREFIX/include/slsDetectorPackage +mkdir -p $PREFIX/lib +mkdir -p $PREFIX/bin +mkdir -p $PREFIX/include/sls -# #Shared and static libraries -# cp build/install/lib/* $PREFIX/lib/ +#Shared and static libraries +cp build/install/lib/* $PREFIX/lib/ -# #Binaries -# cp build/install/bin/sls_detector_acquire $PREFIX/bin/. -# cp build/install/bin/sls_detector_acquire_zmq $PREFIX/bin/. -# cp build/install/bin/sls_detector_get $PREFIX/bin/. -# cp build/install/bin/sls_detector_put $PREFIX/bin/. -# cp build/install/bin/sls_detector_help $PREFIX/bin/. -# cp build/install/bin/slsReceiver $PREFIX/bin/. -# cp build/install/bin/slsMultiReceiver $PREFIX/bin/. +#Binaries +cp build/install/bin/sls_detector_acquire $PREFIX/bin/. +cp build/install/bin/sls_detector_acquire_zmq $PREFIX/bin/. +cp build/install/bin/sls_detector_get $PREFIX/bin/. +cp build/install/bin/sls_detector_put $PREFIX/bin/. +cp build/install/bin/sls_detector_help $PREFIX/bin/. +cp build/install/bin/slsReceiver $PREFIX/bin/. +cp build/install/bin/slsMultiReceiver $PREFIX/bin/. -# cp build/install/include/sls/* $PREFIX/include/sls -# cp -rv build/install/share $PREFIX +cp build/install/include/sls/* $PREFIX/include/sls +cp -rv build/install/share $PREFIX diff --git a/slsDetectorSoftware/tests/test-SharedMemory.cpp b/slsDetectorSoftware/tests/test-SharedMemory.cpp index b16a41b25..5ba3c20a2 100644 --- a/slsDetectorSoftware/tests/test-SharedMemory.cpp +++ b/slsDetectorSoftware/tests/test-SharedMemory.cpp @@ -17,155 +17,155 @@ struct Data { constexpr int shm_id = 10; -// TEST_CASE("Create SharedMemory read and write", "[detector]") { +TEST_CASE("Create SharedMemory read and write", "[detector]") { -// SharedMemory shm(shm_id, -1); -// shm.createSharedMemory(); -// CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + -// std::to_string(shm_id)); + SharedMemory shm(shm_id, -1); + shm.createSharedMemory(); + CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + + std::to_string(shm_id)); -// shm()->x = 3; -// shm()->y = 5.7; -// strcpy_safe(shm()->mess, "Some string"); + shm()->x = 3; + shm()->y = 5.7; + strcpy_safe(shm()->mess, "Some string"); -// CHECK(shm()->x == 3); -// CHECK(shm()->y == 5.7); -// CHECK(std::string(shm()->mess) == "Some string"); + CHECK(shm()->x == 3); + CHECK(shm()->y == 5.7); + CHECK(std::string(shm()->mess) == "Some string"); -// shm.unmapSharedMemory(); -// shm.removeSharedMemory(); + shm.unmapSharedMemory(); + shm.removeSharedMemory(); -// CHECK(shm.exists() == false); -// } + CHECK(shm.exists() == false); +} -// TEST_CASE("Open existing SharedMemory and read", "[detector]") { +TEST_CASE("Open existing SharedMemory and read", "[detector]") { -// { -// SharedMemory shm(shm_id, -1); -// shm.createSharedMemory(); -// *shm() = 5.3; -// } + { + SharedMemory shm(shm_id, -1); + shm.createSharedMemory(); + *shm() = 5.3; + } -// SharedMemory shm2(shm_id, -1); -// shm2.openSharedMemory(true); -// CHECK(*shm2() == 5.3); + SharedMemory shm2(shm_id, -1); + shm2.openSharedMemory(true); + CHECK(*shm2() == 5.3); -// shm2.removeSharedMemory(); -// } + shm2.removeSharedMemory(); +} -// TEST_CASE("Creating a second shared memory with the same name throws", -// "[detector]") { +TEST_CASE("Creating a second shared memory with the same name throws", + "[detector]") { -// SharedMemory shm0(shm_id, -1); -// SharedMemory shm1(shm_id, -1); + SharedMemory shm0(shm_id, -1); + SharedMemory shm1(shm_id, -1); -// shm0.createSharedMemory(); -// CHECK_THROWS(shm1.createSharedMemory()); -// shm0.removeSharedMemory(); -// } + shm0.createSharedMemory(); + CHECK_THROWS(shm1.createSharedMemory()); + shm0.removeSharedMemory(); +} -// TEST_CASE("Open two shared memories to the same place", "[detector]") { +TEST_CASE("Open two shared memories to the same place", "[detector]") { -// // Create the first shared memory -// SharedMemory shm(shm_id, -1); -// shm.createSharedMemory(); -// shm()->x = 5; -// CHECK(shm()->x == 5); + // Create the first shared memory + SharedMemory shm(shm_id, -1); + shm.createSharedMemory(); + shm()->x = 5; + CHECK(shm()->x == 5); -// // Open the second shared memory with the same name -// SharedMemory shm2(shm_id, -1); -// shm2.openSharedMemory(true); -// CHECK(shm2()->x == 5); -// CHECK(shm.getName() == shm2.getName()); + // Open the second shared memory with the same name + SharedMemory shm2(shm_id, -1); + shm2.openSharedMemory(true); + CHECK(shm2()->x == 5); + CHECK(shm.getName() == shm2.getName()); -// // Check that they still point to the same place -// shm2()->x = 7; -// CHECK(shm()->x == 7); + // Check that they still point to the same place + shm2()->x = 7; + CHECK(shm()->x == 7); -// // Remove only needs to be done once since they refer -// // to the same memory -// shm2.removeSharedMemory(); -// CHECK(shm.exists() == false); -// CHECK(shm2.exists() == false); -// } + // Remove only needs to be done once since they refer + // to the same memory + shm2.removeSharedMemory(); + CHECK(shm.exists() == false); + CHECK(shm2.exists() == false); +} -// TEST_CASE("Move SharedMemory", "[detector]") { +TEST_CASE("Move SharedMemory", "[detector]") { -// SharedMemory shm(shm_id, -1); -// CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + -// std::to_string(shm_id)); -// shm.createSharedMemory(); -// shm()->x = 9; + SharedMemory shm(shm_id, -1); + CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + + std::to_string(shm_id)); + shm.createSharedMemory(); + shm()->x = 9; -// SharedMemory shm2(shm_id + 1, -1); -// shm2 = std::move(shm); // shm is now a moved from object! + SharedMemory shm2(shm_id + 1, -1); + shm2 = std::move(shm); // shm is now a moved from object! -// CHECK(shm2()->x == 9); -// REQUIRE_THROWS( -// shm()); // trying to access should throw instead of returning a nullptr -// CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") + -// std::to_string(shm_id)); -// shm2.removeSharedMemory(); -// } + CHECK(shm2()->x == 9); + REQUIRE_THROWS( + shm()); // trying to access should throw instead of returning a nullptr + CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") + + std::to_string(shm_id)); + shm2.removeSharedMemory(); +} -// TEST_CASE("Create several shared memories", "[detector]") { -// constexpr int N = 5; -// std::vector> v; -// v.reserve(N); -// for (int i = 0; i != N; ++i) { -// v.emplace_back(shm_id + i, -1); -// CHECK(v[i].exists() == false); -// v[i].createSharedMemory(); -// *v[i]() = i; -// CHECK(*v[i]() == i); -// } +TEST_CASE("Create several shared memories", "[detector]") { + constexpr int N = 5; + std::vector> v; + v.reserve(N); + for (int i = 0; i != N; ++i) { + v.emplace_back(shm_id + i, -1); + CHECK(v[i].exists() == false); + v[i].createSharedMemory(); + *v[i]() = i; + CHECK(*v[i]() == i); + } -// for (int i = 0; i != N; ++i) { -// CHECK(*v[i]() == i); -// CHECK(v[i].getName() == std::string("/slsDetectorPackage_detector_") + -// std::to_string(i + shm_id)); -// } + for (int i = 0; i != N; ++i) { + CHECK(*v[i]() == i); + CHECK(v[i].getName() == std::string("/slsDetectorPackage_detector_") + + std::to_string(i + shm_id)); + } -// for (int i = 0; i != N; ++i) { -// v[i].removeSharedMemory(); -// CHECK(v[i].exists() == false); -// } -// } + for (int i = 0; i != N; ++i) { + v[i].removeSharedMemory(); + CHECK(v[i].exists() == false); + } +} -// TEST_CASE("Create create a shared memory with a tag") { -// SharedMemory shm(0, -1, "ctbdacs"); -// REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_ctbdacs"); -// } +TEST_CASE("Create create a shared memory with a tag") { + SharedMemory shm(0, -1, "ctbdacs"); + REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_ctbdacs"); +} -// TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set") { +TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set") { -// // if SLSDETNAME is already set we unset it but -// // save the value -// std::string old_slsdetname; -// if (getenv(SHM_ENV_NAME)) -// old_slsdetname = getenv(SHM_ENV_NAME); -// unsetenv(SHM_ENV_NAME); -// setenv(SHM_ENV_NAME, "myprefix", 1); + // if SLSDETNAME is already set we unset it but + // save the value + std::string old_slsdetname; + if (getenv(SHM_ENV_NAME)) + old_slsdetname = getenv(SHM_ENV_NAME); + unsetenv(SHM_ENV_NAME); + setenv(SHM_ENV_NAME, "myprefix", 1); -// SharedMemory shm(0, -1, "ctbdacs"); -// REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_myprefix_ctbdacs"); + SharedMemory shm(0, -1, "ctbdacs"); + REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_myprefix_ctbdacs"); -// // Clean up after us -// if (old_slsdetname.empty()) -// unsetenv(SHM_ENV_NAME); -// else -// setenv(SHM_ENV_NAME, old_slsdetname.c_str(), 1); -// } + // Clean up after us + if (old_slsdetname.empty()) + unsetenv(SHM_ENV_NAME); + else + setenv(SHM_ENV_NAME, old_slsdetname.c_str(), 1); +} -// TEST_CASE("map int64 to int32 throws") { -// SharedMemory shm(shm_id, -1); -// shm.createSharedMemory(); -// *shm() = 7; +TEST_CASE("map int64 to int32 throws") { + SharedMemory shm(shm_id, -1); + shm.createSharedMemory(); + *shm() = 7; -// SharedMemory shm2(shm_id, -1); -// REQUIRE_THROWS(shm2.openSharedMemory(true)); + SharedMemory shm2(shm_id, -1); + REQUIRE_THROWS(shm2.openSharedMemory(true)); -// shm.removeSharedMemory(); -// } + shm.removeSharedMemory(); +} } // namespace sls From 608eb1a4364568b9ff2b765033b3901a1d975037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Wed, 19 Mar 2025 22:03:22 +0100 Subject: [PATCH 26/82] cleaned meta yaml --- conda-recipes/main-library/meta.yaml | 36 ++++------------------------ 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index 762ce7d9f..cdbe70405 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -21,39 +21,16 @@ requirements: - cmake - ninja - qt 5.* - # - xorg-libx11 - # - xorg-libice - # - xorg-libxext - # - xorg-libsm - # - xorg-libxau - # - xorg-libxrender - # - xorg-libxfixes - # - {{ cdt('mesa-libgl-devel') }} # [linux] - # - {{ cdt('mesa-libegl-devel') }} # [linux] - # - {{ cdt('mesa-dri-drivers') }} # [linux] - # - {{ cdt('libselinux') }} # [linux] - # - {{ cdt('libxdamage') }} # [linux] - # - {{ cdt('libxxf86vm') }} # [linux] - # - expat host: - libstdcxx-ng - libgcc-ng - libgl-devel # [linux] - # - xorg-libx11 - # - xorg-libice - # - xorg-libxext - # - xorg-libsm - # - xorg-libxau - # - xorg-libxrender - # - xorg-libxfixes - # - expat - libtiff - # - libpng run: - # - libstdcxx-ng - # - libgcc-ng + - libstdcxx-ng + - libgcc-ng outputs: @@ -65,12 +42,10 @@ outputs: - {{ compiler('c') }} - {{ stdlib("c") }} - {{ compiler('cxx') }} - # - libstdcxx-ng - # - libgcc-ng run: - # - libstdcxx-ng - # - libgcc-ng + - libstdcxx-ng + - libgcc-ng @@ -87,7 +62,7 @@ outputs: run: - {{ pin_subpackage('slsdetlib', exact=True) }} - qt 5.* - - expat + - name: moenchzmq script: copy_moench.sh @@ -101,4 +76,3 @@ outputs: run: - {{ pin_subpackage('slsdetlib', exact=True) }} - - expat \ No newline at end of file From 0da508a8b7c2dd2b525d7fd5ec9e2ddd03b28df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Wed, 19 Mar 2025 22:05:19 +0100 Subject: [PATCH 27/82] added back some python versions --- conda-recipes/main-library/conda_build_config.yaml | 7 ------- conda-recipes/python-client/conda_build_config.yaml | 7 ++----- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/conda-recipes/main-library/conda_build_config.yaml b/conda-recipes/main-library/conda_build_config.yaml index 46fa5230e..2bf732748 100644 --- a/conda-recipes/main-library/conda_build_config.yaml +++ b/conda-recipes/main-library/conda_build_config.yaml @@ -1,10 +1,3 @@ -python: - # - 3.8 - # - 3.9 - # - 3.10 - # - 3.11 - # - 3.12 - - 3.13 c_compiler: - gcc # [linux] diff --git a/conda-recipes/python-client/conda_build_config.yaml b/conda-recipes/python-client/conda_build_config.yaml index 46fa5230e..264e093ef 100644 --- a/conda-recipes/python-client/conda_build_config.yaml +++ b/conda-recipes/python-client/conda_build_config.yaml @@ -1,9 +1,6 @@ python: - # - 3.8 - # - 3.9 - # - 3.10 - # - 3.11 - # - 3.12 + - 3.11 + - 3.12 - 3.13 c_compiler: From 8b3625fc011ac4694d959fefae24225942329088 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Thu, 20 Mar 2025 11:00:40 +0100 Subject: [PATCH 28/82] 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 0b3ead6353a78b2eef86a60c7b05f89fe6bcea05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Thu, 20 Mar 2025 13:10:27 +0100 Subject: [PATCH 29/82] conda build of main library --- .github/workflows/conda_library.yml | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/conda_library.yml diff --git a/.github/workflows/conda_library.yml b/.github/workflows/conda_library.yml new file mode 100644 index 000000000..e1f3082c2 --- /dev/null +++ b/.github/workflows/conda_library.yml @@ -0,0 +1,42 @@ +name: Build slsdetlib + +on: [pull_request] + +jobs: + build: + strategy: + fail-fast: false + matrix: + platform: [ubuntu-latest, ] # macos-12, windows-2019] + python-version: ["3.12",] + + runs-on: ${{ matrix.platform }} + + # The setup-miniconda action needs this to activate miniconda + defaults: + run: + shell: "bash -l {0}" + + steps: + - uses: actions/checkout@v4 + + - name: Get conda + uses: conda-incubator/setup-miniconda@v3.0.4 + with: + python-version: ${{ matrix.python-version }} + channels: conda-forge + + - name: Prepare + run: conda install conda-build=24.9 conda-verify pytest anaconda-client + + - name: Disable upload + run: conda config --set anaconda_upload no + + - name: Build + run: conda build conda-recipe/main-library --output-folder build_output + + - name: Upload all Conda packages + uses: actions/upload-artifact@v4 + with: + name: conda-packages + path: build_output/** # Uploads all packages \ No newline at end of file From 9f49ac6457d9a98dbb525c671edf68c58a9e54f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Thu, 20 Mar 2025 13:12:42 +0100 Subject: [PATCH 30/82] fixed typo --- .github/workflows/conda_library.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conda_library.yml b/.github/workflows/conda_library.yml index e1f3082c2..9cffbd74b 100644 --- a/.github/workflows/conda_library.yml +++ b/.github/workflows/conda_library.yml @@ -33,7 +33,7 @@ jobs: run: conda config --set anaconda_upload no - name: Build - run: conda build conda-recipe/main-library --output-folder build_output + run: conda build conda-recipes/main-library --output-folder build_output - name: Upload all Conda packages uses: actions/upload-artifact@v4 From c3b197f2094aa2198fd7c178090c58b6db48aa60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Thu, 20 Mar 2025 13:28:46 +0100 Subject: [PATCH 31/82] removed conda build pin --- .github/workflows/conda_library.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conda_library.yml b/.github/workflows/conda_library.yml index 9cffbd74b..23f94d467 100644 --- a/.github/workflows/conda_library.yml +++ b/.github/workflows/conda_library.yml @@ -27,7 +27,7 @@ jobs: channels: conda-forge - name: Prepare - run: conda install conda-build=24.9 conda-verify pytest anaconda-client + run: conda install conda-build conda-verify pytest anaconda-client - name: Disable upload run: conda config --set anaconda_upload no From 6dd0a5b0dd821a1971fb8363339e7b02df888c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Thu, 20 Mar 2025 13:39:51 +0100 Subject: [PATCH 32/82] added zlib --- conda-recipes/main-library/build.sh | 2 +- conda-recipes/main-library/meta.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/conda-recipes/main-library/build.sh b/conda-recipes/main-library/build.sh index 730271b6e..229067c3b 100755 --- a/conda-recipes/main-library/build.sh +++ b/conda-recipes/main-library/build.sh @@ -18,7 +18,7 @@ cmake .. -G Ninja \ -DSLS_USE_TESTS=ON \ -DSLS_USE_PYTHON=OFF \ -DCMAKE_BUILD_TYPE=Release \ - -DSLS_USE_HDF5=OFF\ + -DSLS_USE_HDF5=OFF \ NCORES=$(getconf _NPROCESSORS_ONLN) echo "Building using: ${NCORES} cores" diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index cdbe70405..87a9a4f50 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -27,6 +27,7 @@ requirements: - libgcc-ng - libgl-devel # [linux] - libtiff + - zlib run: - libstdcxx-ng From fada23365e1740a9287d2321c221d251f1a9af13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=B6jd=20Lars=20Erik?= Date: Thu, 20 Mar 2025 13:56:46 +0100 Subject: [PATCH 33/82] added workflow for python lib --- .github/workflows/cmake.yml | 2 +- .github/workflows/conda_python.yml | 42 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/conda_python.yml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 9826f4b13..5e99d1f35 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -1,4 +1,4 @@ -name: CMake +name: Native CMake Build on: [push, pull_request] diff --git a/.github/workflows/conda_python.yml b/.github/workflows/conda_python.yml new file mode 100644 index 000000000..d482b8e6f --- /dev/null +++ b/.github/workflows/conda_python.yml @@ -0,0 +1,42 @@ +name: slsdet + +on: [pull_request] + +jobs: + build: + strategy: + fail-fast: false + matrix: + platform: [ubuntu-latest, ] # macos-12, windows-2019] + python-version: ["3.12",] + + runs-on: ${{ matrix.platform }} + + # The setup-miniconda action needs this to activate miniconda + defaults: + run: + shell: "bash -l {0}" + + steps: + - uses: actions/checkout@v4 + + - name: Get conda + uses: conda-incubator/setup-miniconda@v3.0.4 + with: + python-version: ${{ matrix.python-version }} + channels: conda-forge + + - name: Prepare + run: conda install conda-build conda-verify pytest anaconda-client + + - name: Disable upload + run: conda config --set anaconda_upload no + + - name: Build + run: conda build conda-recipes/python-client --output-folder build_output + + - name: Upload all Conda packages + uses: actions/upload-artifact@v4 + with: + name: conda-packages + path: build_output/** # Uploads all packages \ No newline at end of file From 713e4f6822283fe26ae6a664b5e0c4f56a5701fc Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Thu, 20 Mar 2025 11:00:40 +0100 Subject: [PATCH 34/82] 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 35/82] 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 dc8a34592a3202b9f1c8cbec67c5716b9eb876b7 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Thu, 27 Mar 2025 17:03:36 +0100 Subject: [PATCH 36/82] started pattern docu --- docs/CMakeLists.txt | 1 + docs/src/index.rst | 1 + docs/src/pattern.rst | 96 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 docs/src/pattern.rst diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 861debc58..19f09b884 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -54,6 +54,7 @@ set(SPHINX_SOURCE_FILES src/serverdefaults.rst src/quick_start_guide.rst src/troubleshooting.rst + src/pattern.rst src/receivers.rst src/slsreceiver.rst src/udpheader.rst diff --git a/docs/src/index.rst b/docs/src/index.rst index aca6e711c..206b08eef 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -37,6 +37,7 @@ Welcome to slsDetectorPackage's documentation! pyenums pyexamples pyPatternGenerator + pattern .. toctree:: :caption: Command line diff --git a/docs/src/pattern.rst b/docs/src/pattern.rst new file mode 100644 index 000000000..c9548af1b --- /dev/null +++ b/docs/src/pattern.rst @@ -0,0 +1,96 @@ +Pattern +======================== + +This is a test and development feature implemented only for Ctb, Xilinx_Ctb and Mythen3. + +A pattern is a sequence of 64-bit words which is executed using a clock on the FPGA. Each of the 64 bits is connected to a pin or internal signal of the FPGA. The purpose of a pattern is to provide a way to change these 64 signals with precise timing. Commands run by the detector server could manipulate the same signals as the pattern, but they cannot enforce a change in a specific clock cycle. + +**Usage** + +A pattern is written to memory on the FPGA using the patword command. + +.. code-block:: + + patword 0x0000 0x000000000000000A + patword 0x0001 0x000000000000000B + patword 0x0002 0x000000000000000C + patword 0x0003 0x000000000000000D + patword 0x0004 0x000000000000000E + +The example above writes a five-word pattern into FPGA memory. The first argument is the memory address, the second argument is the content to be written into this address. Before executing a pattern one has to set the address limits of the pattern: + +.. code-block:: + + patlimits 0x0000 0x0004 + +This instructs the firmware to execute the commands from address 0 to 4 (including 0 and 4). The execution can be started from the GUI or with the commands + +.. code-block:: + + start [Ctb, Xilinx_Ctb] + patternstart [Mythen3] + +The maximal number of patword addresses is 8192. However, it is possible to extend the length of the pattern sequence using loops and wait commands. Loops can be configured with the following commands: + +.. code-block:: + + patloop 0 0x0001 0x0003 + patnloop 0 7 + +The first argument of both commands is the ID of the loop. Ctb and Xilinx_Ctb can have 6 loops (ID 0-5), Mythen3 can have 4 loop definitions. The commands above configure the loop with ID 0 to run 7 times and jump from the patword with address 3 to the patword with address 1. Important: if patnloop is set to 1 the addesses 0x1-0x3 will execute exactly once, if it is set to 0 the pattern addresses will be skipped. + +The same idea is used to introduce wait times. The example below causes the patword at address 0x0002 to be active for 9 clock cycles before the execution continues. + +.. code-block:: + + patwait 0 0x0002 + patwaittime 0 9 + +Waits can be placed inside a loop and loops can be nested. + +**patioctrl** + +The function of each bit in the sequence of 64-bit words depends on the connected detector and firmware version. Some of the 64 bits might connect directly to pads of a chip. The patioctrl command is used to configure the direction of some of these signals (not all of them !! See tables below). Signals where the corresponding bit in the argument of patioctrl is set to 1 will be driveen from the FPGA. + +**patsetbit and patmask** + +The functions patsetbit and patmask can be used to ignore a specific bit of the pattern. +Example: +.. code-block:: + + patmask 0x0101 + patsetbit 0x0001 + +Patmask configures bit 0 and 8 of the pattern to be set to their value in patsetbit. These bits will be ignored during pattern execution and will always be 0 (bit 8) and 1 (bit 0). + +**CTB Pattern Bit Positions** + +.. table:: + + +----+---+------+----+----------+-------------------+----------------+ + | 63 | 62| 61-57| 56 | 55-48 | 47-32 | 31-0 | + +----+---+------+----+----------+-------------------+----------------+ + | A | D| --- | T | EXTIO | DO, stream source | DIO | + +----+---+------+----+----------+-------------------+----------------+ + +DIO: Driving the 32 FPGA pins corresponding to the lowest 32 bits of the patioctrl command. If bits in patioctrl are 0, the same bit positions in DIO will switch to input pins and connect to dbit sampling. Additionally, some of these 32 bits have an automatic override by detector-specific statemachines which is active whenever these sm's are running (currently bits 7,8,11,14 and 20). + +DO: Directly connected to 16 FPGA pins. Output only. Not influenced by patioctrl. Also connected to bit 47-32 in all Ctb dbit samples. All of them can be used as dbit sample trigger. In Addition, every bit of DO can be selected as trigger for sending out a udp packet with samples to the receiver. + +EXTIO: Similar to DIO, but not used as input to the fpga. With the corresponding patioctrl bits set to 0 these pins will switch to a high impedance mode and be ignored by the firmware. + +T: Driving the trigger output + +D: enable signal for digital sampling + +A: adc enable + +Connections of the signals above to actual pads of a chip depend on the layout of the used detector adapter board. + +**Xilinx_CTB Pattern Positions** + +TODO + +**Mythen3 Pattern Positions** + +TODO From dc85a4886481e1f70ce6744b8af83c281a9cd6ff Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Thu, 27 Mar 2025 18:03:02 +0100 Subject: [PATCH 37/82] update xilinxCtb pattern bit mapping --- docs/src/pattern.rst | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/src/pattern.rst b/docs/src/pattern.rst index c9548af1b..b45b361c6 100644 --- a/docs/src/pattern.rst +++ b/docs/src/pattern.rst @@ -63,7 +63,7 @@ Example: Patmask configures bit 0 and 8 of the pattern to be set to their value in patsetbit. These bits will be ignored during pattern execution and will always be 0 (bit 8) and 1 (bit 0). -**CTB Pattern Bit Positions** +**CTB Pattern Bit Mapping** .. table:: @@ -87,10 +87,19 @@ A: adc enable Connections of the signals above to actual pads of a chip depend on the layout of the used detector adapter board. -**Xilinx_CTB Pattern Positions** - -TODO - -**Mythen3 Pattern Positions** +**Xilinx_CTB Pattern Bit Mapping** + +.. table:: + + +-------+----------------+ + | 63-32 | 31-0 | + +-------+----------------+ + | --- | DIO | + +-------+----------------+ + +DIO: Driving the 32 FPGA pins corresponding to the lowest 32 bits of the patioctrl command. If bits in patioctrl are 0, the same bit positions in DIO will switch to input pins and connect to dbit sampling. Additionally, some of these 32 bits have an automatic override by detector-specific statemachines which is active whenever these sm's are running (currently bits 7,8,11,14 and 20). + + +**Mythen3 Pattern Bit Mapping** TODO From b5c82783d63f4103c8f4ae7ecd644570a4082120 Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Fri, 28 Mar 2025 09:26:55 +0100 Subject: [PATCH 38/82] patching libzmq and cleaned up cmake --- CMakeLists.txt | 37 ++++++++++++++++++++++---- libs/libzmq/libzmq_cmake_version.patch | 17 ++++++++++++ pyproject.toml | 9 ++++--- 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 libs/libzmq/libzmq_cmake_version.patch diff --git a/CMakeLists.txt b/CMakeLists.txt index 0aa6dcd5d..2861c4546 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,20 +30,41 @@ option(SLS_FETCH_ZMQ_FROM_GITHUB "Fetch zmq from github" OFF) option(SLS_FETCH_PYBIND11_FROM_GITHUB "Fetch pybind11 from github" OFF) + + + + +# Allow FetchContent_Populate to be called with a single argument +# otherwise deprecated warning is issued +# Note: From cmake 3.28 we can pass EXCLUDE_FROM_ALL to FetchContent_Declare +# and avoid direct use of Populate +if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30") + cmake_policy(SET CMP0169 OLD) +endif() + +# Patch libzmq to set minimum cmake version to 3.15 to avoid warnings +# with newer cmake versions +set(zmq_patch_version git apply ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq_cmake_version.patch) + +set(SLS_LIBZMQ_VERSION "4.3.4") + + if(SLS_FETCH_ZMQ_FROM_GITHUB) # Opt in to pull down a zmq version from github instead of # using the bundled verison FetchContent_Declare( libzmq GIT_REPOSITORY https://github.com/zeromq/libzmq.git - GIT_TAG v4.3.4 + GIT_TAG v${SLS_LIBZMQ_VERSION} + PATCH_COMMAND ${zmq_patch_version} ) else() # Standard behaviour use libzmq included in this repo (libs/libzmq) FetchContent_Declare( libzmq - URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq-4.3.4.tar.gz + URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq-${SLS_LIBZMQ_VERSION}.tar.gz URL_HASH MD5=cc20b769ac10afa352e5ed2769bb23b3 + PATCH_COMMAND ${zmq_patch_version} ) endif() @@ -335,9 +356,15 @@ if (SLS_USE_CTBGUI) add_subdirectory(pyctbgui) endif(SLS_USE_CTBGUI) -configure_file( .clang-tidy - ${CMAKE_BINARY_DIR}/.clang-tidy -) +# Workaround for file note being copied to build directory +# when issuing a python -m build +# TODO! Proper fix +if(EXISTS ".clang-tidy") + configure_file(.clang-tidy + ${CMAKE_BINARY_DIR}/.clang-tidy + ) +endif() + if (SLS_BUILD_EXAMPLES) add_subdirectory(sample) diff --git a/libs/libzmq/libzmq_cmake_version.patch b/libs/libzmq/libzmq_cmake_version.patch new file mode 100644 index 000000000..901078fe8 --- /dev/null +++ b/libs/libzmq/libzmq_cmake_version.patch @@ -0,0 +1,17 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index dd3d8eb9..75c321fd 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,11 +1,7 @@ + # CMake build script for ZeroMQ + project(ZeroMQ) + +-if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) +- cmake_minimum_required(VERSION 3.0.2) +-else() +- cmake_minimum_required(VERSION 2.8.12) +-endif() ++cmake_minimum_required(VERSION 3.15) + + include(CheckIncludeFiles) + include(CheckCCompilerFlag) diff --git a/pyproject.toml b/pyproject.toml index 35709dae1..eafffa9f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,13 +7,16 @@ name = "slsdet" version = "2025.3.19" -[tool.scikit-build] -cmake.verbose = true +[tool.cibuildwheel] +before-all = "uname -a" + +[tool.scikit-build-core] +build.verbose = true cmake.build-type = "Release" install.components = ["python"] -[tool.scikit-build.cmake.define] +[tool.scikit-build-core.cmake.define] #Only build the control software and python ext SLS_USE_RECEIVER = "OFF" SLS_USE_RECEIVER_BINARIES = "OFF" From 46152d2419a8593438d8beeeffe9bcd71223e1a4 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Fri, 28 Mar 2025 09:35:25 +0100 Subject: [PATCH 39/82] added mythen3 pattern word table --- docs/src/pattern.rst | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/docs/src/pattern.rst b/docs/src/pattern.rst index b45b361c6..4708fe0ec 100644 --- a/docs/src/pattern.rst +++ b/docs/src/pattern.rst @@ -37,7 +37,7 @@ The maximal number of patword addresses is 8192. However, it is possible to exte patloop 0 0x0001 0x0003 patnloop 0 7 -The first argument of both commands is the ID of the loop. Ctb and Xilinx_Ctb can have 6 loops (ID 0-5), Mythen3 can have 4 loop definitions. The commands above configure the loop with ID 0 to run 7 times and jump from the patword with address 3 to the patword with address 1. Important: if patnloop is set to 1 the addesses 0x1-0x3 will execute exactly once, if it is set to 0 the pattern addresses will be skipped. +The first argument of both commands is the ID of the loop. Ctb and Xilinx_Ctb can have 6 loops (ID 0-5), Mythen3 can have 4 loop definitions. The commands above configure the loop with ID 0 to run 7 times and jump from the patword with address 3 to the patword with address 1. Important: If patnloop is set to 1, the addresses 0x1-0x3 will execute exactly once; if it is set to 0, the pattern addresses will be skipped. The same idea is used to introduce wait times. The example below causes the patword at address 0x0002 to be active for 9 clock cycles before the execution continues. @@ -50,18 +50,21 @@ Waits can be placed inside a loop and loops can be nested. **patioctrl** -The function of each bit in the sequence of 64-bit words depends on the connected detector and firmware version. Some of the 64 bits might connect directly to pads of a chip. The patioctrl command is used to configure the direction of some of these signals (not all of them !! See tables below). Signals where the corresponding bit in the argument of patioctrl is set to 1 will be driveen from the FPGA. +The function of each bit in the sequence of 64-bit words depends on the connected detector and firmware version. Some of the 64 bits might connect directly to pads of a chip. The patioctrl command is used to configure the direction of some of these signals (not all of them !! See tables below). Signals where the corresponding bit in the argument of patioctrl is set to 1 will be driven from the FPGA. **patsetbit and patmask** The functions patsetbit and patmask can be used to ignore a specific bit of the pattern. Example: + .. code-block:: patmask 0x0101 patsetbit 0x0001 -Patmask configures bit 0 and 8 of the pattern to be set to their value in patsetbit. These bits will be ignored during pattern execution and will always be 0 (bit 8) and 1 (bit 0). +Patmask configures bit 0 and 8 of the pattern to be set to their value in patsetbit. These bits will be ignored during pattern execution and will always be 0 (bit 8) and 1 (bit 0). + +The mappings of bit positions in the pattern word to signals/pads of the FPGA are listed below for the three detector types where patterns are used. In the case of the two CTB's, connections of the signals to actual pads of a chip depend on the layout of the used detector adapter board. Therefore, each type of detector adapter board adds an additional mapping layer. **CTB Pattern Bit Mapping** @@ -75,18 +78,16 @@ Patmask configures bit 0 and 8 of the pattern to be set to their value in patset DIO: Driving the 32 FPGA pins corresponding to the lowest 32 bits of the patioctrl command. If bits in patioctrl are 0, the same bit positions in DIO will switch to input pins and connect to dbit sampling. Additionally, some of these 32 bits have an automatic override by detector-specific statemachines which is active whenever these sm's are running (currently bits 7,8,11,14 and 20). -DO: Directly connected to 16 FPGA pins. Output only. Not influenced by patioctrl. Also connected to bit 47-32 in all Ctb dbit samples. All of them can be used as dbit sample trigger. In Addition, every bit of DO can be selected as trigger for sending out a udp packet with samples to the receiver. +DO: Directly connected to 16 FPGA pins. Output only. Not influenced by patioctrl. Also connected to bit 47-32 in all Ctb dbit samples. All of them can be used as dbit sample trigger. In addition, every bit of DO can be selected as trigger for sending out a udp packet with samples to the receiver. EXTIO: Similar to DIO, but not used as input to the fpga. With the corresponding patioctrl bits set to 0 these pins will switch to a high impedance mode and be ignored by the firmware. -T: Driving the trigger output +T: trigger output D: enable signal for digital sampling A: adc enable -Connections of the signals above to actual pads of a chip depend on the layout of the used detector adapter board. - **Xilinx_CTB Pattern Bit Mapping** .. table:: @@ -102,4 +103,20 @@ DIO: Driving the 32 FPGA pins corresponding to the lowest 32 bits of the patioct **Mythen3 Pattern Bit Mapping** -TODO +.. table:: + + +-------+--------+-------+--------+------------+----------+----------+-----+-----+ + | 63-33 | 32 | 31-25 | 24 | 23 | 22 | 21 | 20 | 19 | + +-------+--------+-------+--------+------------+----------+----------+-----+-----+ + | --- | signARD| --- | CHSclk | cnt_rst | sto_rst | STATLOAD | STO | SIN | + +-------+--------+-------+--------+------------+----------+----------+-----+-----+ + +.. table:: + + +---------+-----+-------+-------+----+-------+---------+--------+ + | 18 | 17 | 16-14 | 13 | 12 | 11 | 10 | 9-0 | + +---------+-----+-------+-------+----+-------+---------+--------+ + | SR_MODE | clk | EN | PULSE | RD | CHSIN | ANAMode | TBLOAD | + +---------+-----+-------+-------+----+-------+---------+--------+ + +For Mythen3 the pattern word only connects to output pins of the FPGA when the pattern is running. Afterwards the signals will switch back to other logic in the FPGA. Both CTB's hold the last executed pattern word until a new pattern is started. \ No newline at end of file From 3312adddd15b0eb715614ef98d841da28b35e96f Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Fri, 28 Mar 2025 15:43:09 +0100 Subject: [PATCH 40/82] removed compiler version --- CMakeLists.txt | 9 +++------ conda-recipes/main-library/conda_build_config.yaml | 6 ------ conda-recipes/python-client/conda_build_config.yaml | 7 ------- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2861c4546..8d6947522 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,9 +31,6 @@ option(SLS_FETCH_PYBIND11_FROM_GITHUB "Fetch pybind11 from github" OFF) - - - # Allow FetchContent_Populate to be called with a single argument # otherwise deprecated warning is issued # Note: From cmake 3.28 we can pass EXCLUDE_FROM_ALL to FetchContent_Declare @@ -44,7 +41,7 @@ endif() # Patch libzmq to set minimum cmake version to 3.15 to avoid warnings # with newer cmake versions -set(zmq_patch_version git apply ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq_cmake_version.patch) +set(ZMQ_PATCH_CMAKE git apply ${CMAKE_CURRENT_LIST_DIR}/libs/libzmq/libzmq_cmake_version.patch) set(SLS_LIBZMQ_VERSION "4.3.4") @@ -56,7 +53,7 @@ if(SLS_FETCH_ZMQ_FROM_GITHUB) libzmq GIT_REPOSITORY https://github.com/zeromq/libzmq.git GIT_TAG v${SLS_LIBZMQ_VERSION} - PATCH_COMMAND ${zmq_patch_version} + PATCH_COMMAND ${ZMQ_PATCH_CMAKE} ) else() # Standard behaviour use libzmq included in this repo (libs/libzmq) @@ -64,7 +61,7 @@ else() libzmq URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq-${SLS_LIBZMQ_VERSION}.tar.gz URL_HASH MD5=cc20b769ac10afa352e5ed2769bb23b3 - PATCH_COMMAND ${zmq_patch_version} + PATCH_COMMAND ${ZMQ_PATCH_CMAKE} ) endif() diff --git a/conda-recipes/main-library/conda_build_config.yaml b/conda-recipes/main-library/conda_build_config.yaml index 2bf732748..149897ca1 100644 --- a/conda-recipes/main-library/conda_build_config.yaml +++ b/conda-recipes/main-library/conda_build_config.yaml @@ -2,9 +2,6 @@ c_compiler: - gcc # [linux] -c_compiler_version: - - 13 # [linux] - c_stdlib: - sysroot # [linux] @@ -12,8 +9,5 @@ cxx_compiler: - gxx # [linux] -cxx_compiler_version: - - 13 # [linux] - c_stdlib_version: # [linux] - 2.17 # [linux] \ No newline at end of file diff --git a/conda-recipes/python-client/conda_build_config.yaml b/conda-recipes/python-client/conda_build_config.yaml index 264e093ef..0c957b631 100644 --- a/conda-recipes/python-client/conda_build_config.yaml +++ b/conda-recipes/python-client/conda_build_config.yaml @@ -6,18 +6,11 @@ python: c_compiler: - gcc # [linux] -c_compiler_version: - - 13 # [linux] - c_stdlib: - sysroot # [linux] cxx_compiler: - gxx # [linux] - -cxx_compiler_version: - - 13 # [linux] - c_stdlib_version: # [linux] - 2.17 # [linux] \ No newline at end of file From 470e2633c3e657812faa633816bdef8f67da521d Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Fri, 28 Mar 2025 16:32:37 +0100 Subject: [PATCH 41/82] adding pmodules for 9.1.0 rhl8 --- psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants | 1 + 1 file changed, 1 insertion(+) diff --git a/psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants b/psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants index 9a01f5487..c20d6f7e1 100644 --- a/psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants +++ b/psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants @@ -12,5 +12,6 @@ slsDetectorPackage/8.0.1_rh8 stable cmake/3.15.5 Qt/5.12.10 slsDetectorPackage/8.0.2_rh7 stable cmake/3.15.5 Qt/5.12.10 slsDetectorPackage/8.0.2_rh8 stable cmake/3.15.5 Qt/5.12.10 slsDetectorPackage/9.0.0_rh8 stable cmake/3.15.5 Qt/5.12.10 +slsDetectorPackage/9.1.0_rh8 stable cmake/3.15.5 Qt/5.12.10 From 95e11d668a1aaec7e6c3d4c1b423f4deb42f7871 Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Fri, 28 Mar 2025 18:26:45 +0100 Subject: [PATCH 42/82] switched patch tool --- CMakeLists.txt | 11 ++++++----- conda-recipes/main-library/meta.yaml | 2 +- libs/libzmq/libzmq_cmake_version.patch | 5 +++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d6947522..b1d035d76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,19 +41,19 @@ endif() # Patch libzmq to set minimum cmake version to 3.15 to avoid warnings # with newer cmake versions -set(ZMQ_PATCH_CMAKE git apply ${CMAKE_CURRENT_LIST_DIR}/libs/libzmq/libzmq_cmake_version.patch) - +# Patch is applied in the FetchContent_Declare set(SLS_LIBZMQ_VERSION "4.3.4") if(SLS_FETCH_ZMQ_FROM_GITHUB) # Opt in to pull down a zmq version from github instead of - # using the bundled verison + # using the bundled version FetchContent_Declare( libzmq GIT_REPOSITORY https://github.com/zeromq/libzmq.git GIT_TAG v${SLS_LIBZMQ_VERSION} - PATCH_COMMAND ${ZMQ_PATCH_CMAKE} + PATCH_COMMAND ${CMAKE_COMMAND} -E chdir patch -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq_cmake_version.patch + UPDATE_DISCONNECTED 1 ) else() # Standard behaviour use libzmq included in this repo (libs/libzmq) @@ -61,7 +61,8 @@ else() libzmq URL ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq-${SLS_LIBZMQ_VERSION}.tar.gz URL_HASH MD5=cc20b769ac10afa352e5ed2769bb23b3 - PATCH_COMMAND ${ZMQ_PATCH_CMAKE} + PATCH_COMMAND ${CMAKE_COMMAND} -E chdir patch -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/libs/libzmq/libzmq_cmake_version.patch + UPDATE_DISCONNECTED 1 ) endif() diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index 87a9a4f50..2ddc76a6f 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -17,7 +17,7 @@ requirements: - {{ compiler('c') }} - {{ stdlib("c") }} - {{ compiler('cxx') }} - + - git - cmake - ninja - qt 5.* diff --git a/libs/libzmq/libzmq_cmake_version.patch b/libs/libzmq/libzmq_cmake_version.patch index 901078fe8..4e421d322 100644 --- a/libs/libzmq/libzmq_cmake_version.patch +++ b/libs/libzmq/libzmq_cmake_version.patch @@ -1,8 +1,8 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index dd3d8eb9..75c321fd 100644 +index dd3d8eb9..c0187747 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -1,11 +1,7 @@ +@@ -1,11 +1,8 @@ # CMake build script for ZeroMQ project(ZeroMQ) @@ -12,6 +12,7 @@ index dd3d8eb9..75c321fd 100644 - cmake_minimum_required(VERSION 2.8.12) -endif() +cmake_minimum_required(VERSION 3.15) ++message(STATUS "Patched cmake version") include(CheckIncludeFiles) include(CheckCCompilerFlag) From 04583acb21850db64121b54d50da64b29d72849d Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Tue, 1 Apr 2025 14:17:07 +0200 Subject: [PATCH 43/82] reverted to scikit-build in pyproject.toml --- conda-recipes/python-client/meta.yaml | 3 +-- pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml index 9add4b13b..3b710151c 100644 --- a/conda-recipes/python-client/meta.yaml +++ b/conda-recipes/python-client/meta.yaml @@ -1,6 +1,6 @@ package: name: slsdet - version: 2025.2.18 #TODO! how to not duplicate this? + version: 2025.3.19 #TODO! how to not duplicate this? source: path: ../.. @@ -9,7 +9,6 @@ build: number: 0 script: - unset CMAKE_GENERATOR && {{ PYTHON }} -m pip install . -vv # [not win] - - {{ PYTHON }} -m pip install . -vv # [win] requirements: build: diff --git a/pyproject.toml b/pyproject.toml index eafffa9f4..3d128f18e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,13 +10,13 @@ version = "2025.3.19" [tool.cibuildwheel] before-all = "uname -a" -[tool.scikit-build-core] +[tool.scikit-build] build.verbose = true cmake.build-type = "Release" install.components = ["python"] -[tool.scikit-build-core.cmake.define] +[tool.scikit-build.cmake.define] #Only build the control software and python ext SLS_USE_RECEIVER = "OFF" SLS_USE_RECEIVER_BINARIES = "OFF" From 5f14eb32aa83ddd72e52a27499be787f874dadcb Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Tue, 1 Apr 2025 16:57:47 +0200 Subject: [PATCH 44/82] added sls_detector bin --- .github/workflows/{conda_library.yml => conda_library.yaml} | 0 .github/workflows/{conda_python.yml => conda_python.yaml} | 0 conda-recipes/main-library/copy_lib.sh | 1 + 3 files changed, 1 insertion(+) rename .github/workflows/{conda_library.yml => conda_library.yaml} (100%) rename .github/workflows/{conda_python.yml => conda_python.yaml} (100%) diff --git a/.github/workflows/conda_library.yml b/.github/workflows/conda_library.yaml similarity index 100% rename from .github/workflows/conda_library.yml rename to .github/workflows/conda_library.yaml diff --git a/.github/workflows/conda_python.yml b/.github/workflows/conda_python.yaml similarity index 100% rename from .github/workflows/conda_python.yml rename to .github/workflows/conda_python.yaml diff --git a/conda-recipes/main-library/copy_lib.sh b/conda-recipes/main-library/copy_lib.sh index 72343b565..be6c13f47 100755 --- a/conda-recipes/main-library/copy_lib.sh +++ b/conda-recipes/main-library/copy_lib.sh @@ -14,6 +14,7 @@ cp build/install/bin/sls_detector_acquire_zmq $PREFIX/bin/. cp build/install/bin/sls_detector_get $PREFIX/bin/. cp build/install/bin/sls_detector_put $PREFIX/bin/. cp build/install/bin/sls_detector_help $PREFIX/bin/. +cp build/install/bin/sls_detector $PREFIX/bin/. cp build/install/bin/slsReceiver $PREFIX/bin/. cp build/install/bin/slsMultiReceiver $PREFIX/bin/. From d0ccf236c036d708ad31a48953880c3c9aff8431 Mon Sep 17 00:00:00 2001 From: froejdh_e Date: Tue, 1 Apr 2025 17:20:35 +0200 Subject: [PATCH 45/82] added sync, renamed action --- .github/workflows/{cmake.yml => cmake.yaml} | 0 conda-recipes/main-library/copy_lib.sh | 1 + 2 files changed, 1 insertion(+) rename .github/workflows/{cmake.yml => cmake.yaml} (100%) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yaml similarity index 100% rename from .github/workflows/cmake.yml rename to .github/workflows/cmake.yaml diff --git a/conda-recipes/main-library/copy_lib.sh b/conda-recipes/main-library/copy_lib.sh index be6c13f47..88beafdfe 100755 --- a/conda-recipes/main-library/copy_lib.sh +++ b/conda-recipes/main-library/copy_lib.sh @@ -17,6 +17,7 @@ cp build/install/bin/sls_detector_help $PREFIX/bin/. cp build/install/bin/sls_detector $PREFIX/bin/. cp build/install/bin/slsReceiver $PREFIX/bin/. cp build/install/bin/slsMultiReceiver $PREFIX/bin/. +cp build/install/bin/slsFrameSynchronizer $PREFIX/bin/. cp build/install/include/sls/* $PREFIX/include/sls From 0b3cd499a8a6fbf424f53e25a76251564d142ccf Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Wed, 2 Apr 2025 10:18:57 +0200 Subject: [PATCH 46/82] Dhanya's comments --- docs/src/pattern.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/pattern.rst b/docs/src/pattern.rst index 4708fe0ec..471a3e570 100644 --- a/docs/src/pattern.rst +++ b/docs/src/pattern.rst @@ -23,7 +23,7 @@ The example above writes a five-word pattern into FPGA memory. The first argumen patlimits 0x0000 0x0004 -This instructs the firmware to execute the commands from address 0 to 4 (including 0 and 4). The execution can be started from the GUI or with the commands +This instructs the firmware to execute the commands from address 0 to 4 (including 0 and 4). The execution can be started from the pyctbgui or with the commands .. code-block:: @@ -76,7 +76,7 @@ The mappings of bit positions in the pattern word to signals/pads of the FPGA ar | A | D| --- | T | EXTIO | DO, stream source | DIO | +----+---+------+----+----------+-------------------+----------------+ -DIO: Driving the 32 FPGA pins corresponding to the lowest 32 bits of the patioctrl command. If bits in patioctrl are 0, the same bit positions in DIO will switch to input pins and connect to dbit sampling. Additionally, some of these 32 bits have an automatic override by detector-specific statemachines which is active whenever these sm's are running (currently bits 7,8,11,14 and 20). +DIO: Driving the 32 FPGA pins corresponding to the lowest 32 bits of the patioctrl command. If bits in patioctrl are 0, the same bit positions in DIO will switch to input pins and connect to dbit sampling. Additionally, some of these 32 bits have an automatic override by detector-specific statemachines which is active whenever one of these statemachines is running (currently bits 7,8,11,14 and 20). DO: Directly connected to 16 FPGA pins. Output only. Not influenced by patioctrl. Also connected to bit 47-32 in all Ctb dbit samples. All of them can be used as dbit sample trigger. In addition, every bit of DO can be selected as trigger for sending out a udp packet with samples to the receiver. From 5ab2c1693ec46df6d98579ebf53c100b3dadb94e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fr=C3=B6jdh?= Date: Thu, 3 Apr 2025 12:00:57 +0200 Subject: [PATCH 47/82] Fixed broken import in typecaster.h (#1181) - Fixed the broken import _slsdet --> slsdet._slsdet caused by a previous upgrade - Added tests that exercises the conversion from python to C++ and from C++ to python - Python unit tests now run in CI (!) --- .github/workflows/cmake.yaml | 19 ++++++--- python/slsdet/__init__.py | 3 ++ python/src/duration.cpp | 22 +++++++++++ python/src/typecaster.h | 9 ++++- python/tests/test_DurationWrapper.py | 58 ++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 python/tests/test_DurationWrapper.py diff --git a/.github/workflows/cmake.yaml b/.github/workflows/cmake.yaml index 5e99d1f35..00d6a4b86 100644 --- a/.github/workflows/cmake.yaml +++ b/.github/workflows/cmake.yaml @@ -14,7 +14,13 @@ jobs: runs-on: ubuntu-latest name: Configure and build using cmake steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.12 + cache: 'pip' + - run: pip install pytest numpy + - uses: awalsh128/cache-apt-pkgs-action@latest with: packages: libhdf5-dev qtbase5-dev qt5-qmake libqt5svg5-dev libpng-dev libtiff-dev @@ -27,12 +33,15 @@ jobs: - name: Build # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build -j2 --config ${{env.BUILD_TYPE}} + run: cmake --build ${{github.workspace}}/build -j4 --config ${{env.BUILD_TYPE}} - - name: Test + - name: C++ unit tests working-directory: ${{github.workspace}}/build - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest -C ${{env.BUILD_TYPE}} -j1 + - name: Python unit tests + working-directory: ${{github.workspace}}/build/bin + run: | + python -m pytest ${{github.workspace}}/python/tests + diff --git a/python/slsdet/__init__.py b/python/slsdet/__init__.py index 4b216ee62..a3097eda4 100755 --- a/python/slsdet/__init__.py +++ b/python/slsdet/__init__.py @@ -41,3 +41,6 @@ def read_version(): __version__ = read_version() + + + diff --git a/python/src/duration.cpp b/python/src/duration.cpp index db6da3d06..ed8927c90 100644 --- a/python/src/duration.cpp +++ b/python/src/duration.cpp @@ -1,3 +1,4 @@ +#include #include "py_headers.h" #include "DurationWrapper.h" @@ -19,4 +20,25 @@ void init_duration(py::module &m) { << " count: " << self.count() << ")"; return ss.str(); }); + + m.def( + "test_return_DurationWrapper", + []() { + DurationWrapper t(1.3); + return t; + }, + R"( + Test function to return a DurationWrapper object. Ensures that the automatic conversion in typecaster.h works. + )"); + + m.def( + "test_duration_to_ns", + [](const std::chrono::nanoseconds t) { + //Duration wrapper is used to be able to convert from time in python to chrono::nanoseconds + //return count to have something to test + return t.count(); + }, + R"( + Test function convert DurationWrapper or number to chrono::ns. Ensures that the automatic conversion in typecaster.h works. + )"); // default value to test the default constructor } diff --git a/python/src/typecaster.h b/python/src/typecaster.h index 5eba7b436..6412afa72 100644 --- a/python/src/typecaster.h +++ b/python/src/typecaster.h @@ -54,11 +54,16 @@ template <> struct type_caster { value = duration_cast(duration(PyFloat_AsDouble(src.ptr()))); return true; } + // If invoked with an int we assume it is nanoseconds and convert, same as in chrono.h + if (PyLong_Check(src.ptr())) { + value = duration_cast(duration(PyLong_AsLongLong(src.ptr()))); + return true; + } // Lastly if we were actually called with a DurationWrapper object we get // the number of nanoseconds and create a std::chrono::nanoseconds from it - py::object py_cls = py::module::import("_slsdet").attr("DurationWrapper"); + py::object py_cls = py::module::import("slsdet._slsdet").attr("DurationWrapper"); if (py::isinstance(src, py_cls)){ sls::DurationWrapper *cls = src.cast(); value = nanoseconds(cls->count()); @@ -77,7 +82,7 @@ template <> struct type_caster { * set the count from chrono::nanoseconds and return */ static handle cast(std::chrono::nanoseconds src, return_value_policy /* policy */, handle /* parent */) { - py::object py_cls = py::module::import("_slsdet").attr("DurationWrapper"); + py::object py_cls = py::module::import("slsdet._slsdet").attr("DurationWrapper"); py::object* obj = new py::object; *obj = py_cls(); sls::DurationWrapper *dur = obj->cast(); diff --git a/python/tests/test_DurationWrapper.py b/python/tests/test_DurationWrapper.py new file mode 100644 index 000000000..f6902da26 --- /dev/null +++ b/python/tests/test_DurationWrapper.py @@ -0,0 +1,58 @@ +import pytest + +from slsdet import DurationWrapper + +#import the compiled extension to use test functions for the automatic conversion +from slsdet import _slsdet + + +def test_default_construction_of_DurationWrapper(): + """Test default construction of DurationWrapper""" + t = DurationWrapper() + assert t.count() == 0 + assert t.total_seconds() == 0 + +def test_construction_of_DurationWrapper(): + """Test construction of DurationWrapper with total_seconds""" + t = DurationWrapper(5) + assert t.count() == 5e9 + assert t.total_seconds() == 5 + +def test_set_count_on_DurationWrapper(): + """Test set_count on DurationWrapper""" + t = DurationWrapper() + t.set_count(10) + assert t.count() == 10 + assert t.total_seconds() == 10e-9 + t.set_count(0) + assert t.count() == 0 + assert t.total_seconds() == 0 + + +def test_return_a_DurationWrapper_from_cpp(): + """Test returning a DurationWrapper from C++""" + t = _slsdet.test_return_DurationWrapper() + assert t.count() == 1.3e9 + assert t.total_seconds() == 1.3 + +def test_call_a_cpp_function_with_a_duration_wrapper(): + """C++ functions can accept a DurationWrapper""" + t = DurationWrapper(5) + assert _slsdet.test_duration_to_ns(t) == 5e9 + +def test_call_a_cpp_function_converting_number_to_DurationWrapper(): + """int and float can be converted to std::chrono::nanoseconds""" + assert _slsdet.test_duration_to_ns(0) == 0 + assert _slsdet.test_duration_to_ns(3) == 3e9 + assert _slsdet.test_duration_to_ns(1.3) == 1.3e9 + assert _slsdet.test_duration_to_ns(10e-9) == 10 + +def test_call_a_cpp_function_with_datetime_timedelta(): + """datetime.timedelta can be converted to std::chrono::nanoseconds""" + import datetime + t = datetime.timedelta(seconds=5) + assert _slsdet.test_duration_to_ns(t) == 5e9 + t = datetime.timedelta(seconds=0) + assert _slsdet.test_duration_to_ns(t) == 0 + t = datetime.timedelta(seconds=1.3) + assert _slsdet.test_duration_to_ns(t) == 1.3e9 \ No newline at end of file From 1d1b55b864e24eb3e75b2f13c4c205f700e6db57 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Tue, 8 Apr 2025 15:57:11 +0200 Subject: [PATCH 48/82] 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 49/82] 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 50/82] 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 51/82] 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 7c8639b8ae823ab9d5e89cfbd9c1a0138822f838 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Wed, 9 Apr 2025 18:20:58 +0200 Subject: [PATCH 52/82] formatting --- slsDetectorSoftware/include/sls/Pattern.h | 2 +- slsDetectorSoftware/src/Pattern.cpp | 15 +++++++-------- slsSupportLib/include/sls/versionAPI.h | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/slsDetectorSoftware/include/sls/Pattern.h b/slsDetectorSoftware/include/sls/Pattern.h index 4a8cb6f47..90d6aae12 100644 --- a/slsDetectorSoftware/include/sls/Pattern.h +++ b/slsDetectorSoftware/include/sls/Pattern.h @@ -23,7 +23,7 @@ typedef struct __attribute__((packed)) { #ifdef __cplusplus class Pattern { patternParameters *pat = new patternParameters{}; - std::ostream& stream(std::ostream &os) const; + std::ostream &stream(std::ostream &os) const; public: Pattern(); diff --git a/slsDetectorSoftware/src/Pattern.cpp b/slsDetectorSoftware/src/Pattern.cpp index 4083df7fa..1a5f7b80c 100644 --- a/slsDetectorSoftware/src/Pattern.cpp +++ b/slsDetectorSoftware/src/Pattern.cpp @@ -243,10 +243,10 @@ size_t Pattern::load(const std::string &fname) { return numPatWords; } -std::ostream& Pattern::stream(std::ostream &os) const{ +std::ostream &Pattern::stream(std::ostream &os) const { for (uint32_t i = pat->limits[0]; i <= pat->limits[1]; ++i) { os << "patword " << ToStringHex(i, 4) << " " - << ToStringHex(pat->word[i], 16) << std::endl; + << ToStringHex(pat->word[i], 16) << std::endl; } // patioctrl @@ -254,13 +254,12 @@ std::ostream& Pattern::stream(std::ostream &os) const{ // patlimits os << "patlimits " << ToStringHex(pat->limits[0], 4) << " " - << ToStringHex(pat->limits[1], 4) << std::endl; + << ToStringHex(pat->limits[1], 4) << std::endl; for (size_t i = 0; i < MAX_PATTERN_LEVELS; ++i) { // patloop - os << "patloop " << i << " " - << ToStringHex(pat->startloop[i], 4) << " " - << ToStringHex(pat->stoploop[i], 4) << std::endl; + os << "patloop " << i << " " << ToStringHex(pat->startloop[i], 4) << " " + << ToStringHex(pat->stoploop[i], 4) << std::endl; // patnloop os << "patnloop " << i << " " << pat->nloop[i] << std::endl; } @@ -268,10 +267,10 @@ std::ostream& Pattern::stream(std::ostream &os) const{ for (size_t i = 0; i < MAX_PATTERN_LEVELS; ++i) { // patwait os << "patwait " << i << " " << ToStringHex(pat->wait[i], 4) - << std::endl; + << std::endl; // patwaittime os << "patwaittime " << i << " " << pat->waittime[i]; - if (i Date: Wed, 9 Apr 2025 18:21:54 +0200 Subject: [PATCH 53/82] 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 54/82] 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 55/82] 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 56/82] 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 57/82] 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 58/82] 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 59/82] 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 60/82] 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 61/82] 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 62/82] 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 63/82] 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 64/82] 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 65/82] 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 From da760b2b934af55e5e0f691591245af66c59e773 Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Tue, 22 Apr 2025 14:00:45 +0200 Subject: [PATCH 66/82] version number automated for python build --- conda-recipes/build_conda.sh | 8 ++++++++ conda-recipes/main-library/meta.yaml | 6 +++--- conda-recipes/python-client/meta.yaml | 4 ++-- pyproject.toml | 18 +++++++++--------- update_version.py | 22 +++++++++++++++++++++- 5 files changed, 43 insertions(+), 15 deletions(-) create mode 100755 conda-recipes/build_conda.sh diff --git a/conda-recipes/build_conda.sh b/conda-recipes/build_conda.sh new file mode 100755 index 000000000..6915f89a9 --- /dev/null +++ b/conda-recipes/build_conda.sh @@ -0,0 +1,8 @@ + +SCRIPTDIR=$(cd "$(dirname "$0")" && pwd) +VERSION=$(cat $SCRIPTDIR/../VERSION) +export VERSION + +echo "building conda package version: $VERSION" + +conda build . diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index 2ddc76a6f..232f89b20 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -1,8 +1,8 @@ +#{% set version = load_file('VERSION').strip %} package: name: sls_detector_software - version: 2025.3.19 - - + version: {{ environ.get('VERSION') }} #2025.3.19 + source: path: ../.. diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml index 3b710151c..c5e2cbb38 100644 --- a/conda-recipes/python-client/meta.yaml +++ b/conda-recipes/python-client/meta.yaml @@ -1,7 +1,7 @@ + package: name: slsdet - version: 2025.3.19 #TODO! how to not duplicate this? - + version: 0.0.0 source: path: ../.. diff --git a/pyproject.toml b/pyproject.toml index 3d128f18e..5e11fdc45 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,27 +1,27 @@ [build-system] -requires = ["scikit-build-core>=0.10", "pybind11", "numpy"] +requires = [ "scikit-build-core>=0.10", "pybind11", "numpy",] build-backend = "scikit_build_core.build" [project] name = "slsdet" version = "2025.3.19" - [tool.cibuildwheel] before-all = "uname -a" -[tool.scikit-build] -build.verbose = true -cmake.build-type = "Release" -install.components = ["python"] +[tool.scikit-build.build] +verbose = true +[tool.scikit-build.cmake] +build-type = "Release" + +[tool.scikit-build.install] +components = [ "python",] [tool.scikit-build.cmake.define] -#Only build the control software and python ext SLS_USE_RECEIVER = "OFF" SLS_USE_RECEIVER_BINARIES = "OFF" SLS_USE_TEXTCLIENT = "OFF" SLS_BUILD_SHARED_LIBRARIES = "OFF" - SLS_USE_PYTHON = "ON" -SLS_INSTALL_PYTHONEXT = "ON" \ No newline at end of file +SLS_INSTALL_PYTHONEXT = "ON" diff --git a/update_version.py b/update_version.py index c074ae542..f5c28c5af 100644 --- a/update_version.py +++ b/update_version.py @@ -6,6 +6,10 @@ Script to update VERSION file with semantic versioning if provided as an argumen import sys import re +import os +import toml +import yaml +from jinja2 import Template, Undefined def get_version(): @@ -28,9 +32,25 @@ def write_version_to_file(version): version_file.write(version) print(f"Version {version} written to VERSION file.") +def define_environment_variable(version): + os.environ["VERSION"] = version + +def update_pyproject_toml_file(version): + pyproject = toml.load("pyproject.toml") + pyproject["project"]["version"] = version + toml.dump(pyproject, open("pyproject.toml", "w")) #write back + print(f"Version in pyproject.toml set to {version}") + +class NullUndefined(Undefined): + def __getattr__(self, key): + return '' + + # Main script if __name__ == "__main__": version = get_version() - write_version_to_file(version) \ No newline at end of file + write_version_to_file(version) + define_environment_variable(version) + update_pyproject_toml_file(version) From 8fe4a78febcf13e10653270d9fdfa4ad40db9b5f Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Tue, 22 Apr 2025 15:43:01 +0200 Subject: [PATCH 67/82] mistakenly set version back to 0.0.0 --- conda-recipes/python-client/meta.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml index c5e2cbb38..7daa969a6 100644 --- a/conda-recipes/python-client/meta.yaml +++ b/conda-recipes/python-client/meta.yaml @@ -1,7 +1,8 @@ package: name: slsdet - version: 0.0.0 + version: {{ environ.get('VERSION') }} #2025.3.19 + source: path: ../.. From fca31cc4322fa80f33c458bf5f711c0c017babce Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Tue, 22 Apr 2025 17:05:06 +0200 Subject: [PATCH 68/82] updated github workflow scripts to support automatic version numbering with environment variable --- .github/workflows/conda_library.yaml | 2 +- .github/workflows/conda_python.yaml | 2 +- conda-recipes/build_conda.sh | 19 +++++++++++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.github/workflows/conda_library.yaml b/.github/workflows/conda_library.yaml index 23f94d467..807d7872b 100644 --- a/.github/workflows/conda_library.yaml +++ b/.github/workflows/conda_library.yaml @@ -33,7 +33,7 @@ jobs: run: conda config --set anaconda_upload no - name: Build - run: conda build conda-recipes/main-library --output-folder build_output + run: ./conda-recipes/build_conda.sh build_output main-library - name: Upload all Conda packages uses: actions/upload-artifact@v4 diff --git a/.github/workflows/conda_python.yaml b/.github/workflows/conda_python.yaml index d482b8e6f..df67552e1 100644 --- a/.github/workflows/conda_python.yaml +++ b/.github/workflows/conda_python.yaml @@ -33,7 +33,7 @@ jobs: run: conda config --set anaconda_upload no - name: Build - run: conda build conda-recipes/python-client --output-folder build_output + run: ./conda-recipes/build_conda.sh build_output python-client - name: Upload all Conda packages uses: actions/upload-artifact@v4 diff --git a/conda-recipes/build_conda.sh b/conda-recipes/build_conda.sh index 6915f89a9..7e6ab3f46 100755 --- a/conda-recipes/build_conda.sh +++ b/conda-recipes/build_conda.sh @@ -3,6 +3,21 @@ SCRIPTDIR=$(cd "$(dirname "$0")" && pwd) VERSION=$(cat $SCRIPTDIR/../VERSION) export VERSION -echo "building conda package version: $VERSION" +if [ -z "$1" ] +then + output_dir=$CONDA_PREFIX/conda-bld +else + output_dir=$1 +fi -conda build . +if [ -z "$2" ] +then + recipe=$SCRIPTDIR +else + recipe=$SCRIPTDIR/$2 +fi + +echo "building conda package version: $VERSION using recipe $recipe and writing output to $output_dir" + + +conda build $recipe --output-folder $output_dir From 497c3abfc24af91d3cc224db31b91a6324eda6f0 Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Wed, 23 Apr 2025 14:26:26 +0200 Subject: [PATCH 69/82] managed to load VERSION file in yaml file - simplifies things --- .github/workflows/conda_python.yaml | 2 +- conda-recipes/build_conda.sh | 23 ----------------------- conda-recipes/main-library/meta.yaml | 10 +++++----- conda-recipes/python-client/meta.yaml | 10 +++++----- pyproject.toml | 2 +- update_version.py | 14 -------------- 6 files changed, 12 insertions(+), 49 deletions(-) delete mode 100755 conda-recipes/build_conda.sh diff --git a/.github/workflows/conda_python.yaml b/.github/workflows/conda_python.yaml index df67552e1..778b18ad7 100644 --- a/.github/workflows/conda_python.yaml +++ b/.github/workflows/conda_python.yaml @@ -33,7 +33,7 @@ jobs: run: conda config --set anaconda_upload no - name: Build - run: ./conda-recipes/build_conda.sh build_output python-client + run: conda build ./conda-recipes/python-client --build-folder build_output - name: Upload all Conda packages uses: actions/upload-artifact@v4 diff --git a/conda-recipes/build_conda.sh b/conda-recipes/build_conda.sh deleted file mode 100755 index 7e6ab3f46..000000000 --- a/conda-recipes/build_conda.sh +++ /dev/null @@ -1,23 +0,0 @@ - -SCRIPTDIR=$(cd "$(dirname "$0")" && pwd) -VERSION=$(cat $SCRIPTDIR/../VERSION) -export VERSION - -if [ -z "$1" ] -then - output_dir=$CONDA_PREFIX/conda-bld -else - output_dir=$1 -fi - -if [ -z "$2" ] -then - recipe=$SCRIPTDIR -else - recipe=$SCRIPTDIR/$2 -fi - -echo "building conda package version: $VERSION using recipe $recipe and writing output to $output_dir" - - -conda build $recipe --output-folder $output_dir diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index 232f89b20..2c2c88058 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -1,11 +1,11 @@ -#{% set version = load_file('VERSION').strip %} -package: - name: sls_detector_software - version: {{ environ.get('VERSION') }} #2025.3.19 - source: path: ../.. +{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+\.\d+\.\d+)').group(1) %} +package: + name: sls_detector_software + version: {{ version }} #2025.3.19 + build: number: 0 binary_relocation: True diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml index 7daa969a6..cf4f3aa7b 100644 --- a/conda-recipes/python-client/meta.yaml +++ b/conda-recipes/python-client/meta.yaml @@ -1,10 +1,11 @@ +source: + path: ../.. + +{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+\.\d+\.\d+)').group(1) %} package: name: slsdet - version: {{ environ.get('VERSION') }} #2025.3.19 - -source: - path: ../.. + version: {{ version }} # build: number: 0 @@ -18,7 +19,6 @@ requirements: - {{ stdlib("c") }} - {{ compiler('cxx') }} - host: - cmake - ninja diff --git a/pyproject.toml b/pyproject.toml index 5e11fdc45..776657c41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build" [project] name = "slsdet" -version = "2025.3.19" +version = "0.0.0" [tool.cibuildwheel] before-all = "uname -a" diff --git a/update_version.py b/update_version.py index f5c28c5af..507857133 100644 --- a/update_version.py +++ b/update_version.py @@ -6,10 +6,7 @@ Script to update VERSION file with semantic versioning if provided as an argumen import sys import re -import os import toml -import yaml -from jinja2 import Template, Undefined def get_version(): @@ -26,31 +23,20 @@ def get_version(): return version - def write_version_to_file(version): with open("VERSION", "w") as version_file: version_file.write(version) print(f"Version {version} written to VERSION file.") -def define_environment_variable(version): - os.environ["VERSION"] = version - def update_pyproject_toml_file(version): pyproject = toml.load("pyproject.toml") pyproject["project"]["version"] = version toml.dump(pyproject, open("pyproject.toml", "w")) #write back print(f"Version in pyproject.toml set to {version}") -class NullUndefined(Undefined): - def __getattr__(self, key): - return '' - - - # Main script if __name__ == "__main__": version = get_version() write_version_to_file(version) - define_environment_variable(version) update_pyproject_toml_file(version) From 2571397c701515e3cc829d6473f555be933c9896 Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Wed, 23 Apr 2025 14:38:51 +0200 Subject: [PATCH 70/82] saving changes in git workflow failed --- .github/workflows/conda_library.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conda_library.yaml b/.github/workflows/conda_library.yaml index 807d7872b..9bde3bb31 100644 --- a/.github/workflows/conda_library.yaml +++ b/.github/workflows/conda_library.yaml @@ -33,7 +33,7 @@ jobs: run: conda config --set anaconda_upload no - name: Build - run: ./conda-recipes/build_conda.sh build_output main-library + run: conda build ./conda-recipes/main-library --build-folder build_output - name: Upload all Conda packages uses: actions/upload-artifact@v4 From 99735c3ee518da7a111a9f7489ace0f0830cf5c4 Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Wed, 23 Apr 2025 14:46:12 +0200 Subject: [PATCH 71/82] got typo in github workflow --- .github/workflows/conda_library.yaml | 2 +- .github/workflows/conda_python.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conda_library.yaml b/.github/workflows/conda_library.yaml index 9bde3bb31..23f94d467 100644 --- a/.github/workflows/conda_library.yaml +++ b/.github/workflows/conda_library.yaml @@ -33,7 +33,7 @@ jobs: run: conda config --set anaconda_upload no - name: Build - run: conda build ./conda-recipes/main-library --build-folder build_output + run: conda build conda-recipes/main-library --output-folder build_output - name: Upload all Conda packages uses: actions/upload-artifact@v4 diff --git a/.github/workflows/conda_python.yaml b/.github/workflows/conda_python.yaml index 778b18ad7..5dad7745a 100644 --- a/.github/workflows/conda_python.yaml +++ b/.github/workflows/conda_python.yaml @@ -33,7 +33,7 @@ jobs: run: conda config --set anaconda_upload no - name: Build - run: conda build ./conda-recipes/python-client --build-folder build_output + run: conda build ./conda-recipes/python-client --output-folder build_output - name: Upload all Conda packages uses: actions/upload-artifact@v4 From bace9edf8934a898a4fdba9769f2f68f72669c7f Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Wed, 23 Apr 2025 17:09:06 +0200 Subject: [PATCH 72/82] updatet regex pattern to support postfix --- .github/workflows/conda_python.yaml | 2 +- conda-recipes/main-library/meta.yaml | 2 +- conda-recipes/python-client/meta.yaml | 3 +-- update_version.py | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/conda_python.yaml b/.github/workflows/conda_python.yaml index 5dad7745a..4b12cb3ff 100644 --- a/.github/workflows/conda_python.yaml +++ b/.github/workflows/conda_python.yaml @@ -33,7 +33,7 @@ jobs: run: conda config --set anaconda_upload no - name: Build - run: conda build ./conda-recipes/python-client --output-folder build_output + run: conda build conda-recipes/python-client --output-folder build_output - name: Upload all Conda packages uses: actions/upload-artifact@v4 diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index 2c2c88058..3a45167cc 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -1,7 +1,7 @@ source: path: ../.. -{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+\.\d+\.\d+)').group(1) %} +{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+\.\d+\.\d+(?:[\.\-][\.\w\-]+)?)').group(1) %} package: name: sls_detector_software version: {{ version }} #2025.3.19 diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml index cf4f3aa7b..03c4b4436 100644 --- a/conda-recipes/python-client/meta.yaml +++ b/conda-recipes/python-client/meta.yaml @@ -1,8 +1,7 @@ source: path: ../.. -{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+\.\d+\.\d+)').group(1) %} - +{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+\.\d+\.\d+(?:[\.\w\-]+)?)').group(1) %} package: name: slsdet version: {{ version }} # diff --git a/update_version.py b/update_version.py index 507857133..c72099b3c 100644 --- a/update_version.py +++ b/update_version.py @@ -17,8 +17,8 @@ def get_version(): version = sys.argv[1] # Validate that the version argument matches semantic versioning format (X.Y.Z) - if not re.match(r'^\d+\.\d+\.\d+$', version): - print("Error: Version argument must be in semantic versioning format (X.Y.Z)") + if not re.match(r'^\d+\.\d+\.\d+(?:[\-\.][\.\w\-]+)?+$', version): + print("Error: Version argument must be in semantic versioning format (X.Y.Z[./-][postfix])") sys.exit(1) return version From 0e4cb7cbcd8482b872a24d46c3111637d4b5369e Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Thu, 24 Apr 2025 08:45:18 +0200 Subject: [PATCH 73/82] normalized version to PEP 440 specification in update_version.py --- conda-recipes/main-library/meta.yaml | 4 +--- conda-recipes/python-client/meta.yaml | 2 +- update_version.py | 14 ++++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index 3a45167cc..bfc176363 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -1,7 +1,7 @@ source: path: ../.. -{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+\.\d+\.\d+(?:[\.\-][\.\w\-]+)?)').group(1) %} +{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*+(?:[\+\w\.]+))').group(1) %} package: name: sls_detector_software version: {{ version }} #2025.3.19 @@ -49,8 +49,6 @@ outputs: - libgcc-ng - - - name: slsdetgui script: copy_gui.sh requirements: diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml index 03c4b4436..dd9ea031c 100644 --- a/conda-recipes/python-client/meta.yaml +++ b/conda-recipes/python-client/meta.yaml @@ -1,7 +1,7 @@ source: path: ../.. -{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+\.\d+\.\d+(?:[\.\w\-]+)?)').group(1) %} +{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*+(?:[\+\w\.]+))').group(1) %} package: name: slsdet version: {{ version }} # diff --git a/update_version.py b/update_version.py index c72099b3c..914797a1d 100644 --- a/update_version.py +++ b/update_version.py @@ -7,6 +7,7 @@ Script to update VERSION file with semantic versioning if provided as an argumen import sys import re import toml +from packaging.version import Version, InvalidVersion def get_version(): @@ -16,21 +17,22 @@ def get_version(): version = sys.argv[1] - # Validate that the version argument matches semantic versioning format (X.Y.Z) - if not re.match(r'^\d+\.\d+\.\d+(?:[\-\.][\.\w\-]+)?+$', version): - print("Error: Version argument must be in semantic versioning format (X.Y.Z[./-][postfix])") + try: + v = Version(version) # normalize according to PEP 440 specification + return v + except InvalidVersion as e: + print(f"Invalid version {version}. Version format must follow semantic versioning format of python PEP 440 version identification specification.") sys.exit(1) - return version def write_version_to_file(version): with open("VERSION", "w") as version_file: - version_file.write(version) + version_file.write(str(version)) print(f"Version {version} written to VERSION file.") def update_pyproject_toml_file(version): pyproject = toml.load("pyproject.toml") - pyproject["project"]["version"] = version + pyproject["project"]["version"] = str(version) toml.dump(pyproject, open("pyproject.toml", "w")) #write back print(f"Version in pyproject.toml set to {version}") From c3f1d050338ee7451131c7ff2e82ab1126ff1d40 Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Thu, 24 Apr 2025 09:16:32 +0200 Subject: [PATCH 74/82] bug did not support version 0.0.0 --- conda-recipes/main-library/meta.yaml | 2 +- conda-recipes/python-client/meta.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index bfc176363..5ac6967d2 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -1,7 +1,7 @@ source: path: ../.. -{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*+(?:[\+\w\.]+))').group(1) %} +{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*(?:[\+\w\.]+))').group(1) %} package: name: sls_detector_software version: {{ version }} #2025.3.19 diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml index dd9ea031c..d3fed0b9a 100644 --- a/conda-recipes/python-client/meta.yaml +++ b/conda-recipes/python-client/meta.yaml @@ -1,7 +1,7 @@ source: path: ../.. -{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*+(?:[\+\w\.]+))').group(1) %} +{% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*(?:[\+\w\.]+))').group(1) %} package: name: slsdet version: {{ version }} # From 4d7d3c9138b9a2a4520e06b44e96a39dc244733d Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Fri, 25 Apr 2025 09:09:49 +0200 Subject: [PATCH 75/82] upgrading to c++17 from c++11 and patch command has to be found before applying patch on libzmq (#1195) --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b1d035d76..6b3127da1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,10 @@ endif() # Patch is applied in the FetchContent_Declare set(SLS_LIBZMQ_VERSION "4.3.4") +find_program(PATCH_EXECUTABLE patch) +if(NOT PATCH_EXECUTABLE) + message(FATAL_ERROR "The 'patch' tool is required for patching lib zeromq. Please install it.") +endif() if(SLS_FETCH_ZMQ_FROM_GITHUB) # Opt in to pull down a zmq version from github instead of @@ -216,7 +220,7 @@ endif() # to control options for the libraries if(NOT TARGET slsProjectOptions) add_library(slsProjectOptions INTERFACE) - target_compile_features(slsProjectOptions INTERFACE cxx_std_11) + target_compile_features(slsProjectOptions INTERFACE cxx_std_17) endif() if (NOT TARGET slsProjectWarnings) From 5fa2402ec53ad6937517e5576132ea1466f8a40d Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Fri, 25 Apr 2025 10:14:15 +0200 Subject: [PATCH 76/82] Dev/allow localhost for virtual tests (#1190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove the check for localhost being used in rx_hostname for python test for simulators, run rx_arping test only if hostname is not 'localhost' * fix tests for fpath: cannot set back to empty anymore (empty is default) * default rx_hostname arg = localhost, and default settings path =../../settingsdir * changed virtual tests script for better printout on exceptions * fix for catching generaltests exceptions and exiting instead of continuing * fix minor * fixed shared memeory tests to include current env and fixed prints for errors --------- Co-authored-by: Erik Fröjdh --- .../tests/Caller/test-Caller-rx.cpp | 39 ++--- .../tests/test-SharedMemory.cpp | 25 +++- tests/scripts/test_simulators.py | 138 +++++++++--------- 3 files changed, 114 insertions(+), 88 deletions(-) diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp index 508abc59d..fcf0de97d 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp @@ -445,23 +445,25 @@ TEST_CASE("rx_arping", "[.cmdcall][.rx]") { Detector det; Caller caller(&det); auto prev_val = det.getRxArping(); - { - std::ostringstream oss; - caller.call("rx_arping", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_arping 1\n"); - } - { - std::ostringstream oss; - caller.call("rx_arping", {}, -1, GET, oss); - REQUIRE(oss.str() == "rx_arping 1\n"); - } - { - std::ostringstream oss; - caller.call("rx_arping", {"0"}, -1, PUT, oss); - REQUIRE(oss.str() == "rx_arping 0\n"); - } - for (int i = 0; i != det.size(); ++i) { - det.setRxArping(prev_val[i], {i}); + if (det.getDestinationUDPIP()[0].str() != "127.0.0.1") { + { + std::ostringstream oss; + caller.call("rx_arping", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_arping 1\n"); + } + { + std::ostringstream oss; + caller.call("rx_arping", {}, -1, GET, oss); + REQUIRE(oss.str() == "rx_arping 1\n"); + } + { + std::ostringstream oss; + caller.call("rx_arping", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "rx_arping 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setRxArping(prev_val[i], {i}); + } } } @@ -583,6 +585,9 @@ TEST_CASE("fpath", "[.cmdcall]") { REQUIRE(oss.str() == "fpath /tmp\n"); } for (int i = 0; i != det.size(); ++i) { + if (prev_val[i].empty()) { + continue; + } det.setFilePath(prev_val[i], {i}); } } diff --git a/slsDetectorSoftware/tests/test-SharedMemory.cpp b/slsDetectorSoftware/tests/test-SharedMemory.cpp index 5ba3c20a2..4dff6d5d7 100644 --- a/slsDetectorSoftware/tests/test-SharedMemory.cpp +++ b/slsDetectorSoftware/tests/test-SharedMemory.cpp @@ -18,11 +18,16 @@ struct Data { constexpr int shm_id = 10; TEST_CASE("Create SharedMemory read and write", "[detector]") { + const char *env_p = std::getenv("SLSDETNAME"); + std::string env_name = env_p ? ("_" + std::string(env_p)) : ""; SharedMemory shm(shm_id, -1); + if (shm.exists()) { + shm.removeSharedMemory(); + } shm.createSharedMemory(); CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + - std::to_string(shm_id)); + std::to_string(shm_id) + env_name); shm()->x = 3; shm()->y = 5.7; @@ -90,10 +95,12 @@ TEST_CASE("Open two shared memories to the same place", "[detector]") { } TEST_CASE("Move SharedMemory", "[detector]") { + const char *env_p = std::getenv("SLSDETNAME"); + std::string env_name = env_p ? ("_" + std::string(env_p)) : ""; SharedMemory shm(shm_id, -1); CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") + - std::to_string(shm_id)); + std::to_string(shm_id) + env_name); shm.createSharedMemory(); shm()->x = 9; @@ -104,15 +111,19 @@ TEST_CASE("Move SharedMemory", "[detector]") { REQUIRE_THROWS( shm()); // trying to access should throw instead of returning a nullptr CHECK(shm2.getName() == std::string("/slsDetectorPackage_detector_") + - std::to_string(shm_id)); + std::to_string(shm_id) + env_name); shm2.removeSharedMemory(); } TEST_CASE("Create several shared memories", "[detector]") { + const char *env_p = std::getenv("SLSDETNAME"); + std::string env_name = env_p ? ("_" + std::string(env_p)) : ""; + constexpr int N = 5; std::vector> v; v.reserve(N); for (int i = 0; i != N; ++i) { + std::cout << "i:" << i << std::endl; v.emplace_back(shm_id + i, -1); CHECK(v[i].exists() == false); v[i].createSharedMemory(); @@ -123,7 +134,7 @@ TEST_CASE("Create several shared memories", "[detector]") { for (int i = 0; i != N; ++i) { CHECK(*v[i]() == i); CHECK(v[i].getName() == std::string("/slsDetectorPackage_detector_") + - std::to_string(i + shm_id)); + std::to_string(i + shm_id) + env_name); } for (int i = 0; i != N; ++i) { @@ -133,8 +144,12 @@ TEST_CASE("Create several shared memories", "[detector]") { } TEST_CASE("Create create a shared memory with a tag") { + const char *env_p = std::getenv("SLSDETNAME"); + std::string env_name = env_p ? ("_" + std::string(env_p)) : ""; + SharedMemory shm(0, -1, "ctbdacs"); - REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_ctbdacs"); + REQUIRE(shm.getName() == + "/slsDetectorPackage_detector_0" + env_name + "_ctbdacs"); } TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set") { diff --git a/tests/scripts/test_simulators.py b/tests/scripts/test_simulators.py index ce7fbd420..ea580c5e6 100644 --- a/tests/scripts/test_simulators.py +++ b/tests/scripts/test_simulators.py @@ -4,7 +4,7 @@ This file is used to start up simulators, receivers and run all the tests on them and finally kill the simulators and receivers. ''' import argparse -import os, sys, subprocess, time, colorama, signal +import os, sys, subprocess, time, colorama from colorama import Fore from slsdet import Detector, detectorType, detectorSettings @@ -23,23 +23,9 @@ def Log(color, message): def checkIfProcessRunning(processName): - cmd = "ps -ef | grep " + processName - print(cmd) - res=subprocess.getoutput(cmd) - print(res) - # eg. of output - #l_user 250506 243295 0 14:38 pts/5 00:00:00 /bin/sh -c ps -ef | grep slsReceiver - #l_user 250508 250506 0 14:38 pts/5 00:00:00 grep slsReceiver - - print('how many') - cmd = "ps -ef | grep " + processName + " | wc -l" - print(cmd) - res=subprocess.getoutput(cmd) - print(res) - - if res == '2': - return False - return True + cmd = f"pgrep -f {processName}" + res = subprocess.getoutput(cmd) + return bool(res.strip()) def killProcess(name): @@ -52,7 +38,7 @@ def killProcess(name): print('process not running : ' + name) -def killAllStaleProcesses(): +def killAllStaleProcesses(fp): killProcess('eigerDetectorServer_virtual') killProcess('jungfrauDetectorServer_virtual') killProcess('mythen3DetectorServer_virtual') @@ -62,9 +48,9 @@ def killAllStaleProcesses(): killProcess('xilinx_ctbDetectorServer_virtual') killProcess('slsReceiver') killProcess('slsMultiReceiver') - cleanSharedmemory() + cleanSharedmemory(fp) -def cleanup(name): +def cleanup(name, fp): ''' kill both servers, receivers and clean shared memory ''' @@ -72,9 +58,9 @@ def cleanup(name): killProcess(name + 'DetectorServer_virtual') killProcess('slsReceiver') killProcess('slsMultiReceiver') - cleanSharedmemory() + cleanSharedmemory(fp) -def cleanSharedmemory(): +def cleanSharedmemory(fp): Log(Fore.GREEN, 'Cleaning up shared memory...') try: p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp) @@ -87,8 +73,8 @@ def startProcessInBackground(name): # in background and dont print output p = subprocess.Popen(name.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False) Log(Fore.GREEN, 'Starting up ' + name + ' ...') - except: - Log(Fore.RED, 'Could not start ' + name) + except Exception as e: + Log(Fore.RED, f'Could not start {name}:{e}') raise def startServer(name): @@ -139,14 +125,19 @@ def loadConfig(name, rx_hostname, settingsdir): def startCmdTests(name, fp, fname): Log(Fore.GREEN, 'Cmd Tests for ' + name) cmd = 'tests --abort [.cmdcall] -s -o ' + fname - p = subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True) - p.check_returncode() + try: + subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True) + except subprocess.CalledProcessError as e: + pass with open (fname, 'r') as f: for line in f: if "FAILED" in line: msg = 'Cmd tests failed for ' + name + '!!!' + sys.stdout = original_stdout Log(Fore.RED, msg) + Log(Fore.RED, line) + sys.stdout = fp raise Exception(msg) Log(Fore.GREEN, 'Cmd Tests successful for ' + name) @@ -154,14 +145,18 @@ def startCmdTests(name, fp, fname): def startGeneralTests(fp, fname): Log(Fore.GREEN, 'General Tests') cmd = 'tests --abort -s -o ' + fname - p = subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True) - p.check_returncode() + try: + subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True) + except subprocess.CalledProcessError as e: + pass with open (fname, 'r') as f: for line in f: if "FAILED" in line: msg = 'General tests failed !!!' - Log(Fore.RED, msg) + sys.stdout = original_stdout + Log(Fore.RED, msg + '\n' + line) + sys.stdout = fp raise Exception(msg) Log(Fore.GREEN, 'General Tests successful') @@ -170,12 +165,10 @@ def startGeneralTests(fp, fname): # parse cmd line for rx_hostname and settingspath using the argparse library parser = argparse.ArgumentParser(description = 'automated tests with the virtual detector servers') -parser.add_argument('rx_hostname', help = 'hostname/ip of the current machine') -parser.add_argument('settingspath', help = 'Relative or absolut path to the settingspath') +parser.add_argument('rx_hostname', nargs='?', default='localhost', help = 'hostname/ip of the current machine') +parser.add_argument('settingspath', nargs='?', default='../../settingsdir', help = 'Relative or absolut path to the settingspath') parser.add_argument('-s', '--servers', help='Detector servers to run', nargs='*') args = parser.parse_args() -if args.rx_hostname == 'localhost': - raise RuntimeException('Cannot use localhost for rx_hostname for the tests (fails for rx_arping for eg.)') if args.servers is None: servers = [ @@ -203,46 +196,59 @@ Log(Fore.BLUE, '\nLog File: ' + fname) with open(fname, 'w') as fp: + + # general tests file_results = prefix_fname + '_results_general.txt' Log(Fore.BLUE, 'General tests (results: ' + file_results + ')') sys.stdout = fp sys.stderr = fp Log(Fore.BLUE, 'General tests (results: ' + file_results + ')') - startGeneralTests(fp, file_results) - killAllStaleProcesses() + try: + startGeneralTests(fp, file_results) + killAllStaleProcesses(fp) - for server in servers: - try: - # print to terminal for progress - sys.stdout = original_stdout - sys.stderr = original_stderr - file_results = prefix_fname + '_results_cmd_' + server + '.txt' - Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')') - sys.stdout = fp - sys.stderr = fp - Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')') - - # cmd tests for det - cleanup(server) - startServer(server) - startReceiver(server) - loadConfig(server, args.rx_hostname, args.settingspath) - startCmdTests(server, fp, file_results) - cleanup(server) - except: - Log(Fore.RED, 'Exception caught. Cleaning up.') - cleanup(server) - sys.stdout = original_stdout - sys.stderr = original_stderr - Log(Fore.RED, 'Cmd tests failed for ' + server + '!!!') - raise + testError = False + for server in servers: + try: + # print to terminal for progress + sys.stdout = original_stdout + sys.stderr = original_stderr + file_results = prefix_fname + '_results_cmd_' + server + '.txt' + Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')') + sys.stdout = fp + sys.stderr = fp + Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')') + + # cmd tests for det + cleanup(server, fp) + startServer(server) + startReceiver(server) + loadConfig(server, args.rx_hostname, args.settingspath) + startCmdTests(server, fp, file_results) + cleanup(server, fp) + + except Exception as e: + # redirect to terminal + sys.stdout = original_stdout + sys.stderr = original_stderr + Log(Fore.RED, f'Exception caught while testing {server}. Cleaning up...') + testError = True + break + + # redirect to terminal + sys.stdout = original_stdout + sys.stderr = original_stderr + if not testError: + Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers)) - Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers)) + except Exception as e: + # redirect to terminal + sys.stdout = original_stdout + sys.stderr = original_stderr + Log(Fore.RED, f'Exception caught with general testing. Cleaning up...') + cleanSharedmemory(sys.stdout) + -# redirect to terminal -sys.stdout = original_stdout -sys.stderr = original_stderr -Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers) + '\nYayyyy! :) ') \ No newline at end of file From 2815913d1051635182d3a1332163c80f077b85e1 Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Fri, 25 Apr 2025 10:48:16 +0200 Subject: [PATCH 77/82] added regex pattern matching to version in toml file --- conda-recipes/main-library/meta.yaml | 2 +- conda-recipes/python-client/meta.yaml | 2 +- pyproject.toml | 8 +++++++- update_version.py | 17 +++++++---------- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/conda-recipes/main-library/meta.yaml b/conda-recipes/main-library/meta.yaml index 5ac6967d2..8b11b4536 100755 --- a/conda-recipes/main-library/meta.yaml +++ b/conda-recipes/main-library/meta.yaml @@ -4,7 +4,7 @@ source: {% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*(?:[\+\w\.]+))').group(1) %} package: name: sls_detector_software - version: {{ version }} #2025.3.19 + version: {{ version }} build: number: 0 diff --git a/conda-recipes/python-client/meta.yaml b/conda-recipes/python-client/meta.yaml index d3fed0b9a..c86f401ef 100644 --- a/conda-recipes/python-client/meta.yaml +++ b/conda-recipes/python-client/meta.yaml @@ -4,7 +4,7 @@ source: {% set version = load_file_regex(load_file = 'VERSION', regex_pattern = '(\d+(?:\.\d+)*(?:[\+\w\.]+))').group(1) %} package: name: slsdet - version: {{ version }} # + version: {{ version }} build: number: 0 diff --git a/pyproject.toml b/pyproject.toml index 776657c41..8deb25dde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,16 @@ +[tool.scikit-build.metadata.version] +provider = "scikit_build_core.metadata.regex" +input = "VERSION" +regex = '^(?P\d+(?:\.\d+)*(?:[\.\+\w]+)?)$' +result = "{version}" + [build-system] requires = [ "scikit-build-core>=0.10", "pybind11", "numpy",] build-backend = "scikit_build_core.build" [project] name = "slsdet" -version = "0.0.0" +dynamic = ["version"] [tool.cibuildwheel] before-all = "uname -a" diff --git a/update_version.py b/update_version.py index 914797a1d..2b5609198 100644 --- a/update_version.py +++ b/update_version.py @@ -5,10 +5,13 @@ Script to update VERSION file with semantic versioning if provided as an argumen """ import sys -import re -import toml +import os + from packaging.version import Version, InvalidVersion + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) + def get_version(): # Check at least one argument is passed @@ -26,19 +29,13 @@ def get_version(): def write_version_to_file(version): - with open("VERSION", "w") as version_file: + version_file_path = os.path.join(SCRIPT_DIR, "VERSION") + with open(version_file_path, "w") as version_file: version_file.write(str(version)) print(f"Version {version} written to VERSION file.") -def update_pyproject_toml_file(version): - pyproject = toml.load("pyproject.toml") - pyproject["project"]["version"] = str(version) - toml.dump(pyproject, open("pyproject.toml", "w")) #write back - print(f"Version in pyproject.toml set to {version}") - # Main script if __name__ == "__main__": version = get_version() write_version_to_file(version) - update_pyproject_toml_file(version) From 625f4353fbc3bcd4102022d3050e93767d3cca3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fr=C3=B6jdh?= Date: Fri, 25 Apr 2025 12:04:45 +0200 Subject: [PATCH 78/82] Dev/gitea docker (#1194) * gitea workflows for RH8 and RH9 * using our docker images --- .gitea/workflows/rh8-native.yml | 29 +++++++++++++++++++++++++++++ .gitea/workflows/rh9-native.yml | 27 +++++++++++++++++++++++++++ CMakeLists.txt | 3 ++- 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/rh8-native.yml create mode 100644 .gitea/workflows/rh9-native.yml diff --git a/.gitea/workflows/rh8-native.yml b/.gitea/workflows/rh8-native.yml new file mode 100644 index 000000000..51d754125 --- /dev/null +++ b/.gitea/workflows/rh8-native.yml @@ -0,0 +1,29 @@ +name: Build on RHEL8 + +on: + push: + workflow_dispatch: + +permissions: + contents: read + +jobs: + build: + runs-on: "ubuntu-latest" + container: + image: gitea.psi.ch/detectors/rhel8-detectors-dev + steps: + - name: Clone repository + run: | + echo Cloning ${{ github.ref_name }} + git clone https://${{secrets.GITHUB_TOKEN}}@gitea.psi.ch/${{ github.repository }}.git --branch=${{ github.ref_name }} . + + - name: Build library + run: | + mkdir build && cd build + cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON + make -j 2 + + - name: C++ unit tests + working-directory: ${{gitea.workspace}}/build + run: ctest \ No newline at end of file diff --git a/.gitea/workflows/rh9-native.yml b/.gitea/workflows/rh9-native.yml new file mode 100644 index 000000000..890b09edf --- /dev/null +++ b/.gitea/workflows/rh9-native.yml @@ -0,0 +1,27 @@ +name: Build on RHEL9 + +on: + push: + workflow_dispatch: + +permissions: + contents: read + +jobs: + build: + runs-on: "ubuntu-latest" + container: + image: gitea.psi.ch/detectors/rhel9-detectors-dev + steps: + - uses: actions/checkout@v4 + + + - name: Build library + run: | + mkdir build && cd build + cmake .. -DSLS_USE_PYTHON=ON -DSLS_USE_TESTS=ON + make -j 2 + + - name: C++ unit tests + working-directory: ${{gitea.workspace}}/build + run: ctest \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b3127da1..212281f68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -333,7 +333,8 @@ if (SLS_USE_INTEGRATION_TESTS) endif (SLS_USE_INTEGRATION_TESTS) if (SLS_USE_PYTHON) - find_package (Python 3.8 COMPONENTS Interpreter Development) + find_package (Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED) + set(PYBIND11_FINDPYTHON ON) # Needed for RH8 if(SLS_FETCH_PYBIND11_FROM_GITHUB) FetchContent_Declare( pybind11 From 27530fca31ccae8193cab4c4e77a62cb8181409d Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Tue, 29 Apr 2025 11:14:52 +0200 Subject: [PATCH 79/82] version now supports . before postfix --- update_version.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/update_version.py b/update_version.py index 2b5609198..6b3e1ebad 100644 --- a/update_version.py +++ b/update_version.py @@ -19,10 +19,11 @@ def get_version(): return "0.0.0" version = sys.argv[1] - + try: - v = Version(version) # normalize according to PEP 440 specification - return v + v = Version(version) # normalizcheck if version follows PEP 440 specification + #replace - + return version.replace("-", ".") except InvalidVersion as e: print(f"Invalid version {version}. Version format must follow semantic versioning format of python PEP 440 version identification specification.") sys.exit(1) @@ -31,7 +32,7 @@ def get_version(): def write_version_to_file(version): version_file_path = os.path.join(SCRIPT_DIR, "VERSION") with open(version_file_path, "w") as version_file: - version_file.write(str(version)) + version_file.write(version) print(f"Version {version} written to VERSION file.") # Main script From 98b1e287a4446e7dbec9920f6fbaea6b7a4667b5 Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Wed, 30 Apr 2025 09:08:07 +0200 Subject: [PATCH 80/82] moved dbitoffset, dbitreorder and dbitlist to GeneralData --- slsReceiverSoftware/src/DataProcessor.cpp | 28 ++++++------- slsReceiverSoftware/src/DataProcessor.h | 8 +--- slsReceiverSoftware/src/GeneralData.h | 29 +++++++++++++ slsReceiverSoftware/src/Implementation.cpp | 37 +++++++--------- slsReceiverSoftware/src/Implementation.h | 3 -- .../tests/test-ArrangeDataBasedOnBitList.cpp | 42 +++++++++++-------- 6 files changed, 83 insertions(+), 64 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 1956d3578..710875496 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -72,14 +72,6 @@ void DataProcessor::SetStreamingStartFnum(uint32_t value) { void DataProcessor::SetFramePadding(bool enable) { framePadding = enable; } -void DataProcessor::SetCtbDbitList(std::vector value) { - ctbDbitList = 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) { @@ -361,13 +353,14 @@ void DataProcessor::ProcessAnImage(sls_receiver_header &header, size_t &size, PadMissingPackets(header, data); // rearrange ctb digital bits - if (!ctbDbitList.empty()) { + if (!generalData->ctbDbitList.empty()) { ArrangeDbitData(size, data); - } else if (ctbDbitReorder) { - ctbDbitList.resize(64); + } else if (generalData->ctbDbitReorder) { + std::vector ctbDbitList(64); std::iota(ctbDbitList.begin(), ctbDbitList.end(), 0); + generalData->SetctbDbitList(ctbDbitList); ArrangeDbitData(size, data); - } else if (ctbDbitOffset > 0) { + } else if (generalData->ctbDbitOffset > 0) { RemoveTrailingBits(size, data); } @@ -542,6 +535,7 @@ void DataProcessor::RemoveTrailingBits(size_t &size, char *data) { const size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); const size_t nTransceiverDataBytes = generalData->GetNumberOfTransceiverDatabytes(); + const size_t ctbDbitOffset = generalData->ctbDbitOffset; const size_t ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset; @@ -568,10 +562,14 @@ void DataProcessor::ArrangeDbitData(size_t &size, char *data) { std::to_string(generalData->detType)); } - size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); - size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); - size_t nTransceiverDataBytes = + const size_t nAnalogDataBytes = generalData->GetNumberOfAnalogDatabytes(); + const size_t nDigitalDataBytes = generalData->GetNumberOfDigitalDatabytes(); + const size_t nTransceiverDataBytes = generalData->GetNumberOfTransceiverDatabytes(); + const size_t ctbDbitOffset = generalData->ctbDbitOffset; + const bool ctbDbitReorder = generalData->ctbDbitReorder; + const auto ctbDbitList = generalData->ctbDbitList; + // TODO! (Erik) Refactor and add tests int ctbDigitalDataBytes = nDigitalDataBytes - ctbDbitOffset; diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index 16778ec23..e21d73c90 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -45,9 +45,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { void SetStreamingTimerInMs(uint32_t value); void SetStreamingStartFnum(uint32_t value); void SetFramePadding(bool enable); - void SetCtbDbitList(std::vector value); - void SetCtbDbitOffset(int value); - void SetCtbDbitReorder(bool value); void SetQuadEnable(bool value); void SetFlipRows(bool fd); void SetNumberofTotalFrames(uint64_t value); @@ -171,11 +168,8 @@ 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}; - bool ctbDbitReorder{true}; std::atomic startedFlag{false}; std::atomic firstIndex{0}; bool quadEnable{false}; diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index 17a4ea7e5..6657630cc 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -52,6 +52,9 @@ class GeneralData { uint32_t nAnalogSamples{0}; uint32_t nDigitalSamples{0}; uint32_t nTransceiverSamples{0}; + std::vector ctbDbitList; + int ctbDbitOffset{0}; + bool ctbDbitReorder{false}; slsDetectorDefs::readoutMode readoutType{slsDetectorDefs::ANALOG_ONLY}; uint32_t adcEnableMaskOneGiga{BIT32_MASK}; uint32_t adcEnableMaskTenGiga{BIT32_MASK}; @@ -148,6 +151,18 @@ class GeneralData { virtual void SetTransceiverEnableMask(int n) { ThrowGenericError("SetTransceiverEnableMask"); }; + + virtual void SetctbDbitOffset(const int n) { + ThrowGenericError("SetctbDbitOffset"); + }; + + virtual void SetctbDbitList(const std::vector &value) { + ThrowGenericError("SetctbDbitList"); + }; + + virtual void SetctbDbitReorder(const bool reorder) { + ThrowGenericError("SetctbDbitReorder"); + }; }; class EigerData : public GeneralData { @@ -387,6 +402,7 @@ class ChipTestBoardData : public GeneralData { framesPerFile = CTB_MAX_FRAMES_PER_FILE; fifoDepth = 2500; standardheader = true; + ctbDbitReorder = true; UpdateImageSize(); }; @@ -412,6 +428,12 @@ class ChipTestBoardData : public GeneralData { UpdateImageSize(); }; + void SetctbDbitOffset(const int value) { ctbDbitOffset = value; } + + void SetctbDbitList(const std::vector &value) { ctbDbitList = value; } + + void SetctbDbitReorder(const bool value) { ctbDbitReorder = value; } + void SetOneGigaAdcEnableMask(int n) { adcEnableMaskOneGiga = n; UpdateImageSize(); @@ -518,6 +540,7 @@ class XilinxChipTestBoardData : public GeneralData { dataSize = 8144; packetSize = headerSizeinPacket + dataSize; tengigaEnable = true; + ctbDbitReorder = true; UpdateImageSize(); }; @@ -543,6 +566,12 @@ class XilinxChipTestBoardData : public GeneralData { UpdateImageSize(); }; + void SetctbDbitOffset(const int value) { ctbDbitOffset = value; } + + void SetctbDbitList(const std::vector &value) { ctbDbitList = value; } + + void SetctbDbitReorder(const bool value) { ctbDbitReorder = value; } + void SetOneGigaAdcEnableMask(int n) { adcEnableMaskOneGiga = n; UpdateImageSize(); diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index e4385d9c0..f9480c5d4 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -200,9 +200,6 @@ void Implementation::SetupDataProcessor(int i) { dataProcessor[i]->SetStreamingTimerInMs(streamingTimerInMs); dataProcessor[i]->SetStreamingStartFnum(streamingStartFnum); 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); @@ -991,11 +988,11 @@ void Implementation::StartMasterWriter() { ? 1 : 0; masterAttributes.digitalSamples = generalData->nDigitalSamples; - masterAttributes.dbitoffset = ctbDbitOffset; - masterAttributes.dbitreorder = ctbDbitReorder; + masterAttributes.dbitoffset = generalData->ctbDbitOffset; + masterAttributes.dbitreorder = generalData->ctbDbitReorder; masterAttributes.dbitlist = 0; - for (auto &i : ctbDbitList) { + for (auto &i : generalData->ctbDbitList) { masterAttributes.dbitlist |= (static_cast(1) << i); } masterAttributes.transceiverSamples = @@ -1751,31 +1748,29 @@ void Implementation::setTenGigaADCEnableMask(uint32_t mask) { LOG(logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame); } -std::vector Implementation::getDbitList() const { return ctbDbitList; } +std::vector Implementation::getDbitList() const { + return generalData->ctbDbitList; +} void Implementation::setDbitList(const std::vector &v) { - ctbDbitList = v; - for (const auto &it : dataProcessor) - it->SetCtbDbitList(ctbDbitList); - LOG(logINFO) << "Dbit list: " << ToString(ctbDbitList); + generalData->SetctbDbitList(v); + LOG(logINFO) << "Dbit list: " << ToString(v); } -int Implementation::getDbitOffset() const { return ctbDbitOffset; } +int Implementation::getDbitOffset() const { return generalData->ctbDbitOffset; } void Implementation::setDbitOffset(const int s) { - ctbDbitOffset = s; - for (const auto &it : dataProcessor) - it->SetCtbDbitOffset(ctbDbitOffset); - LOG(logINFO) << "Dbit offset: " << ctbDbitOffset; + generalData->SetctbDbitOffset(s); + LOG(logINFO) << "Dbit offset: " << s; } -bool Implementation::getDbitReorder() const { return ctbDbitReorder; } +bool Implementation::getDbitReorder() const { + return generalData->ctbDbitReorder; +} void Implementation::setDbitReorder(const bool reorder) { - ctbDbitReorder = reorder; - for (const auto &it : dataProcessor) - it->SetCtbDbitReorder(ctbDbitReorder); - LOG(logINFO) << "Dbit reorder: " << ctbDbitReorder; + generalData->SetctbDbitReorder(reorder); + LOG(logINFO) << "Dbit reorder: " << reorder; } uint32_t Implementation::getTransceiverEnableMask() const { diff --git a/slsReceiverSoftware/src/Implementation.h b/slsReceiverSoftware/src/Implementation.h index 79baa670b..9fbf1fd28 100644 --- a/slsReceiverSoftware/src/Implementation.h +++ b/slsReceiverSoftware/src/Implementation.h @@ -370,9 +370,6 @@ class Implementation : private virtual slsDetectorDefs { int thresholdEnergyeV{-1}; std::array thresholdAllEnergyeV = {{-1, -1, -1}}; std::vector rateCorrections; - std::vector ctbDbitList; - int ctbDbitOffset{0}; - bool ctbDbitReorder{true}; // callbacks void (*startAcquisitionCallBack)(const startCallbackHeader, diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index f65ff3e80..df87f392f 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -32,17 +32,23 @@ class GeneralDataTest : public GeneralData { nTransceiverBytes = value; } + void SetCtbDbitOffset(const int value) { ctbDbitOffset = value; } + + void SetCtbDbitList(const std::vector &value) { ctbDbitList = value; } + + void SetCtbDbitReorder(const bool value) { ctbDbitReorder = value; } + private: - int nAnalogBytes; - int nDigitalBytes; - int nTransceiverBytes; + int nAnalogBytes{}; + int nDigitalBytes{}; + int nTransceiverBytes{}; }; // 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); } @@ -140,7 +146,7 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Remove Trailing Bits", set_random_offset_bytes(num_random_offset_bytes); set_data(); - dataprocessor->SetCtbDbitOffset(num_random_offset_bytes); + generaldata->SetCtbDbitOffset(num_random_offset_bytes); size_t expected_size = get_size() - num_random_offset_bytes; @@ -183,8 +189,8 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Reorder all", std::vector bitlist(64); std::iota(bitlist.begin(), bitlist.end(), 0); - dataprocessor->SetCtbDbitList(bitlist); - dataprocessor->SetCtbDbitReorder(true); // set reorder to true + generaldata->SetCtbDbitList(bitlist); + generaldata->SetCtbDbitReorder(true); // set reorder to true const size_t expected_size = num_analog_bytes + num_transceiver_bytes + expected_num_digital_bytes; @@ -222,9 +228,9 @@ TEST_CASE_METHOD(DataProcessorTestFixture, 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 + generaldata->SetCtbDbitList(bitlist); + generaldata->SetCtbDbitOffset(num_random_offset_bytes); + generaldata->SetCtbDbitReorder(true); // set reorder to true const size_t expected_num_digital_bytes = 64; std::vector expected_digital_part{0b00011111}; @@ -272,9 +278,9 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder false", std::tie(num_samples, bitlist, expected_num_digital_bytes, expected_digital_part) = parameters; - dataprocessor->SetCtbDbitList(bitlist); + generaldata->SetCtbDbitList(bitlist); - dataprocessor->SetCtbDbitReorder(false); + generaldata->SetCtbDbitReorder(false); set_num_samples(num_samples); set_data(); @@ -324,9 +330,9 @@ TEST_CASE_METHOD(DataProcessorTestFixture, "Arrange bitlist with reorder true", std::tie(num_samples, bitlist, expected_num_digital_bytes, expected_digital_part) = parameters; - dataprocessor->SetCtbDbitList(bitlist); + generaldata->SetCtbDbitList(bitlist); - dataprocessor->SetCtbDbitReorder(true); + generaldata->SetCtbDbitReorder(true); set_num_samples(num_samples); set_data(); @@ -368,11 +374,11 @@ TEST_CASE_METHOD(DataProcessorTestFixture, set_random_offset_bytes(num_random_offset_bytes); set_data(); - dataprocessor->SetCtbDbitList(bitlist); + generaldata->SetCtbDbitList(bitlist); - dataprocessor->SetCtbDbitReorder(false); + generaldata->SetCtbDbitReorder(false); - dataprocessor->SetCtbDbitOffset(num_random_offset_bytes); + generaldata->SetCtbDbitOffset(num_random_offset_bytes); std::vector expected_digital_part{0b00000111}; const size_t expected_num_digital_bytes = 5; From 062002243ef1bec664951fb86b449aeecbeef2d4 Mon Sep 17 00:00:00 2001 From: mazzol_a Date: Wed, 30 Apr 2025 10:54:34 +0200 Subject: [PATCH 81/82] added error message on receiver side, throw error --- slsReceiverSoftware/src/DataProcessor.cpp | 4 +++- slsReceiverSoftware/src/GeneralData.h | 2 +- slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 710875496..cfad27a3d 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -295,7 +295,9 @@ void DataProcessor::ThreadExecution() { memImage->data); } catch (const std::exception &e) { fifo->FreeAddress(buffer); - return; + LOG(logERROR) << "DataProcessor " << index << ": Failed to Process. " + << e.what() << std::endl; + throw RuntimeError(e.what()); } // stream (if time/freq to stream) or free diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index 6657630cc..7147d0e2c 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -52,7 +52,7 @@ class GeneralData { uint32_t nAnalogSamples{0}; uint32_t nDigitalSamples{0}; uint32_t nTransceiverSamples{0}; - std::vector ctbDbitList; + std::vector ctbDbitList{}; int ctbDbitOffset{0}; bool ctbDbitReorder{false}; slsDetectorDefs::readoutMode readoutType{slsDetectorDefs::ANALOG_ONLY}; diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index df87f392f..7ad93b908 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -73,8 +73,6 @@ class DataProcessorTestFixture { dataprocessor = new DataProcessorTest; generaldata = new GeneralDataTest; - // set_num_samples(num_samples); - generaldata->SetNumberOfAnalogDatabytes(num_analog_bytes); generaldata->SetNumberOfTransceiverDatabytes(num_transceiver_bytes); generaldata->SetNumberOfDigitalDatabytes(num_digital_bytes + From 36faec6ad34ca4710fedd885c0bb11130e6a7090 Mon Sep 17 00:00:00 2001 From: AliceMazzoleni99 Date: Wed, 30 Apr 2025 12:17:16 +0200 Subject: [PATCH 82/82] removed log as error already printed --- slsReceiverSoftware/src/DataProcessor.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index cfad27a3d..50a41753e 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -295,8 +295,6 @@ void DataProcessor::ThreadExecution() { memImage->data); } catch (const std::exception &e) { fifo->FreeAddress(buffer); - LOG(logERROR) << "DataProcessor " << index << ": Failed to Process. " - << e.what() << std::endl; throw RuntimeError(e.what()); }