2020-05-20 10:14:57 +02:00

258 lines
10 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"
"Exptime1 (ns) : %lld\n"
"Exptime2 (ns) : %lld\n"
"Exptime3 (ns) : %lld\n"
"GateDelay1 (ns) : %lld\n"
"GateDelay2 (ns) : %lld\n"
"GateDelay3 (ns) : %lld\n"
"Gates : %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,
(long long int)masterFileAttributes.exptime1Ns,
(long long int)masterFileAttributes.exptime2Ns,
(long long int)masterFileAttributes.exptime3Ns,
(long long int)masterFileAttributes.gateDelay1Ns,
(long long int)masterFileAttributes.gateDelay2Ns,
(long long int)masterFileAttributes.gateDelay3Ns,
masterFileAttributes.gates, 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;
}
}