2020-05-05 10:04:52 +02:00

245 lines
9.3 KiB
C++

/************************************************
* @file BinaryFile.cpp
* @short sets/gets properties for the binary file,
* creates/closes the file and writes data to it
***********************************************/
#include "BinaryFile.h"
#include "Fifo.h"
#include "receiver_defs.h"
#include <iomanip>
#include <iostream>
#include <string.h>
FILE *BinaryFile::masterfd = nullptr;
BinaryFile::BinaryFile(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, bool *smode)
: File(ind, BINARY, maxf, nd, fname, fpath, findex, owenable, dindex,
nunits, nf, dr, portno, smode),
filefd(nullptr), numFramesInFile(0), numActualPacketsInFile(0),
maxMasterFileSize(2000) {
#ifdef VERBOSE
PrintMembers();
#endif
}
BinaryFile::~BinaryFile() { CloseAllFiles(); }
void BinaryFile::PrintMembers(TLogLevel level) {
File::PrintMembers(level);
LOG(logINFO) << "Max Frames Per File: " << *maxFramesPerFile;
LOG(logINFO) << "Number of Frames in File: " << numFramesInFile;
}
void BinaryFile::CreateFile() {
numFramesInFile = 0;
numActualPacketsInFile = 0;
std::ostringstream os;
os << *filePath << "/" << *fileNamePrefix << "_d"
<< (*detIndex * (*numUnitsPerDetector) + index) << "_f" << subFileIndex
<< '_' << *fileIndex << ".raw";
currentFileName = os.str();
if (!(*overWriteEnable)) {
if (NULL ==
(filefd = fopen((const char *)currentFileName.c_str(), "wx"))) {
filefd = 0;
throw sls::RuntimeError("Could not create/overwrite file " +
currentFileName);
}
} else if (NULL ==
(filefd = fopen((const char *)currentFileName.c_str(), "w"))) {
filefd = 0;
throw sls::RuntimeError("Could not create file " + currentFileName);
}
// setting to no file buffering
setvbuf(filefd, NULL, _IONBF, 0);
if (!(*silentMode)) {
LOG(logINFO) << "[" << *udpPortNumber
<< "]: Binary File created: " << currentFileName;
}
}
void BinaryFile::CloseCurrentFile() {
if (filefd)
fclose(filefd);
filefd = 0;
}
void BinaryFile::CloseAllFiles() {
CloseCurrentFile();
if (master) {
if (masterfd)
fclose(masterfd);
masterfd = 0;
}
}
int BinaryFile::WriteData(char *buf, int bsize) {
if (!filefd)
return 0;
return fwrite(buf, 1, bsize, filefd);
}
void BinaryFile::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++;
numActualPacketsInFile += numPacketsCaught;
// write to file
int ret = 0;
// contiguous bitset
if (sizeof(sls_bitset) == sizeof(bitset_storage)) {
ret = WriteData(buffer, buffersize);
}
// not contiguous bitset
else {
// write detector header
ret = WriteData(buffer, sizeof(sls_detector_header));
// get contiguous representation of bit mask
bitset_storage storage;
memset(storage, 0, sizeof(bitset_storage));
sls_bitset bits = *(sls_bitset *)(buffer + sizeof(sls_detector_header));
for (int i = 0; i < MAX_NUM_PACKETS; ++i)
storage[i >> 3] |= (bits[i] << (i & 7));
// write bitmask
ret += WriteData((char *)storage, sizeof(bitset_storage));
// write data
ret += WriteData(buffer + sizeof(sls_detector_header),
buffersize - sizeof(sls_receiver_header));
}
// if write error
if (ret != buffersize) {
throw sls::RuntimeError(std::to_string(index) +
" : Write to file failed for image number " +
std::to_string(currentFrameNumber));
}
}
void BinaryFile::CreateMasterFile(bool masterFileWriteEnable,
masterAttributes &masterFileAttributes) {
// beginning of every acquisition
numFramesInFile = 0;
numActualPacketsInFile = 0;
if (masterFileWriteEnable && master) {
std::ostringstream os;
os << *filePath << "/" << *fileNamePrefix << "_master"
<< "_" << *fileIndex << ".raw";
masterFileName = os.str();
if (!(*silentMode)) {
LOG(logINFO) << "Master File: " << masterFileName;
}
masterFileAttributes.version = BINARY_WRITER_VERSION;
// create master file
if (!(*overWriteEnable)) {
if (NULL == (masterfd = fopen((const char *)masterFileName.c_str(),
"wx"))) {
masterfd = 0;
throw sls::RuntimeError("Could not create binary master file "
"(without overwrite enable) " +
masterFileName);
}
} else if (NULL == (masterfd = fopen(
(const char *)masterFileName.c_str(), "w"))) {
masterfd = 0;
throw sls::RuntimeError("Could not create binary master file "
"(with overwrite enable) " +
masterFileName);
}
// create master file data
time_t t = time(0);
char message[maxMasterFileSize];
sprintf(message,
"Version : %.1f\n"
"Detector Type : %d\n"
"Dynamic Range : %d\n"
"Ten Giga : %d\n"
"Image Size : %d bytes\n"
"nPixelsX : %d pixels\n"
"nPixelsY : %d pixels\n"
"Max Frames Per File : %u\n"
"Total Frames : %lld\n"
"Exptime (ns) : %lld\n"
"SubExptime (ns) : %lld\n"
"SubPeriod(ns) : %lld\n"
"Period (ns) : %lld\n"
"Quad Enable : %d\n"
"Analog Flag : %d\n"
"Digital Flag : %d\n"
"ADC Mask : %d\n"
"Dbit Offset : %d\n"
"Dbit Bitset : %lld\n"
"Roi (xmin, xmax) : %d %d\n"
"Timestamp : %s\n\n"
"#Frame Header\n"
"Frame Number : 8 bytes\n"
"SubFrame Number/ExpLength : 4 bytes\n"
"Packet Number : 4 bytes\n"
"Bunch ID : 8 bytes\n"
"Timestamp : 8 bytes\n"
"Module Id : 2 bytes\n"
"Row : 2 bytes\n"
"Column : 2 bytes\n"
"Reserved : 2 bytes\n"
"Debug : 4 bytes\n"
"Round Robin Number : 2 bytes\n"
"Detector Type : 1 byte\n"
"Header Version : 1 byte\n"
"Packets Caught Mask : 64 bytes\n",
masterFileAttributes.version, masterFileAttributes.detectorType,
masterFileAttributes.dynamicRange, masterFileAttributes.tenGiga,
masterFileAttributes.imageSize, masterFileAttributes.nPixelsX,
masterFileAttributes.nPixelsY,
masterFileAttributes.maxFramesPerFile,
(long long int)masterFileAttributes.totalFrames,
(long long int)masterFileAttributes.exptimeNs,
(long long int)masterFileAttributes.subExptimeNs,
(long long int)masterFileAttributes.subPeriodNs,
(long long int)masterFileAttributes.periodNs,
masterFileAttributes.quadEnable,
masterFileAttributes.analogFlag,
masterFileAttributes.digitalFlag, masterFileAttributes.adcmask,
masterFileAttributes.dbitoffset,
(long long int)masterFileAttributes.dbitlist,
masterFileAttributes.roiXmin, masterFileAttributes.roiXmax,
ctime(&t));
if (strlen(message) > maxMasterFileSize) {
throw sls::RuntimeError("Master File Size " +
std::to_string(strlen(message)) +
" is greater than max str size " +
std::to_string(maxMasterFileSize));
}
// write and close file
if (fwrite((void *)message, 1, strlen(message), masterfd) !=
strlen(message)) {
throw sls::RuntimeError(
"Master binary file incorrect number of bytes written to file");
}
if (masterfd)
fclose(masterfd);
masterfd = 0;
}
}