From 7258adfe158342f47aa8591a0b5163aaba9d9461 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Tue, 24 Jun 2025 14:29:19 +0200 Subject: [PATCH] wip --- slsReceiverSoftware/src/DataProcessor.cpp | 15 +- slsReceiverSoftware/src/DataProcessor.h | 3 + slsReceiverSoftware/src/Implementation.cpp | 9 +- slsReceiverSoftware/src/MasterFileUtility.cpp | 250 ++++++++++-------- slsReceiverSoftware/src/MasterFileUtility.h | 3 +- 5 files changed, 157 insertions(+), 123 deletions(-) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index 7a02d2f62..64ae23547 100644 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -54,6 +54,11 @@ void DataProcessor::SetPortROI(ROI roi) { isOutsideRoi = portRoi.noRoi(); } +void DataProcessor::setMultiROIMetadata( + const std::vector &args) { + multiRoiMetadata = args; +} + void DataProcessor::SetDataStreamEnable(bool enable) { dataStreamEnable = enable; } @@ -203,9 +208,9 @@ std::string DataProcessor::CreateVirtualFile( const int modulePos, const int numModX, const int numModY, std::mutex *hdf5LibMutex) { - if (isPartiallyInRoi) { - throw std::runtime_error( - "Skipping virtual hdf5 file since rx_roi is enabled."); + if (!multiRoiMetadata.empty() && generalData->dynamicRange == 4) { + throw std::runtime_error("Skipping virtual hdf5 file since rx_roi is " + "enabled in 4 bit mode."); } bool gotthard25um = ((generalData->detType == GOTTHARD || @@ -227,7 +232,7 @@ std::string DataProcessor::CreateVirtualFile( generalData->nPixelsX, generalData->nPixelsY, generalData->dynamicRange, numFramesCaught, numModX, numModY, dataFile->GetPDataType(), dataFile->GetParameterNames(), dataFile->GetParameterDataTypes(), - hdf5LibMutex, gotthard25um); + hdf5LibMutex, gotthard25um, multiRoiMetadata); } void DataProcessor::LinkFileInMaster(const std::string &masterFileName, @@ -235,7 +240,7 @@ void DataProcessor::LinkFileInMaster(const std::string &masterFileName, const bool silentMode, std::mutex *hdf5LibMutex) { - if (isPartiallyInRoi) { + if (!multiRoiMetadata.empty()) { throw std::runtime_error( "Should not be here, roi with hdf5 virtual should throw."); } diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index a53e38de4..ecfdacc7e 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -40,6 +40,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { void SetUdpPortNumber(const uint16_t portNumber); void SetActivate(bool enable); void SetPortROI(const ROI arg); + void setMultiROIMetadata(const std::vector &args); void SetDataStreamEnable(bool enable); void SetStreamingFrequency(uint32_t value); void SetStreamingTimerInMs(uint32_t value); @@ -162,6 +163,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { ROI portRoi{}; bool isPartiallyInRoi{false}; bool isOutsideRoi{false}; + std::vector multiRoiMetadata{}; + std::unique_ptr completeImageToStreamBeforeCropping; /** if 0, sending random images with a timer */ uint32_t streamingFrequency; diff --git a/slsReceiverSoftware/src/Implementation.cpp b/slsReceiverSoftware/src/Implementation.cpp index ffffb7d05..10f5aead7 100644 --- a/slsReceiverSoftware/src/Implementation.cpp +++ b/slsReceiverSoftware/src/Implementation.cpp @@ -200,6 +200,8 @@ void Implementation::SetupDataProcessor(int i) { } else { dataProcessor[i]->SetPortROI(portRois[i]); } + if (i == 0) + dataProcessor[0]->setMultiROIMetadata(multiRoiMetadata); dataProcessor[i]->SetDataStreamEnable(dataStreamEnable); dataProcessor[i]->SetStreamingFrequency(streamingFrequency); dataProcessor[i]->SetStreamingTimerInMs(streamingTimerInMs); @@ -414,13 +416,16 @@ void Implementation::setPortROIs(const std::vector &args) { for (size_t i = 0; i != listener.size(); ++i) listener[i]->SetIsOutsideRoi(i >= portRois.size()); - for (size_t i = 0; i != dataProcessor.size(); ++i) + for (size_t i = 0; i != dataProcessor.size(); ++i) { if (i >= portRois.size()) { ROI roi{0, 0, 0, 0}; dataProcessor[i]->SetPortROI(roi); } else { dataProcessor[i]->SetPortROI(portRois[i]); } + } + if (dataProcessor.size() > 0) + dataProcessor[0]->setMultiROIMetadata(multiRoiMetadata); for (size_t i = 0; i != dataStreamer.size(); ++i) { if (i >= portRois.size()) { ROI roi{0, 0, 0, 0}; @@ -435,6 +440,8 @@ void Implementation::setPortROIs(const std::vector &args) { void Implementation::setMultiROIMetadata( const std::vector &args) { multiRoiMetadata = args; + if (dataProcessor.size() > 0) + dataProcessor[0]->setMultiROIMetadata(multiRoiMetadata); LOG(logINFO) << "Multi ROI Metadata: " << ToString(multiRoiMetadata); } diff --git a/slsReceiverSoftware/src/MasterFileUtility.cpp b/slsReceiverSoftware/src/MasterFileUtility.cpp index 793dc777e..6e0c7903b 100644 --- a/slsReceiverSoftware/src/MasterFileUtility.cpp +++ b/slsReceiverSoftware/src/MasterFileUtility.cpp @@ -160,6 +160,7 @@ std::string CreateMasterHDF5File(const std::string &filePath, return fileName; } +/** Will not be called if dynamic range is 4 and roi enabled */ std::string CreateVirtualHDF5File( const std::string &filePath, const std::string &fileNamePrefix, const uint64_t fileIndex, const bool overWriteEnable, const bool silentMode, @@ -169,7 +170,8 @@ std::string CreateVirtualHDF5File( const uint64_t numImagesCaught, const int numModX, const int numModY, const H5::DataType dataType, const std::vector parameterNames, const std::vector parameterDataTypes, - std::mutex *hdf5LibMutex, bool gotthard25um) { + std::mutex *hdf5LibMutex, bool gotthard25um, + std::vector &multiRoi) { // virtual file name std::ostringstream osfn; @@ -205,134 +207,150 @@ std::string CreateVirtualHDF5File( "version", H5::PredType::NATIVE_DOUBLE, dataspace_attr); attribute.write(H5::PredType::NATIVE_DOUBLE, &dValue); - // dataspace - hsize_t vdsDims[DATA_RANK] = {numImagesCaught, numModY * nDimy, - numModZ * nDimz}; - hsize_t vdsDimsPara[VDS_PARA_RANK] = {numImagesCaught, - numModY * numModZ}; - H5::DataSpace vdsDataSpace(DATA_RANK, vdsDims, nullptr); - H5::DataSpace vdsDataSpacePara(VDS_PARA_RANK, vdsDimsPara, nullptr); - - // property list - H5::DSetCreatPropList plist; - uint64_t fill_value = -1; - plist.setFillValue(dataType, &fill_value); - std::vector plistPara(paraSize); - // ignoring last fill (string) - for (unsigned int i = 0; i != plistPara.size() - 1; ++i) { - plistPara[i].setFillValue(parameterDataTypes[i], &fill_value); + // complete detector in roi + if (multiRoi.empty()) { + int ny = nPixelsY * numModY; + int nx = nPixelsX * numModX; + if (nPixelsY == 1) { + multiRoi.push_back(defs::ROI{0, nx - 1}); + } else { + multiRoi.push_back(defs::ROI{0, nx - 1, 0, ny - 1}); + } } - // hyperslab (files) - int numFiles = numImagesCaught / maxFramesPerFile; - if (numImagesCaught % maxFramesPerFile) - ++numFiles; - uint64_t framesSaved = 0; - for (int iFile = 0; iFile < numFiles; ++iFile) { + for (size_t iRoi = 0; iRoi != multiRoi.size(); ++iRoi) { - uint64_t nDimx = - ((numImagesCaught - framesSaved) > maxFramesPerFile) - ? maxFramesPerFile - : (numImagesCaught - framesSaved); + // dataspace + hsize_t vdsDims[DATA_RANK] = {numImagesCaught, numModY * nDimy, + numModZ * nDimz}; + hsize_t vdsDimsPara[VDS_PARA_RANK] = {numImagesCaught, + numModY * numModZ}; + H5::DataSpace vdsDataSpace(DATA_RANK, vdsDims, nullptr); + H5::DataSpace vdsDataSpacePara(VDS_PARA_RANK, vdsDimsPara, nullptr); - hsize_t startLocation[DATA_RANK] = {framesSaved, 0, 0}; - hsize_t strideBetweenBlocks[DATA_RANK] = {1, 1, 1}; - hsize_t numBlocks[DATA_RANK] = {nDimx, nDimy, nDimz}; - hsize_t blockSize[DATA_RANK] = {1, 1, 1}; - - hsize_t startLocationPara[VDS_PARA_RANK] = {framesSaved, 0}; - hsize_t strideBetweenBlocksPara[VDS_PARA_RANK] = {1, 1}; - hsize_t numBlocksPara[VDS_PARA_RANK] = {nDimx, 1}; - hsize_t blockSizePara[VDS_PARA_RANK] = {1, 1}; - - // interleaving for g2 - if (gotthard25um) { - strideBetweenBlocks[2] = 2; + // property list + H5::DSetCreatPropList plist; + uint64_t fill_value = -1; + plist.setFillValue(dataType, &fill_value); + std::vector plistPara(paraSize); + // ignoring last fill (string) + for (unsigned int i = 0; i != plistPara.size() - 1; ++i) { + plistPara[i].setFillValue(parameterDataTypes[i], &fill_value); } - for (unsigned int iReadout = 0; iReadout < numModY * numModZ; - ++iReadout) { + // hyperslab (files) + int numFiles = numImagesCaught / maxFramesPerFile; + if (numImagesCaught % maxFramesPerFile) + ++numFiles; + uint64_t framesSaved = 0; + for (int iFile = 0; iFile < numFiles; ++iFile) { - // interleaving for g2 (startLocation is 0 and 1) + uint64_t nDimx = + ((numImagesCaught - framesSaved) > maxFramesPerFile) + ? maxFramesPerFile + : (numImagesCaught - framesSaved); + + hsize_t startLocation[DATA_RANK] = {framesSaved, 0, 0}; + hsize_t strideBetweenBlocks[DATA_RANK] = {1, 1, 1}; + hsize_t numBlocks[DATA_RANK] = {nDimx, nDimy, nDimz}; + hsize_t blockSize[DATA_RANK] = {1, 1, 1}; + + hsize_t startLocationPara[VDS_PARA_RANK] = {framesSaved, 0}; + hsize_t strideBetweenBlocksPara[VDS_PARA_RANK] = {1, 1}; + hsize_t numBlocksPara[VDS_PARA_RANK] = {nDimx, 1}; + hsize_t blockSizePara[VDS_PARA_RANK] = {1, 1}; + + // interleaving for g2 if (gotthard25um) { - startLocation[2] = iReadout; + strideBetweenBlocks[2] = 2; } - vdsDataSpace.selectHyperslab(H5S_SELECT_SET, numBlocks, - startLocation, strideBetweenBlocks, - blockSize); + for (unsigned int iReadout = 0; iReadout < numModY * numModZ; + ++iReadout) { - vdsDataSpacePara.selectHyperslab( - H5S_SELECT_SET, numBlocksPara, startLocationPara, - strideBetweenBlocksPara, blockSizePara); - - // source file name - std::ostringstream os; - os << filePath << "/" << fileNamePrefix << "_d" - << (modulePos * numUnitsPerReadout + iReadout) << "_f" - << iFile << '_' << fileIndex << ".h5"; - std::string srcFileName = os.str(); - LOG(logDEBUG1) << srcFileName; - - // find relative path - std::string relative_srcFileName = srcFileName; - { - size_t p = srcFileName.rfind('/', srcFileName.length()); - if (p != std::string::npos) - relative_srcFileName = (srcFileName.substr( - p + 1, srcFileName.length() - p)); - } - - // source dataspace - hsize_t srcDims[DATA_RANK] = {nDimx, nDimy, nDimz}; - hsize_t srcDimsMax[DATA_RANK] = {H5S_UNLIMITED, nDimy, nDimz}; - H5::DataSpace srcDataSpace(DATA_RANK, srcDims, srcDimsMax); - hsize_t srcDimsPara[PARA_RANK] = {nDimx}; - hsize_t srcDimsMaxPara[PARA_RANK] = {H5S_UNLIMITED}; - H5::DataSpace srcDataSpacePara(PARA_RANK, srcDimsPara, - srcDimsMaxPara); - // temporary fixfor corner case bug: - // (framescaught not multiple of framesperfile, - // virtual parameter datasets error loading (bad scalar value)) - if (nDimx != maxFramesPerFile) { - hsize_t count[1] = {nDimx}; - hsize_t start[1] = {0}; - srcDataSpacePara.selectHyperslab( - H5S_SELECT_SET, count, start, strideBetweenBlocksPara, - blockSizePara); - } - - // mapping of property list - plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(), - DATASET_NAME, srcDataSpace); - for (unsigned int p = 0; p < paraSize; ++p) { - plistPara[p].setVirtual( - vdsDataSpacePara, relative_srcFileName.c_str(), - parameterNames[p].c_str(), srcDataSpacePara); - } - - // H5Sclose(srcDataspace); - // H5Sclose(srcDataspace_para); - - if (!gotthard25um) { - startLocation[2] += nDimz; - if (startLocation[2] >= (numModZ * nDimz)) { - startLocation[2] = 0; - startLocation[1] += nDimy; + // interleaving for g2 (startLocation is 0 and 1) + if (gotthard25um) { + startLocation[2] = iReadout; } - } - ++startLocationPara[1]; - } - framesSaved += nDimx; - } - // datasets - H5::DataSet vdsDataSet( - fd->createDataSet(DATASET_NAME, dataType, vdsDataSpace, plist)); - for (unsigned int p = 0; p < paraSize; ++p) { - H5::DataSet vdsDataSetPara(fd->createDataSet( - parameterNames[p].c_str(), parameterDataTypes[p], - vdsDataSpacePara, plistPara[p])); + vdsDataSpace.selectHyperslab( + H5S_SELECT_SET, numBlocks, startLocation, + strideBetweenBlocks, blockSize); + + vdsDataSpacePara.selectHyperslab( + H5S_SELECT_SET, numBlocksPara, startLocationPara, + strideBetweenBlocksPara, blockSizePara); + + // source file name + std::ostringstream os; + os << filePath << "/" << fileNamePrefix << "_d" + << (modulePos * numUnitsPerReadout + iReadout) << "_f" + << iFile << '_' << fileIndex << ".h5"; + std::string srcFileName = os.str(); + LOG(logDEBUG1) << srcFileName; + + // find relative path + std::string relative_srcFileName = srcFileName; + { + size_t p = srcFileName.rfind('/', srcFileName.length()); + if (p != std::string::npos) + relative_srcFileName = (srcFileName.substr( + p + 1, srcFileName.length() - p)); + } + + // source dataspace + hsize_t srcDims[DATA_RANK] = {nDimx, nDimy, nDimz}; + hsize_t srcDimsMax[DATA_RANK] = {H5S_UNLIMITED, nDimy, + nDimz}; + H5::DataSpace srcDataSpace(DATA_RANK, srcDims, srcDimsMax); + hsize_t srcDimsPara[PARA_RANK] = {nDimx}; + hsize_t srcDimsMaxPara[PARA_RANK] = {H5S_UNLIMITED}; + H5::DataSpace srcDataSpacePara(PARA_RANK, srcDimsPara, + srcDimsMaxPara); + // temporary fixfor corner case bug: + // (framescaught not multiple of framesperfile, + // virtual parameter datasets error loading (bad scalar + // value)) + if (nDimx != maxFramesPerFile) { + hsize_t count[1] = {nDimx}; + hsize_t start[1] = {0}; + srcDataSpacePara.selectHyperslab( + H5S_SELECT_SET, count, start, + strideBetweenBlocksPara, blockSizePara); + } + + // mapping of property list + plist.setVirtual(vdsDataSpace, relative_srcFileName.c_str(), + DATASET_NAME, srcDataSpace); + for (unsigned int p = 0; p < paraSize; ++p) { + plistPara[p].setVirtual( + vdsDataSpacePara, relative_srcFileName.c_str(), + parameterNames[p].c_str(), srcDataSpacePara); + } + + // H5Sclose(srcDataspace); + // H5Sclose(srcDataspace_para); + + if (!gotthard25um) { + startLocation[2] += nDimz; + if (startLocation[2] >= (numModZ * nDimz)) { + startLocation[2] = 0; + startLocation[1] += nDimy; + } + } + ++startLocationPara[1]; + } + framesSaved += nDimx; + } + // datasets + H5::DataSet vdsDataSet( + fd->createDataSet(DATASET_NAME, dataType, vdsDataSpace, plist)); + + for (unsigned int p = 0; p < paraSize; ++p) { + H5::DataSet vdsDataSetPara(fd->createDataSet( + parameterNames[p].c_str(), parameterDataTypes[p], + vdsDataSpacePara, plistPara[p])); + } } fd->close(); diff --git a/slsReceiverSoftware/src/MasterFileUtility.h b/slsReceiverSoftware/src/MasterFileUtility.h index ec7494c1d..0cdcb93d3 100644 --- a/slsReceiverSoftware/src/MasterFileUtility.h +++ b/slsReceiverSoftware/src/MasterFileUtility.h @@ -39,7 +39,8 @@ std::string CreateVirtualHDF5File( const uint64_t numImagesCaught, const int numModX, const int numModY, const H5::DataType dataType, const std::vector parameterNames, const std::vector parameterDataTypes, - std::mutex *hdf5LibMutex, bool gotthard25um); + std::mutex *hdf5LibMutex, bool gotthard25um, + std::vector &multiRoi); #endif } // namespace masterFileUtility