mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-24 07:20:01 +02:00
328 lines
9.3 KiB
C++
328 lines
9.3 KiB
C++
/************************************************
|
|
* @file HDF5File.cpp
|
|
* @short sets/gets properties for the HDF5 file,
|
|
* creates/closes the file and writes data to it
|
|
***********************************************/
|
|
#include "HDF5File.h"
|
|
#include "receiver_defs.h"
|
|
#include "Fifo.h"
|
|
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <libgen.h> //basename
|
|
#include <string.h>
|
|
|
|
|
|
pthread_mutex_t HDF5File::Mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
H5File* HDF5File::masterfd = 0;
|
|
hid_t HDF5File::virtualfd = 0;
|
|
|
|
|
|
|
|
HDF5File::HDF5File(int ind, uint32_t* maxf,
|
|
int* nd, char* fname, char* 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, maxf, nd, fname, fpath, findex, owenable, dindex, nunits, nf, dr, portno, smode),
|
|
filefd(0),
|
|
dataspace(0),
|
|
dataset(0),
|
|
datatype(PredType::STD_U16LE),
|
|
nPixelsX(nx),
|
|
nPixelsY(ny),
|
|
numFramesInFile(0),
|
|
numActualPacketsInFile(0),
|
|
numFilesinAcquisition(0),
|
|
dataspace_para(0),
|
|
extNumImages(0)
|
|
{
|
|
PrintMembers();
|
|
dataset_para.clear();
|
|
parameterNames.clear();
|
|
parameterDataTypes.clear();
|
|
|
|
parameterNames.push_back("frame number");
|
|
parameterDataTypes.push_back(PredType::STD_U64LE);
|
|
|
|
parameterNames.push_back("exp length or sub exposure time");
|
|
parameterDataTypes.push_back(PredType::STD_U32LE);
|
|
|
|
parameterNames.push_back("packets caught");
|
|
parameterDataTypes.push_back(PredType::STD_U32LE);
|
|
|
|
parameterNames.push_back("bunch id");
|
|
parameterDataTypes.push_back(PredType::STD_U64LE);
|
|
|
|
parameterNames.push_back("timestamp");
|
|
parameterDataTypes.push_back(PredType::STD_U64LE);
|
|
|
|
parameterNames.push_back("mod id");
|
|
parameterDataTypes.push_back(PredType::STD_U16LE);
|
|
|
|
parameterNames.push_back("row");
|
|
parameterDataTypes.push_back(PredType::STD_U16LE);
|
|
|
|
parameterNames.push_back("column");
|
|
parameterDataTypes.push_back(PredType::STD_U16LE);
|
|
|
|
parameterNames.push_back("reserved");
|
|
parameterDataTypes.push_back(PredType::STD_U16LE);
|
|
|
|
parameterNames.push_back("debug");
|
|
parameterDataTypes.push_back(PredType::STD_U32LE);
|
|
|
|
parameterNames.push_back("round robin number");
|
|
parameterDataTypes.push_back(PredType::STD_U16LE);
|
|
|
|
parameterNames.push_back("detector type");
|
|
parameterDataTypes.push_back(PredType::STD_U8LE);
|
|
|
|
parameterNames.push_back("detector header version");
|
|
parameterDataTypes.push_back(PredType::STD_U8LE);
|
|
|
|
parameterNames.push_back("packets caught bit mask");
|
|
StrType strdatatype(PredType::C_S1, sizeof(bitset_storage));
|
|
parameterDataTypes.push_back(strdatatype);
|
|
|
|
}
|
|
|
|
|
|
HDF5File::~HDF5File() {
|
|
CloseAllFiles();
|
|
}
|
|
|
|
void HDF5File::PrintMembers(TLogLevel level) {
|
|
File::PrintMembers();
|
|
UpdateDataType();
|
|
if (datatype == PredType::STD_U8LE) {
|
|
FILE_LOG(level) << "Data Type: 4 or 8";
|
|
} else if (datatype == PredType::STD_U16LE) {
|
|
FILE_LOG(level) << "Data Type: 16";
|
|
} else if (datatype == PredType::STD_U32LE) {
|
|
FILE_LOG(level) << "Data Type: 32";
|
|
} else {
|
|
FILE_LOG(logERROR) << "unknown data type";
|
|
}
|
|
}
|
|
|
|
|
|
void HDF5File::SetNumberofPixels(uint32_t nx, uint32_t ny) {
|
|
nPixelsX = nx;
|
|
nPixelsY = ny;
|
|
}
|
|
|
|
|
|
slsDetectorDefs::fileFormat HDF5File::GetFileType() {
|
|
return HDF5;
|
|
}
|
|
|
|
|
|
void HDF5File::UpdateDataType() {
|
|
switch(*dynamicRange){
|
|
case 16: datatype = PredType::STD_U16LE; break;
|
|
case 32: datatype = PredType::STD_U32LE; break;
|
|
default: datatype = PredType::STD_U8LE; break;
|
|
}
|
|
}
|
|
|
|
|
|
int HDF5File::CreateFile(uint64_t fnum) {
|
|
numFilesinAcquisition++;
|
|
numFramesInFile = 0;
|
|
numActualPacketsInFile = 0;
|
|
currentFileName = HDF5FileStatic::CreateFileName(filePath, fileNamePrefix, *fileIndex,
|
|
(*numImages > 1), fnum, *detIndex, *numUnitsPerDetector, index);
|
|
|
|
//first time
|
|
if(!fnum) UpdateDataType();
|
|
|
|
uint64_t framestosave = ((*maxFramesPerFile == 0) ? *numImages : // infinite images
|
|
(((extNumImages - fnum) > (*maxFramesPerFile)) ? // save up to maximum at a time
|
|
(*maxFramesPerFile) : (extNumImages-fnum)));
|
|
pthread_mutex_lock(&Mutex);
|
|
if (HDF5FileStatic::CreateDataFile(index, *overWriteEnable, currentFileName, (*numImages > 1),
|
|
fnum, framestosave, nPixelsY, ((*dynamicRange==4) ? (nPixelsX/2) : nPixelsX),
|
|
datatype, filefd, dataspace, dataset,
|
|
HDF5_WRITER_VERSION, MAX_CHUNKED_IMAGES,
|
|
dataspace_para, dataset_para,
|
|
parameterNames, parameterDataTypes) == FAIL) {
|
|
pthread_mutex_unlock(&Mutex);
|
|
return FAIL;
|
|
}
|
|
pthread_mutex_unlock(&Mutex);
|
|
|
|
if(!(*silentMode)) {
|
|
FILE_LOG(logINFO) << *udpPortNumber << ": HDF5 File created: " << currentFileName;
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
|
|
void HDF5File::CloseCurrentFile() {
|
|
pthread_mutex_lock(&Mutex);
|
|
HDF5FileStatic::CloseDataFile(index, filefd);
|
|
pthread_mutex_unlock(&Mutex);
|
|
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=0;}
|
|
if(dataset) {delete dataset;dataset=0;}
|
|
if(dataspace) {delete dataspace;dataspace=0;}
|
|
if(filefd) {delete filefd;filefd=0;}
|
|
}
|
|
|
|
|
|
void HDF5File::CloseAllFiles() {
|
|
numFilesinAcquisition = 0;
|
|
pthread_mutex_lock(&Mutex);
|
|
HDF5FileStatic::CloseDataFile(index, filefd);
|
|
if (master && (*detIndex==0)) {
|
|
HDF5FileStatic::CloseMasterDataFile(masterfd);
|
|
HDF5FileStatic::CloseVirtualDataFile(virtualfd);
|
|
}
|
|
pthread_mutex_unlock(&Mutex);
|
|
|
|
for (unsigned int i = 0; i < dataset_para.size(); ++i)
|
|
delete dataset_para[i];
|
|
dataset_para.clear();
|
|
if(dataspace_para) delete dataspace_para;
|
|
if(dataset) delete dataset;
|
|
if(dataspace) delete dataspace;
|
|
if(filefd) delete filefd;
|
|
}
|
|
|
|
|
|
int HDF5File::WriteToFile(char* buffer, int buffersize, uint64_t fnum, uint32_t nump) {
|
|
|
|
// check if maxframesperfile = 0 for infinite
|
|
if ((*maxFramesPerFile) && (numFramesInFile >= (*maxFramesPerFile))) {
|
|
CloseCurrentFile();
|
|
CreateFile(fnum);
|
|
}
|
|
numFramesInFile++;
|
|
numActualPacketsInFile += nump;
|
|
pthread_mutex_lock(&Mutex);
|
|
|
|
// extend dataset (when receiver start followed by many status starts (jungfrau)))
|
|
if (fnum >= extNumImages) {
|
|
if (HDF5FileStatic::ExtendDataset(index, dataspace, dataset,
|
|
dataspace_para, dataset_para, *numImages) == OK) {
|
|
if (!(*silentMode)) {
|
|
FILE_LOG(logINFO) << index << " Extending HDF5 dataset by " <<
|
|
extNumImages << ", Total x Dimension: " << (extNumImages + *numImages);
|
|
}
|
|
extNumImages += *numImages;
|
|
}
|
|
}
|
|
|
|
if (HDF5FileStatic::WriteDataFile(index, buffer + sizeof(sls_receiver_header),
|
|
// infinite then no need for %maxframesperfile
|
|
((*maxFramesPerFile == 0) ? fnum : fnum%(*maxFramesPerFile)),
|
|
nPixelsY, ((*dynamicRange==4) ? (nPixelsX/2) : nPixelsX),
|
|
dataspace, dataset, datatype) == OK) {
|
|
|
|
if (HDF5FileStatic::WriteParameterDatasets(index, dataspace_para,
|
|
// infinite then no need for %maxframesperfile
|
|
((*maxFramesPerFile == 0) ? fnum : fnum%(*maxFramesPerFile)),
|
|
dataset_para, (sls_receiver_header*) (buffer),
|
|
parameterDataTypes) == OK) {
|
|
pthread_mutex_unlock(&Mutex);
|
|
return OK;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&Mutex);
|
|
FILE_LOG(logERROR) << index << "Write to file failed";
|
|
return FAIL;
|
|
}
|
|
|
|
|
|
int HDF5File::CreateMasterFile(bool en, uint32_t size,
|
|
uint32_t nx, uint32_t ny, uint64_t at, uint64_t st, uint64_t sp,
|
|
uint64_t ap) {
|
|
|
|
//beginning of every acquisition
|
|
numFramesInFile = 0;
|
|
numActualPacketsInFile = 0;
|
|
extNumImages = *numImages;
|
|
|
|
if (master && (*detIndex==0)) {
|
|
virtualfd = 0;
|
|
masterFileName = HDF5FileStatic::CreateMasterFileName(filePath,
|
|
fileNamePrefix, *fileIndex);
|
|
if(!(*silentMode)) {
|
|
FILE_LOG(logINFO) << "Master File: " << masterFileName;
|
|
}
|
|
pthread_mutex_lock(&Mutex);
|
|
int ret = HDF5FileStatic::CreateMasterDataFile(masterfd, masterFileName,
|
|
*overWriteEnable,
|
|
*dynamicRange, en, size, nx, ny, *numImages, *maxFramesPerFile,
|
|
at, st, sp, ap,
|
|
HDF5_WRITER_VERSION);
|
|
pthread_mutex_unlock(&Mutex);
|
|
return ret;
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
|
|
void HDF5File::EndofAcquisition(bool anyPacketsCaught, uint64_t numf) {
|
|
//not created before
|
|
if (!virtualfd && anyPacketsCaught) {
|
|
|
|
// called only by the one maser receiver
|
|
if (master && (*detIndex==0)) {
|
|
|
|
//only one file and one sub image (link current file in master)
|
|
if (((numFilesinAcquisition == 1) && (numDetY*numDetX) == 1)) {
|
|
LinkVirtualFileinMasterFile();
|
|
}
|
|
//create virutal file
|
|
else{
|
|
CreateVirtualFile(numf);}
|
|
}
|
|
}
|
|
numFilesinAcquisition = 0;
|
|
}
|
|
|
|
|
|
// called only by the one maser receiver
|
|
int HDF5File::CreateVirtualFile(uint64_t numf) {
|
|
pthread_mutex_lock(&Mutex);
|
|
|
|
std::string vname = HDF5FileStatic::CreateVirtualFileName(filePath, fileNamePrefix, *fileIndex);
|
|
if(!(*silentMode)) {
|
|
FILE_LOG(logINFO) << "Virtual File: " << vname;
|
|
}
|
|
|
|
int ret = HDF5FileStatic::CreateVirtualDataFile(vname,
|
|
virtualfd, masterFileName,
|
|
filePath, fileNamePrefix, *fileIndex, (*numImages > 1),
|
|
*detIndex, *numUnitsPerDetector,
|
|
// infinite images in 1 file, then maxfrperfile = numf
|
|
((*maxFramesPerFile == 0) ? numf+1 : *maxFramesPerFile),
|
|
numf+1,
|
|
"data", datatype,
|
|
numDetY, numDetX, nPixelsY, ((*dynamicRange==4) ? (nPixelsX/2) : nPixelsX),
|
|
HDF5_WRITER_VERSION,
|
|
parameterNames, parameterDataTypes);
|
|
pthread_mutex_unlock(&Mutex);
|
|
return ret;
|
|
}
|
|
|
|
// called only by the one maser receiver
|
|
int HDF5File::LinkVirtualFileinMasterFile() {
|
|
//dataset name
|
|
std::ostringstream osfn;
|
|
osfn << "/data";
|
|
if ((*numImages > 1)) osfn << "_f" << std::setfill('0') << std::setw(12) << 0;
|
|
std::string dsetname = osfn.str();
|
|
|
|
pthread_mutex_lock(&Mutex);
|
|
int ret = HDF5FileStatic::LinkVirtualInMaster(masterFileName, currentFileName,
|
|
dsetname, parameterNames);
|
|
pthread_mutex_unlock(&Mutex);
|
|
return ret;
|
|
}
|