feat(opatIO): opat fileformat addedd
This commit is contained in:
18
src/opatIO/meson.build
Normal file
18
src/opatIO/meson.build
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Define the library
|
||||||
|
opatIO_sources = files(
|
||||||
|
'private/opatIO.cpp',
|
||||||
|
)
|
||||||
|
|
||||||
|
opatIO_headers = files(
|
||||||
|
'public/opatIO.h'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Define the libopatIO library so it can be linked against by other parts of the build system
|
||||||
|
libopatIO = library('opatIO',
|
||||||
|
opatIO_sources,
|
||||||
|
include_directories: include_directories('public'),
|
||||||
|
cpp_args: ['-fvisibility=default'],
|
||||||
|
install : true)
|
||||||
|
|
||||||
|
# Make headers accessible
|
||||||
|
install_headers(opatIO_headers, subdir : '4DSSE/opatIO')
|
||||||
313
src/opatIO/private/opatIO.cpp
Normal file
313
src/opatIO/private/opatIO.cpp
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
#include "opatIO.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstring>
|
||||||
|
#include <algorithm>
|
||||||
|
#include<cstring>
|
||||||
|
#include<iomanip>
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
OpatIO::OpatIO() {}
|
||||||
|
|
||||||
|
OpatIO::OpatIO(std::string filename) : filename(filename) {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
OpatIO::~OpatIO() {
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the OPAT file
|
||||||
|
void OpatIO::load() {
|
||||||
|
if (loaded) return;
|
||||||
|
|
||||||
|
std::ifstream file(filename, std::ios::binary);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
throw std::runtime_error("Could not open file: " + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
readHeader(file);
|
||||||
|
readTableIndex(file);
|
||||||
|
|
||||||
|
loaded = true;
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Unload the OPAT file
|
||||||
|
void OpatIO::unload() {
|
||||||
|
if (!loaded) return;
|
||||||
|
|
||||||
|
tableIndex.clear();
|
||||||
|
while (!tableQueue.empty()) {
|
||||||
|
tableQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the header from the file
|
||||||
|
void OpatIO::readHeader(std::ifstream &file) {
|
||||||
|
file.read(reinterpret_cast<char*>(&header), sizeof(Header));
|
||||||
|
if (file.gcount() != sizeof(Header)) {
|
||||||
|
throw std::runtime_error("Error reading header from file: " + filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the table index from the file
|
||||||
|
void OpatIO::readTableIndex(std::ifstream &file) {
|
||||||
|
file.seekg(header.indexOffset, std::ios::beg);
|
||||||
|
tableIndex.resize(header.numTables);
|
||||||
|
file.read(reinterpret_cast<char*>(tableIndex.data()), header.numTables * sizeof(TableIndex));
|
||||||
|
if (file.gcount() != static_cast<std::streamsize>(header.numTables * sizeof(TableIndex))) {
|
||||||
|
throw std::runtime_error("Error reading table index from file: " + filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Check if a table is in the queue
|
||||||
|
// bool OpatIO::isTableInQueue(double X, double Z) {
|
||||||
|
// for (const auto &table : tableQueue) {
|
||||||
|
// if (table.X == X && table.Z == Z) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get a table from the queue
|
||||||
|
// OPATTable OpatIO::getTableFromQueue(double X, double Z) {
|
||||||
|
// std::queue<OPATTable> tempQueue;
|
||||||
|
// OPATTable result;
|
||||||
|
|
||||||
|
// while (!tableQueue.empty()) {
|
||||||
|
// OPATTable table = tableQueue.front();
|
||||||
|
// tableQueue.pop();
|
||||||
|
// if (table.X == X && table.Z == Z) {
|
||||||
|
// result = table;
|
||||||
|
// }
|
||||||
|
// tempQueue.push(table);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// tableQueue = tempQueue;
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Add a table to the queue
|
||||||
|
// void OpatIO::addTableToQueue(OPATTable table) {
|
||||||
|
// if (tableQueue.size() >= maxQueueDepth) {
|
||||||
|
// removeTableFromQueue();
|
||||||
|
// }
|
||||||
|
// tableQueue.push(table);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Remove a table from the queue
|
||||||
|
// void OpatIO::removeTableFromQueue() {
|
||||||
|
// if (!tableQueue.empty()) {
|
||||||
|
// tableQueue.pop();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Flush the queue
|
||||||
|
// void OpatIO::flushQueue() {
|
||||||
|
// while (!tableQueue.empty()) {
|
||||||
|
// tableQueue.pop();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get the OPAT version
|
||||||
|
// uint16_t OpatIO::getOPATVersion() {
|
||||||
|
// return header.version;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get the table ID for given X and Z
|
||||||
|
// uint16_t OpatIO::getTableID(double X, double Z) {
|
||||||
|
// for (const auto &index : tableIndex) {
|
||||||
|
// if (index.X == X && index.Z == Z) {
|
||||||
|
// return index.tableID;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// throw std::runtime_error("Table ID not found for given X and Z");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get the byte start for a given table ID
|
||||||
|
// uint64_t OpatIO::getTableByteStart(uint16_t tableID) {
|
||||||
|
// for (const auto &index : tableIndex) {
|
||||||
|
// if (index.tableID == tableID) {
|
||||||
|
// return index.byteStart;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// throw std::runtime_error("Byte start not found for given table ID");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get the byte end for a given table ID
|
||||||
|
// uint64_t OpatIO::getTableByteEnd(uint16_t tableID) {
|
||||||
|
// for (const auto &index : tableIndex) {
|
||||||
|
// if (index.tableID == tableID) {
|
||||||
|
// return index.byteEnd;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// throw std::runtime_error("Byte end not found for given table ID");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get a table for given X and Z
|
||||||
|
// OPATTable OpatIO::getTable(double X, double Z) {
|
||||||
|
// if (isTableInQueue(X, Z)) {
|
||||||
|
// return getTableFromQueue(X, Z);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// uint16_t tableID = getTableID(X, Z);
|
||||||
|
// return getTable(tableID);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get a table for given table ID
|
||||||
|
// OPATTable OpatIO::getTable(uint16_t tableID) {
|
||||||
|
// std::ifstream file(filename, std::ios::binary);
|
||||||
|
// if (!file.is_open()) {
|
||||||
|
// throw std::runtime_error("Could not open file: " + filename);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// uint64_t byteStart = getTableByteStart(tableID);
|
||||||
|
// uint64_t byteEnd = getTableByteEnd(tableID);
|
||||||
|
// uint64_t tableSize = byteEnd - byteStart;
|
||||||
|
|
||||||
|
// file.seekg(byteStart, std::ios::beg);
|
||||||
|
// OPATTable table;
|
||||||
|
// file.read(reinterpret_cast<char*>(&table), tableSize);
|
||||||
|
// if (file.gcount() != tableSize) {
|
||||||
|
// throw std::runtime_error("Error reading table from file: " + filename);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// addTableToQueue(table);
|
||||||
|
// file.close();
|
||||||
|
// return table;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Set the maximum queue depth
|
||||||
|
void OpatIO::setMaxQDepth(int depth) {
|
||||||
|
maxQDepth = depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OpatIO::getMaxQDepth() {
|
||||||
|
return maxQDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the filename
|
||||||
|
void OpatIO::setFilename(std::string filename) {
|
||||||
|
if (loaded) {
|
||||||
|
throw std::runtime_error("Cannot set filename while file is loaded");
|
||||||
|
}
|
||||||
|
this->filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the file is loaded
|
||||||
|
bool OpatIO::isLoaded() {
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the header
|
||||||
|
void OpatIO::printHeader() {
|
||||||
|
std::cout << "Version: " << header.version << std::endl;
|
||||||
|
std::cout << "Number of Tables: " << header.numTables << std::endl;
|
||||||
|
std::cout << "Header Size: " << header.headerSize << std::endl;
|
||||||
|
std::cout << "Index Offset: " << header.indexOffset << std::endl;
|
||||||
|
std::cout << "Creation Date: " << header.creationDate << std::endl;
|
||||||
|
std::cout << "Source Info: " << header.sourceInfo << std::endl;
|
||||||
|
std::cout << "Comment: " << header.comment << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the table index
|
||||||
|
void OpatIO::printTableIndex() {
|
||||||
|
if (tableIndex.empty()) {
|
||||||
|
std::cout << "No table indexes found." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print table header
|
||||||
|
std::cout << std::left << std::setw(10) << "X"
|
||||||
|
<< std::setw(10) << "Z"
|
||||||
|
<< std::setw(15) << "Byte Start"
|
||||||
|
<< std::setw(15) << "Byte End"
|
||||||
|
<< "Checksum (SHA-256)" << std::endl;
|
||||||
|
|
||||||
|
std::cout << std::string(80, '=') << std::endl; // Separator line
|
||||||
|
|
||||||
|
// Print each entry in the table
|
||||||
|
for (const auto &index : tableIndex) {
|
||||||
|
std::cout << std::fixed << std::setprecision(4)
|
||||||
|
<< std::setw(10) << index.X
|
||||||
|
<< std::setw(10) << index.Z
|
||||||
|
<< std::setw(15) << index.byteStart
|
||||||
|
<< std::setw(15) << index.byteEnd
|
||||||
|
<< std::hex; // Switch to hex mode for checksum
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; ++i) { // Print first 8 bytes of SHA-256 for brevity
|
||||||
|
std::cout << std::setw(2) << std::setfill('0') << (int)index.sha256[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "..." << std::dec << std::setfill(' ') << std::endl; // Reset formatting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// // Print a table
|
||||||
|
// void OpatIO::printTable(OPATTable table) {
|
||||||
|
// std::cout << "Table ID: " << table.tableID << std::endl;
|
||||||
|
// std::cout << "N_R: " << table.N_R << std::endl;
|
||||||
|
// std::cout << "N_T: " << table.N_T << std::endl;
|
||||||
|
// std::cout << "LogR: ";
|
||||||
|
// for (uint32_t i = 0; i < table.N_R; ++i) {
|
||||||
|
// std::cout << table.logR[i] << " ";
|
||||||
|
// }
|
||||||
|
// std::cout << std::endl;
|
||||||
|
// std::cout << "LogT: ";
|
||||||
|
// for (uint32_t i = 0; i < table.N_T; ++i) {
|
||||||
|
// std::cout << table.logT[i] << " ";
|
||||||
|
// }
|
||||||
|
// std::cout << std::endl;
|
||||||
|
// std::cout << "LogKappa: ";
|
||||||
|
// for (uint32_t i = 0; i < table.N_R * table.N_T; ++i) {
|
||||||
|
// std::cout << table.logKappa[i] << " ";
|
||||||
|
// }
|
||||||
|
// std::cout << std::endl;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get all tables
|
||||||
|
// std::vector<OPATTable> OpatIO::getTables() {
|
||||||
|
// std::vector<OPATTable> tables;
|
||||||
|
// for (const auto &index : tableIndex) {
|
||||||
|
// tables.push_back(getTable(index.tableID));
|
||||||
|
// }
|
||||||
|
// return tables;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Get the table index
|
||||||
|
std::vector<TableIndex> OpatIO::getTableIndex() {
|
||||||
|
return tableIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the header
|
||||||
|
Header OpatIO::getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Get the closest X tables
|
||||||
|
// std::vector<OPATTable> OpatIO::getClosestXTables(double X, double ZExact, int numTables) {
|
||||||
|
// std::vector<OPATTable> closestTables;
|
||||||
|
// // Implement logic to find closest X tables
|
||||||
|
// return closestTables;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get the closest Z tables
|
||||||
|
// std::vector<OPATTable> OpatIO::getClosestZTables(double XExact, double Z, int numTables) {
|
||||||
|
// std::vector<OPATTable> closestTables;
|
||||||
|
// // Implement logic to find closest Z tables
|
||||||
|
// return closestTables;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Get the closest tables
|
||||||
|
// std::vector<OPATTable> OpatIO::getClosestTables(double X, double Z, int numTables) {
|
||||||
|
// std::vector<OPATTable> closestTables;
|
||||||
|
// // Implement logic to find closest tables
|
||||||
|
// return closestTables;
|
||||||
|
// }
|
||||||
93
src/opatIO/public/opatIO.h
Normal file
93
src/opatIO/public/opatIO.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#ifndef OPATIO_H
|
||||||
|
#define OPATIO_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
struct Header {
|
||||||
|
char magic[4];
|
||||||
|
uint16_t version;
|
||||||
|
uint32_t numTables;
|
||||||
|
uint32_t headerSize;
|
||||||
|
uint64_t indexOffset;
|
||||||
|
char creationDate[16];
|
||||||
|
char sourceInfo[64];
|
||||||
|
char comment[128];
|
||||||
|
char reserved[26];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TableIndex {
|
||||||
|
double X;
|
||||||
|
double Z;
|
||||||
|
// double C; // For type 2 OPAL tables. When not set will be 0
|
||||||
|
// double O; // For type 2 OPAL tables. When not set will be 0
|
||||||
|
uint64_t byteStart;
|
||||||
|
uint64_t byteEnd;
|
||||||
|
char sha256[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OPATTable {
|
||||||
|
uint32_t N_R;
|
||||||
|
uint32_t N_T;
|
||||||
|
std::vector<double> logR;
|
||||||
|
std::vector<double> logT;
|
||||||
|
std::vector<std::vector<double>> logKappa;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpatIO {
|
||||||
|
private:
|
||||||
|
Header header;
|
||||||
|
std::vector<TableIndex> tableIndex;
|
||||||
|
std::queue<OPATTable> tableQueue;
|
||||||
|
int maxQDepth = 10;
|
||||||
|
std::string filename;
|
||||||
|
bool loaded = false;
|
||||||
|
|
||||||
|
void readHeader(std::ifstream &file);
|
||||||
|
void readTableIndex(std::ifstream &file);
|
||||||
|
|
||||||
|
bool isTableInQueue(double X, double Z);
|
||||||
|
OPATTable getTableFromQueue(double X, double Z);
|
||||||
|
void addTableToQueue(OPATTable table);
|
||||||
|
void removeTableFromQueue();
|
||||||
|
|
||||||
|
void flushQueue();
|
||||||
|
|
||||||
|
uint16_t getOPATVersion();
|
||||||
|
|
||||||
|
uint16_t getTableID(double X, double Z);
|
||||||
|
uint64_t getTableByteStart(uint16_t tableID);
|
||||||
|
uint64_t getTableByteEnd(uint16_t tableID);
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpatIO();
|
||||||
|
OpatIO(std::string filename);
|
||||||
|
~OpatIO();
|
||||||
|
|
||||||
|
OPATTable getTable(double X, double, double C=0, double O=0);
|
||||||
|
OPATTable getTable(uint16_t tableID);
|
||||||
|
void setMaxQDepth(int depth);
|
||||||
|
int getMaxQDepth();
|
||||||
|
void setFilename(std::string filename);
|
||||||
|
void load();
|
||||||
|
void unload();
|
||||||
|
bool isLoaded();
|
||||||
|
|
||||||
|
void printHeader();
|
||||||
|
void printTableIndex();
|
||||||
|
void printTable(OPATTable table);
|
||||||
|
|
||||||
|
std::vector<OPATTable> getTables();
|
||||||
|
std::vector<TableIndex> getTableIndex();
|
||||||
|
Header getHeader();
|
||||||
|
|
||||||
|
std::vector<OPATTable> getClosestXTables(double X, double ZExact, double C=0, double O=0, int numTables=1);
|
||||||
|
std::vector<OPATTable> getClosestZTables(double XExact, double Z, double C=0, double O=0, int numTables=1);
|
||||||
|
std::vector<OPATTable> getClosestTables(double X, double Z, double C=0, double O=0, int numTables=1);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user