diff --git a/slsReceiverSoftware/src/HDF5File.cpp b/slsReceiverSoftware/src/HDF5File.cpp index c27284d1f..eaef047c6 100644 --- a/slsReceiverSoftware/src/HDF5File.cpp +++ b/slsReceiverSoftware/src/HDF5File.cpp @@ -13,151 +13,6 @@ #include //basename #include -std::mutex HDF5File::hdf5Lib; - -HDF5File::HDF5File(int ind, uint32_t *maxf, int *nd, std::string *fname, - std::string *fpath, uint64_t *findex, bool *owenable, - int *dindex, int *nunits, uint64_t *nf, uint32_t *dr, - uint32_t *portno, uint32_t nx, uint32_t ny, bool *smode) - : - - File(ind, HDF5, maxf, nd, fname, fpath, findex, owenable, dindex, nunits, - nf, dr, portno, smode), - masterfd(nullptr), virtualfd(0), filefd(nullptr), dataspace(nullptr), - dataset(nullptr), datatype(PredType::STD_U16LE), nPixelsX(nx), - nPixelsY(ny), numFramesInFile(0), numFilesinAcquisition(0), - dataspace_para(nullptr), extNumImages(0) { - PrintMembers(); - dataset_para.clear(); - parameterNames.clear(); - parameterDataTypes.clear(); - - parameterNames = std::vector{ - "frame number", - "exp length or sub exposure time", - "packets caught", - "bunch id", - "timestamp", - "mod id", - "row", - "column", - "reserved", - "debug", - "round robin number", - "detector type", - "detector header version", - "packets caught bit mask", - }; - StrType strdatatype(PredType::C_S1, sizeof(bitset_storage)); - parameterDataTypes = std::vector{ - PredType::STD_U64LE, PredType::STD_U32LE, PredType::STD_U32LE, - PredType::STD_U64LE, PredType::STD_U64LE, PredType::STD_U16LE, - PredType::STD_U16LE, PredType::STD_U16LE, PredType::STD_U16LE, - PredType::STD_U32LE, PredType::STD_U16LE, PredType::STD_U8LE, - PredType::STD_U8LE, strdatatype}; -} - -HDF5File::~HDF5File() { CloseAllFiles(); } - -void HDF5File::SetNumberofPixels(uint32_t nx, uint32_t ny) { - nPixelsX = nx; - nPixelsY = ny; -} - -void HDF5File::CreateFile() { - numFilesinAcquisition++; - numFramesInFile = 0; - - // first time - if (subFileIndex == 0u) { - switch (*dynamicRange) { - case 16: - datatype = PredType::STD_U16LE; - break; - case 32: - datatype = PredType::STD_U32LE; - break; - default: - datatype = PredType::STD_U8LE; - break; - } - } - CreateDataFile(); -} - -void HDF5File::CloseAllFiles() { - CloseCurrentDataFile(); - CloseMasterFile(); -} - -void HDF5File::CloseMasterFile() { - if (master) { - CloseFile(masterfd, true); - // close virtual file - // c code due to only c implementation of H5Pset_virtual available - if (virtualfd != 0) { - if (H5Fclose(virtualfd) < 0) { - LOG(logERROR) << "Could not close virtual HDF5 handles"; - } - virtualfd = 0; - } - } -} - -void HDF5File::CloseCurrentDataFile() { - CloseFile(filefd, false); - for (unsigned int i = 0; i < dataset_para.size(); ++i) - delete dataset_para[i]; - dataset_para.clear(); - if (dataspace_para) { - delete dataspace_para; - dataspace_para = nullptr; - } - if (dataset) { - delete dataset; - dataset = nullptr; - } - if (dataspace) { - delete dataspace; - dataspace = nullptr; - } -} - -void HDF5File::WriteToFile(char *buffer, int bufferSize, - uint64_t currentFrameNumber, - uint32_t numPacketsCaught) { - - // check if maxframesperfile = 0 for infinite - if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) { - CloseCurrentFile(); - ++subFileIndex; - CreateFile(); - } - numFramesInFile++; - - // extend dataset (when receiver start followed by many status starts - // (jungfrau))) - if (currentFrameNumber >= extNumImages) { - ExtendDataset(); - } - - WriteDataFile(currentFrameNumber, buffer + sizeof(sls_receiver_header)); - WriteParameterDatasets(currentFrameNumber, (sls_receiver_header *)(buffer)); -} - -void HDF5File::CreateMasterFile(MasterAttributes *attr) { - if (master) { - virtualfd = 0; - CreateMasterDataFile(attr); - } -} - -void HDF5File::StartofAcquisition() { - numFilesinAcquisition = 0; - numFramesInFile = 0; - extNumImages = *numImages; -} - void HDF5File::EndofAcquisition(bool anyPacketsCaught, uint64_t numImagesCaught) { // not created before @@ -190,313 +45,6 @@ void HDF5File::EndofAcquisition(bool anyPacketsCaught, numFilesinAcquisition = 0; } -void HDF5File::CloseFile(H5File *&fd, bool masterFile) { - std::lock_guard lock(HDF5File::hdf5Lib); - try { - Exception::dontPrint(); // to handle errors - if (fd) { - fd->close(); - delete fd; - fd = nullptr; - } - } catch (const Exception &error) { - LOG(logERROR) << "Could not close " << (masterFile ? "master" : "data") - << " HDF5 handles of index " << index; - error.printErrorStack(); - } -} - -void HDF5File::WriteDataFile(uint64_t currentFrameNumber, char *buffer) { - std::lock_guard lock(HDF5File::hdf5Lib); - - uint64_t nDimx = - ((*maxFramesPerFile == 0) ? currentFrameNumber - : currentFrameNumber % (*maxFramesPerFile)); - uint32_t nDimy = nPixelsY; - uint32_t nDimz = ((*dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX); - - hsize_t count[3] = {1, nDimy, nDimz}; - hsize_t start[3] = {nDimx, 0, 0}; - hsize_t dims2[2] = {nDimy, nDimz}; - try { - Exception::dontPrint(); // to handle errors - - dataspace->selectHyperslab(H5S_SELECT_SET, count, start); - DataSpace memspace(2, dims2); - dataset->write(buffer, datatype, memspace, *dataspace); - memspace.close(); - } catch (const Exception &error) { - LOG(logERROR) << "Could not write to file in object " << index; - error.printErrorStack(); - throw sls::RuntimeError("Could not write to file in object " + - std::to_string(index)); - } -} - -void HDF5File::WriteParameterDatasets(uint64_t currentFrameNumber, - sls_receiver_header *rheader) { - std::lock_guard lock(HDF5File::hdf5Lib); - - uint64_t fnum = - ((*maxFramesPerFile == 0) ? currentFrameNumber - : currentFrameNumber % (*maxFramesPerFile)); - - sls_detector_header header = rheader->detHeader; - hsize_t count[1] = {1}; - hsize_t start[1] = {fnum}; - int i = 0; - try { - Exception::dontPrint(); // to handle errors - dataspace_para->selectHyperslab(H5S_SELECT_SET, count, start); - DataSpace memspace(H5S_SCALAR); - dataset_para[0]->write(&header.frameNumber, parameterDataTypes[0], - memspace, *dataspace_para); - i = 1; - dataset_para[1]->write(&header.expLength, parameterDataTypes[1], - memspace, *dataspace_para); - i = 2; - dataset_para[2]->write(&header.packetNumber, parameterDataTypes[2], - memspace, *dataspace_para); - i = 3; - dataset_para[3]->write(&header.bunchId, parameterDataTypes[3], memspace, - *dataspace_para); - i = 4; - dataset_para[4]->write(&header.timestamp, parameterDataTypes[4], - memspace, *dataspace_para); - i = 5; - dataset_para[5]->write(&header.modId, parameterDataTypes[5], memspace, - *dataspace_para); - i = 6; - dataset_para[6]->write(&header.row, parameterDataTypes[6], memspace, - *dataspace_para); - i = 7; - dataset_para[7]->write(&header.column, parameterDataTypes[7], memspace, - *dataspace_para); - i = 8; - dataset_para[8]->write(&header.reserved, parameterDataTypes[8], - memspace, *dataspace_para); - i = 9; - dataset_para[9]->write(&header.debug, parameterDataTypes[9], memspace, - *dataspace_para); - i = 10; - dataset_para[10]->write(&header.roundRNumber, parameterDataTypes[10], - memspace, *dataspace_para); - i = 11; - dataset_para[11]->write(&header.detType, parameterDataTypes[11], - memspace, *dataspace_para); - i = 12; - dataset_para[12]->write(&header.version, parameterDataTypes[12], - memspace, *dataspace_para); - i = 13; - - // contiguous bitset - if (sizeof(sls_bitset) == sizeof(bitset_storage)) { - dataset_para[13]->write((char *)&(rheader->packetsMask), - parameterDataTypes[13], memspace, - *dataspace_para); - } - - // not contiguous bitset - else { - // get contiguous representation of bit mask - bitset_storage storage; - memset(storage, 0, sizeof(bitset_storage)); - sls_bitset bits = rheader->packetsMask; - for (int i = 0; i < MAX_NUM_PACKETS; ++i) - storage[i >> 3] |= (bits[i] << (i & 7)); - // write bitmask - dataset_para[13]->write((char *)storage, parameterDataTypes[13], - memspace, *dataspace_para); - } - i = 14; - } catch (const Exception &error) { - error.printErrorStack(); - throw sls::RuntimeError( - "Could not write parameters (index:" + std::to_string(i) + - ") to file in object " + std::to_string(index)); - } -} - -void HDF5File::ExtendDataset() { - std::lock_guard lock(HDF5File::hdf5Lib); - - try { - Exception::dontPrint(); // to handle errors - - hsize_t dims[3]; - dataspace->getSimpleExtentDims(dims); - dims[0] += *numImages; - - dataset->extend(dims); - delete dataspace; - dataspace = nullptr; - dataspace = new DataSpace(dataset->getSpace()); - - hsize_t dims_para[1] = {dims[0]}; - for (unsigned int i = 0; i < dataset_para.size(); ++i) - dataset_para[i]->extend(dims_para); - delete dataspace_para; - dataspace_para = nullptr; - dataspace_para = new DataSpace(dataset_para[0]->getSpace()); - - } catch (const Exception &error) { - error.printErrorStack(); - throw sls::RuntimeError("Could not extend dataset in object " + - std::to_string(index)); - } - if (!(*silentMode)) { - LOG(logINFO) << index << " Extending HDF5 dataset by " << extNumImages - << ", Total x Dimension: " << (extNumImages + *numImages); - } - extNumImages += *numImages; -} - -void HDF5File::CreateDataFile() { - - std::ostringstream os; - os << *filePath << "/" << *fileNamePrefix << "_d" - << (*detIndex * (*numUnitsPerDetector) + index) << "_f" << subFileIndex - << '_' << *fileIndex << ".h5"; - currentFileName = os.str(); - - std::lock_guard lock(HDF5File::hdf5Lib); - - uint64_t framestosave = - ((*maxFramesPerFile == 0) ? *numImages : // infinite images - (((extNumImages - subFileIndex) > (*maxFramesPerFile)) - ? // save up to maximum at a time - (*maxFramesPerFile) - : (extNumImages - subFileIndex))); - - uint64_t nDimx = framestosave; - uint32_t nDimy = nPixelsY; - uint32_t nDimz = ((*dynamicRange == 4) ? (nPixelsX / 2) : nPixelsX); - - try { - Exception::dontPrint(); // to handle errors - - // file - FileAccPropList fapl; - fapl.setFcloseDegree(H5F_CLOSE_STRONG); - filefd = nullptr; - if (!(*overWriteEnable)) - filefd = new H5File(currentFileName.c_str(), H5F_ACC_EXCL, - FileCreatPropList::DEFAULT, fapl); - else - filefd = new H5File(currentFileName.c_str(), H5F_ACC_TRUNC, - FileCreatPropList::DEFAULT, fapl); - - // attributes - version - double dValue = HDF5_WRITER_VERSION; - DataSpace dataspace_attr = DataSpace(H5S_SCALAR); - Attribute attribute = filefd->createAttribute( - "version", PredType::NATIVE_DOUBLE, dataspace_attr); - attribute.write(PredType::NATIVE_DOUBLE, &dValue); - - // dataspace - hsize_t srcdims[3] = {nDimx, nDimy, nDimz}; - hsize_t srcdimsmax[3] = {H5S_UNLIMITED, nDimy, nDimz}; - dataspace = nullptr; - dataspace = new DataSpace(3, srcdims, srcdimsmax); - - // dataset name - std::ostringstream osfn; - osfn << "/data"; - if (*numImages > 1) - osfn << "_f" << std::setfill('0') << std::setw(12) << subFileIndex; - std::string dsetname = osfn.str(); - - // dataset - // fill value - DSetCreatPropList plist; - int fill_value = -1; - plist.setFillValue(datatype, &fill_value); - // always create chunked dataset as unlimited is only - // supported with chunked layout - hsize_t chunk_dims[3] = {MAX_CHUNKED_IMAGES, nDimy, nDimz}; - plist.setChunk(3, chunk_dims); - dataset = nullptr; - dataset = new DataSet(filefd->createDataSet(dsetname.c_str(), datatype, - *dataspace, plist)); - - // create parameter datasets - hsize_t dims[1] = {nDimx}; - hsize_t dimsmax[1] = {H5S_UNLIMITED}; - dataspace_para = nullptr; - dataspace_para = new DataSpace(1, dims, dimsmax); - - // always create chunked dataset as unlimited is only - // supported with chunked layout - DSetCreatPropList paralist; - hsize_t chunkpara_dims[3] = {MAX_CHUNKED_IMAGES}; - paralist.setChunk(1, chunkpara_dims); - - for (unsigned int i = 0; i < parameterNames.size(); ++i) { - DataSet *ds = new DataSet(filefd->createDataSet( - parameterNames[i].c_str(), parameterDataTypes[i], - *dataspace_para, paralist)); - dataset_para.push_back(ds); - } - } catch (const Exception &error) { - error.printErrorStack(); - if (filefd) { - filefd->close(); - } - throw sls::RuntimeError("Could not create HDF5 handles in object " + - index); - } - if (!(*silentMode)) { - LOG(logINFO) << *udpPortNumber - << ": HDF5 File created: " << currentFileName; - } -} - -void HDF5File::CreateMasterDataFile(MasterAttributes *attr) { - - std::ostringstream os; - os << *filePath << "/" << *fileNamePrefix << "_master" - << "_" << *fileIndex << ".h5"; - masterFileName = os.str(); - - if (!(*silentMode)) { - LOG(logINFO) << "Master File: " << masterFileName; - } - - std::lock_guard lock(HDF5File::hdf5Lib); - - try { - Exception::dontPrint(); // to handle errors - - FileAccPropList flist; - flist.setFcloseDegree(H5F_CLOSE_STRONG); - masterfd = nullptr; - if (!(*overWriteEnable)) - masterfd = new H5File(masterFileName.c_str(), H5F_ACC_EXCL, - FileCreatPropList::DEFAULT, flist); - else - masterfd = new H5File(masterFileName.c_str(), H5F_ACC_TRUNC, - FileCreatPropList::DEFAULT, flist); - - // Create a group in the file - Group group1(masterfd->createGroup("entry")); - Group group2(group1.createGroup("data")); - Group group3(group1.createGroup("instrument")); - Group group4(group3.createGroup("beam")); - Group group5(group3.createGroup("detector")); - Group group6(group1.createGroup("sample")); - - attr->WriteMasterHDF5Attributes(masterfd, &group5); - masterfd->close(); - - } catch (const Exception &error) { - error.printErrorStack(); - if (masterfd) { - masterfd->close(); - } - throw sls::RuntimeError("Could not create master HDF5 handles"); - } -} - void HDF5File::CreateVirtualDataFile(uint32_t maxFramesPerFile, uint64_t numf) { std::ostringstream osfn;