build(GridFire): added project structure
This commit is contained in:
88
.gitignore
vendored
Normal file
88
.gitignore
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
*.env
|
||||||
|
*.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
ENV.bak/
|
||||||
|
*.egg-info/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# C and C++ (using Meson)
|
||||||
|
build/
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.d
|
||||||
|
*.dSYM/
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.obj
|
||||||
|
*.dll
|
||||||
|
*.lib
|
||||||
|
*.pdb
|
||||||
|
*.exp
|
||||||
|
*.log
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Fortran
|
||||||
|
*.mod
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Doxygen
|
||||||
|
html/
|
||||||
|
latex/
|
||||||
|
xml/
|
||||||
|
man/
|
||||||
|
rtf/
|
||||||
|
tags
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
*.swp
|
||||||
|
*._DS_Store
|
||||||
|
*.DS_Store
|
||||||
|
*.bak
|
||||||
|
*.tmp
|
||||||
|
*.log
|
||||||
|
*.cache
|
||||||
|
*.private
|
||||||
|
*.private/
|
||||||
|
|
||||||
|
subprojects/mfem/
|
||||||
|
subprojects/tetgen/
|
||||||
|
subprojects/yaml-cpp/
|
||||||
|
subprojects/quill/
|
||||||
|
subprojects/googletest-*/
|
||||||
|
subprojects/opat-core/
|
||||||
|
subprojects/pybind11*/
|
||||||
|
subprojects/packagecache/
|
||||||
|
subprojects/hypre/
|
||||||
|
subprojects/qhull/
|
||||||
|
subprojects/cppad/
|
||||||
|
|
||||||
|
qhull.wrap
|
||||||
|
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
*.log
|
||||||
|
mpi-install-log.txt
|
||||||
|
|
||||||
|
output/
|
||||||
|
|
||||||
|
.boost_installed
|
||||||
|
4DSSE_logs/
|
||||||
|
.last_build_flags
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
scratch/
|
||||||
437
README.md
Normal file
437
README.md
Normal file
@@ -0,0 +1,437 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img src="assets/logo/opatCoreLogo.png" width="300" alt="OPAT Core Libraries Logo">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1 align="center">OPAT Core Libraries</h1>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://pypi.org/project/opatio/"><img src="https://img.shields.io/pypi/v/opatio" alt="PyPI - Version"></a>
|
||||||
|
<a href="https://github.com/4D-STAR/opat-core/blob/main/LICENSE"><img src="https://img.shields.io/github/license/4D-STAR/opat-core" alt="GitHub License"></a>
|
||||||
|
<a href="https://4d-star.github.io/opat-core/"><img src="https://img.shields.io/badge/Documentation-View%20Here-blue" alt="Documentation"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This repository contains the core C++ library, python module, and file specification for the OPAT file format.
|
||||||
|
|
||||||
|
OPAT is a structured binary file format developed by the 4D-STAR collaboration for efficient and standardized storage of set of tabular data indexed by some floating point vector (such as composition).
|
||||||
|
|
||||||
|
The general principle behind OPAT is that an arbitrary number of data cards are stored, indexed by some arbitrary-length composition vector. Each data card contains an arbitrary number of data tables indexed by some string tag.
|
||||||
|
|
||||||
|
The provided python module can be used to create and read OPAT files while the C++ module is intended to be used to interface OPAT tables with C++ code for reading (but not currently generation).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
This repository provides both C++ and python bindings. The first thing to note is that these do not depend on each other at all. If you want to generate OPAT tables and/or use them in python code you will want the python module. If you want to use OPAT tables in C++ code you will want the C++ module.
|
||||||
|
|
||||||
|
There are more details on usage for each language in their respective folder; however, broad installation instructions are included here as well.
|
||||||
|
|
||||||
|
### Dependencies Overview
|
||||||
|
|
||||||
|
Below is a summary of the key dependencies for each part of the project.
|
||||||
|
|
||||||
|
#### Python Dependencies
|
||||||
|
These are managed by `pip` and are listed in `opatIO-py/pyproject.toml`.
|
||||||
|
|
||||||
|
| Dependency | Minimum Version | Usage | Source/Authors |
|
||||||
|
|-------------|-----------------|----------------------------------------|--------------------------------------------------------------------------------|
|
||||||
|
| `numpy` | `>= 1.21.1` | Numerical operations, array handling | [NumPy Developers](https://numpy.org/) |
|
||||||
|
| `xxhash` | `>= 3.5.0` | Fast hashing algorithms (internal use) | [Yann Collet (Cyan4973)](https://github.com/Cyan4973/xxHash) |
|
||||||
|
| `scipy` | `>= 1.15.0` | Triangulation (for interpolation) | [SciPy Developers](https://scipy.org/) |
|
||||||
|
|
||||||
|
#### C++ Dependencies
|
||||||
|
Most C++ dependencies are handled via Meson's wrap system (built at compile time). Boost is an exception.
|
||||||
|
|
||||||
|
| Dependency | Installation | Usage | Source/Authors |
|
||||||
|
|------------|--------------------------------------------------|-----------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| Boost | System install or via bundled script (prompts user) | Numerical linear algebra (`ublas`) in `TableLattice` | [Boost Community](https://www.boost.org/) |
|
||||||
|
| Qhull | Meson wrap (built automatically) | N-dimensional Delaunay triangulation for `TableLattice` | [Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull algorithm for convex hulls," ACM Trans. on Mathematical Software, 22(4):469-483, Dec 1996](http://www.qhull.org/) |
|
||||||
|
| xxHash | Meson wrap (built automatically) | Fast hashing for `FloatIndexVector` lookups in `OPAT` class | [Yann Collet (Cyan4973)](https://github.com/Cyan4973/xxHash) & [Stefan Brumme (stbrumme)](https://create.stephan-brumme.com/xxhash/)
|
||||||
|
| PicoSHA2 | Meson wrap (built automatically) | SHA-256 hashing for data integrity checks (`CardCatalogEntry`) | [Shintarou Okada (okdshin)](https://github.com/okdshin/PicoSHA2)
|
||||||
|
| cxxopts | Meson wrap (built automatically) | Command-line option parsing for CLI tools (e.g., `opatHeader`) | [Jarryd Beck (jarro2783)](https://github.com/jarro2783/cxxopts)
|
||||||
|
|
||||||
|
### Python Installation
|
||||||
|
```bash
|
||||||
|
pip install opatio
|
||||||
|
```
|
||||||
|
|
||||||
|
### C++ Installation
|
||||||
|
You will need `meson`, `cmake`, and `ninja` installed pre-installed. Note that cmake is needed in order to build subprojects which use CMake as their build system. *opat-core does not make use of CMake as a build system*. These can be installed with pip
|
||||||
|
```bash
|
||||||
|
pip install "meson>=1.6.0"
|
||||||
|
pip install cmake
|
||||||
|
pip install ninja
|
||||||
|
```
|
||||||
|
Then you can build and install opat-core
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/4D-STAR/opat-core
|
||||||
|
cd opat-core
|
||||||
|
meson setup build --buildtype=release
|
||||||
|
meson compile -C build
|
||||||
|
```
|
||||||
|
If you want to run tests you can use meson's build in test command. Note that due to small numerical differences between computers and compilers, some tests may fail. This is expected and can be ignored. Specifically, `TableLattice` tests rely on the ordering / adjacency of Delaunay triangulation which can vary between systems.
|
||||||
|
```bash
|
||||||
|
meson test -C build
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
To install headers, libraries, the pkg_config file (`opatIO.pc`), and the command line utilities
|
||||||
|
```bash
|
||||||
|
meson install -C build
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
## Python Usage
|
||||||
|
See the `opatIO-py` directory for detailed installation and usage instructions. The Python module allows for both creating and reading OPAT files. A comprehensive API manual can also be found in `opatIO-py/docs/build/latex/opatio.pdf`.
|
||||||
|
|
||||||
|
The general workflow involves creating an `OPAT` object, adding tables to it, and then saving it.
|
||||||
|
|
||||||
|
### Creating and Writing an OPAT File
|
||||||
|
```python
|
||||||
|
from opatio import OPAT
|
||||||
|
|
||||||
|
# Initialize an OPAT object
|
||||||
|
opacityFile = OPAT()
|
||||||
|
opacityFile.set_comment("This is a sample opacity file")
|
||||||
|
opacityFile.set_source("OPLIB") # Optional: set a source identifier
|
||||||
|
|
||||||
|
# Assume you have your data:
|
||||||
|
# X, Z: components of the index vector (e.g., Hydrogen and Metal mass fractions)
|
||||||
|
# logR: 1D array of log(R) values (e.g., density variable)
|
||||||
|
# logT: 1D array of log(T) values (e.g., temperature variable)
|
||||||
|
# logKappa: 2D array of log(opacity) values, with shape (len(logR), len(logT))
|
||||||
|
X, Z = 0.7, 0.02
|
||||||
|
logR = [1.0, 2.0, 3.0]
|
||||||
|
logT = [4.0, 5.0, 6.0, 7.0]
|
||||||
|
logKappa = [[1.1, 1.2, 1.3, 1.4], [2.1, 2.2, 2.3, 2.4], [3.1, 3.2, 3.3, 3.4]]
|
||||||
|
|
||||||
|
|
||||||
|
# Add a table to a new DataCard, indexed by (X, Z)
|
||||||
|
# The tag "data" identifies this specific table within the DataCard
|
||||||
|
card = opacityFile.add_table(index_vector=(X, Z),
|
||||||
|
tag="data",
|
||||||
|
row_values=logR,
|
||||||
|
col_values=logT,
|
||||||
|
table_data=logKappa,
|
||||||
|
rowName="logR",
|
||||||
|
columnName="logT")
|
||||||
|
|
||||||
|
# You can add another table to the same DataCard
|
||||||
|
# For example, interpolation coefficients
|
||||||
|
# xOrder, yOrder, coeff = ... (your coefficient data)
|
||||||
|
# opacityFile.add_table(index_vector=(X,Z), tag="interp_coeffs",
|
||||||
|
# row_values=x_coeffs_indices, col_values=y_coeffs_indices, table_data=coeffs,
|
||||||
|
# card=card) # Pass the existing card object
|
||||||
|
|
||||||
|
# Save the OPAT file
|
||||||
|
opacityFile.save("opacity.opat")
|
||||||
|
|
||||||
|
# Optionally, save an ASCII representation (for debugging or human-readable inspection)
|
||||||
|
opacityFile.save_as_ascii("opacity_ascii.txt")
|
||||||
|
|
||||||
|
print("OPAT file created and saved.")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reading an OPAT File
|
||||||
|
```python
|
||||||
|
from opatio import read_opat
|
||||||
|
|
||||||
|
# Load an existing OPAT file
|
||||||
|
opacityFile = read_opat("opacity.opat")
|
||||||
|
|
||||||
|
# Print the header information
|
||||||
|
print(opacityFile.header)
|
||||||
|
|
||||||
|
# Access a specific DataCard by its index vector
|
||||||
|
# Note: Index vectors are tuples. For floating point comparisons,
|
||||||
|
# direct dictionary-like access might require exact matches.
|
||||||
|
# It's often better to iterate or use methods that handle floating point precision if needed.
|
||||||
|
# For this example, we assume the index (0.7, 0.02) exists.
|
||||||
|
target_index = (0.7, 0.02)
|
||||||
|
if target_index in opacityFile.cards:
|
||||||
|
data_card = opacityFile.cards[target_index]
|
||||||
|
|
||||||
|
# Access a specific table within the DataCard by its tag
|
||||||
|
if "data" in data_card.tables:
|
||||||
|
table = data_card.tables["data"]
|
||||||
|
print(f"\nTable 'data' for index {target_index}:")
|
||||||
|
print(f"Row Names (logR): {table.row_values}")
|
||||||
|
print(f"Column Names (logT): {table.col_values}")
|
||||||
|
print(f"Table Data (logKappa):\n{table.table_data}")
|
||||||
|
else:
|
||||||
|
print(f"Table 'data' not found in card with index {target_index}")
|
||||||
|
else:
|
||||||
|
print(f"DataCard with index {target_index} not found.")
|
||||||
|
|
||||||
|
# Iterate through all cards and their tables
|
||||||
|
for index_vec, card in opacityFile.cards.items():
|
||||||
|
print(f"\nDataCard at index: {index_vec}")
|
||||||
|
for tag, table in card.tables.items():
|
||||||
|
print(f" Table tag: {tag}, Shape: ({table.num_rows}, {table.num_cols})")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Converting OPAL Type I to OPAT
|
||||||
|
A utility is provided to convert common OPAL Type I opacity files to the OPAT format.
|
||||||
|
```python
|
||||||
|
from opatio.convert import OPALI_2_OPAT
|
||||||
|
|
||||||
|
# Assuming an OPAL Type I file named "GS98hz" is in the current directory
|
||||||
|
OPALI_2_OPAT("GS98hz", "gs98hz.opat")
|
||||||
|
print("Converted OPAL Type I file to gs98hz.opat")
|
||||||
|
```
|
||||||
|
|
||||||
|
## C++ Library/Header Usage
|
||||||
|
The C++ library is primarily designed for reading and interpolating data from OPAT files. Below are some common usage examples. For a more detailed API manual, refer to the Doxygen documentation generated in `opatIO-cpp/docs/html/index.html` (or the PDF version in `opatIO-cpp/docs/latex/refman.pdf`).
|
||||||
|
|
||||||
|
### Linking the C++ Library
|
||||||
|
|
||||||
|
The installation process detailed above generate a package config file `opatIO.pc` that can be used to link against the
|
||||||
|
C++ library. You can use this in your `CMakeLists.txt`, `meson.build` files, or directly in your compiler commands.
|
||||||
|
|
||||||
|
as a simple example lets say you make a file called `main.cpp` with the following contents:
|
||||||
|
```c++
|
||||||
|
#include <opatIO.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
opat::OPAT opat_file = opat::readOPAT("example.opat");
|
||||||
|
std::cout << "Successfully read OPAT file: example.opat" << std::endl;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
if you were to just run
|
||||||
|
```bash
|
||||||
|
g++ main.cpp -o main
|
||||||
|
```
|
||||||
|
This would fail because the compiler neither knows where to find the `opatIO.h` header file nor the `libopatio.a` library.
|
||||||
|
|
||||||
|
However, if you use the `pkg-config` tool, you can easily compile and link against the OPAT library:
|
||||||
|
```bash
|
||||||
|
g++ main.cpp -o main $(pkg-config --cflags --libs opatIO) --std=c++23
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ The `--std=c++23` flag is required as the OPAT C++ library makes use of C++23 features. --std=c++17 is the minimum required version, but C++23 is recommended for full compatibility.
|
||||||
|
>
|
||||||
|
|
||||||
|
### C++ API Usage Examples
|
||||||
|
|
||||||
|
#### Accessing a Table by Index and Tag
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include "opatIO.h"
|
||||||
|
#include "indexVector.h" // For FloatIndexVector
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::string filename = "example.opat";
|
||||||
|
try {
|
||||||
|
opat::OPAT opat_file = opat::readOPAT(filename);
|
||||||
|
// Define the index vector for the DataCard you want to access
|
||||||
|
FloatIndexVector target_index({0.35, 0.004}); // Example index
|
||||||
|
// Define the tag for the table within the DataCard
|
||||||
|
std::string table_tag = "data"; // Example tag
|
||||||
|
|
||||||
|
const opat::DataCard& data_card = opat_file[target_index];
|
||||||
|
const opat::OPATTable& table = data_card[table_tag];
|
||||||
|
|
||||||
|
std::cout << "Table '" << table_tag << "' at index " << target_index << ":" << std::endl;
|
||||||
|
table.print(); // Print the table data
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Error accessing table: " << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Slicing a Table
|
||||||
|
```c++
|
||||||
|
#include "opatIO.h"
|
||||||
|
#include "indexVector.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::string filename = "example.opat";
|
||||||
|
try {
|
||||||
|
opat::OPAT opat_file = opat::readOPAT(filename);
|
||||||
|
FloatIndexVector target_index({0.35, 0.004});
|
||||||
|
std::string table_tag = "data";
|
||||||
|
|
||||||
|
// Define slices for rows and columns
|
||||||
|
opat::Slice row_slice(0, 6); // Rows 0 through 5
|
||||||
|
opat::Slice col_slice(25, 36); // Columns 25 through 35
|
||||||
|
|
||||||
|
const opat::OPATTable& original_table = opat_file[target_index][table_tag];
|
||||||
|
opat::OPATTable sliced_table = original_table.slice(row_slice, col_slice);
|
||||||
|
|
||||||
|
std::cout << "Sliced table '" << table_tag << "' at index " << target_index << ":" << std::endl;
|
||||||
|
sliced_table.print(); // Print the sliced table
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Error slicing table: " << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Using `TableLattice` for Interpolation
|
||||||
|
The `TableLattice` class allows for N-dimensional linear interpolation of data within an OPAT file.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include "opatIO.h"
|
||||||
|
#include "indexVector.h"
|
||||||
|
#include "tableLattice.h" // For TableLattice
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::string opat_filename = "your_data.opat"; // Replace with your OPAT file
|
||||||
|
try {
|
||||||
|
opat::OPAT opat_data = opat::readOPAT(opat_filename);
|
||||||
|
|
||||||
|
// Initialize TableLattice with the loaded OPAT data
|
||||||
|
opat::lattice::TableLattice lattice(opat_data);
|
||||||
|
std::cout << "TableLattice initialized." << std::endl;
|
||||||
|
|
||||||
|
// Define the index vector for which you want to interpolate data
|
||||||
|
// Ensure its dimension matches opat_data.header.numIndex
|
||||||
|
FloatIndexVector query_point({0.54, 0.07}); // Example for a 2D OPAT
|
||||||
|
|
||||||
|
// Get the interpolated DataCard
|
||||||
|
opat::DataCard interpolated_card = lattice.get(query_point);
|
||||||
|
std::cout << "Interpolated DataCard retrieved for " << query_point << std::endl;
|
||||||
|
|
||||||
|
// Access tables from the interpolated_card as needed
|
||||||
|
// For example, if your OPAT files contain a table tagged "density":
|
||||||
|
// if (!interpolated_card.getKeys().empty()) {
|
||||||
|
// const opat::OPATTable& density_table = interpolated_card[interpolated_card.getKeys()[0]];
|
||||||
|
// density_table.print();
|
||||||
|
// }
|
||||||
|
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "An error occurred: " << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Command Line Utility Usage
|
||||||
|
After running `meson install -C build`, three command-line utilities will be available in your system's path (you might need to resource your shell, e.g., `source ~/.bashrc` or `source ~/.zshrc`, or open a new terminal). These utilities are:
|
||||||
|
|
||||||
|
1. **`opatHeader`**: Prints out the main header information of an OPAT file.
|
||||||
|
```bash
|
||||||
|
opatHeader --file path/to/your/file.opat
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **`opatInspect`**: Prints the main header and the card catalog (index of all data cards) of an OPAT file.
|
||||||
|
```bash
|
||||||
|
opatInspect --file path/to/your/file.opat
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **`opatVerify`**: Verifies if the provided file is a valid OPAT file according to the specification. It checks the magic number and performs other integrity checks.
|
||||||
|
```bash
|
||||||
|
opatVerify --file path/to/your/file.opat
|
||||||
|
```
|
||||||
|
|
||||||
|
Note the `--file` (or `-f`) flag is required before providing the path to the OPAT file for all tools.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fortran Usage
|
||||||
|
A Fortran wrapper around the C++ `opatIO` module is provided. This interface allows Fortran applications to read data from OPAT files. Note that this is primarily for reading and may not receive the same level of feature development as the C++ and Python interfaces.
|
||||||
|
|
||||||
|
The Fortran module and object files are typically built into `build/opatIO-fortran/libopatio_f.a` (and associated `.mod` files in `build/opatIO-fortran/libopatio_f.a.p`). You will need to link against this library and potentially the C++ `opatIO` library as well.
|
||||||
|
|
||||||
|
Refer to `opatIO-fortran/readme.md` and `opatIO-cpp/docs/static/fortran.md` for more details.
|
||||||
|
|
||||||
|
### Example: Reading an OPAT File in Fortran
|
||||||
|
|
||||||
|
The core workflow involves:
|
||||||
|
1. Loading the OPAT file using `load_opat_file`.
|
||||||
|
2. Retrieving a specific table using `get_opat_table`.
|
||||||
|
3. Checking the returned table structure for errors.
|
||||||
|
4. Accessing table data.
|
||||||
|
5. Freeing resources with `free_opat_file`.
|
||||||
|
|
||||||
|
```fortran
|
||||||
|
program opat_fortran_example
|
||||||
|
use opat_interface_module
|
||||||
|
use, intrinsic :: iso_c_binding
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=256) :: filename
|
||||||
|
real(c_double), target :: index_vec(2) ! Assuming 2D index vector
|
||||||
|
character(len=32) :: tag ! Ensure tag length matches definition in module
|
||||||
|
type(opat_table_f_type) :: my_table
|
||||||
|
integer :: load_status
|
||||||
|
integer :: i, j
|
||||||
|
|
||||||
|
! --- Configuration ---
|
||||||
|
filename = 'gs98hz.opat' ! Ensure this file exists where the program is run
|
||||||
|
! A copy can be found in opatIO-cpp/examples
|
||||||
|
index_vec(1) = 0.9_c_double ! Example X value
|
||||||
|
index_vec(2) = 0.08_c_double ! Example Z value
|
||||||
|
tag = 'data' ! Tag of the table to retrieve
|
||||||
|
|
||||||
|
! --- Load OPAT File ---
|
||||||
|
print *, "Attempting to load OPAT file: ", trim(filename)
|
||||||
|
load_status = load_opat_file(trim(filename))
|
||||||
|
if (load_status /= 0) then
|
||||||
|
print *, "ERROR: Failed to load OPAT file. Status: ", load_status
|
||||||
|
stop 1
|
||||||
|
end if
|
||||||
|
print *, "OPAT file loaded successfully."
|
||||||
|
|
||||||
|
! --- Get Table ---
|
||||||
|
print *, "Attempting to retrieve table with tag '", trim(tag), "' for index [", index_vec(1), ",", index_vec(2), "]"
|
||||||
|
call get_opat_table(index_vec, trim(tag), my_table)
|
||||||
|
|
||||||
|
! --- Check for Errors and Process Table ---
|
||||||
|
if (my_table%error_code /= 0) then
|
||||||
|
print *, "ERROR: Failed to retrieve table. Error code: ", my_table%error_code
|
||||||
|
if (my_table%error_code == 1) print *, " (Likely cause: Index vector not found)"
|
||||||
|
if (my_table%error_code == 2) print *, " (Likely cause: Table tag not found for given index)"
|
||||||
|
else
|
||||||
|
print *, "Table retrieved successfully!"
|
||||||
|
print *, "Table dimensions: ", my_table%num_rows, "rows, ", my_table%num_cols, "cols"
|
||||||
|
|
||||||
|
! Check if pointers are associated (important!)
|
||||||
|
if (.not. c_associated(my_table%row_values)) then
|
||||||
|
print *, "ERROR: Row values pointer not associated."
|
||||||
|
else if (.not. c_associated(my_table%col_values)) then
|
||||||
|
print *, "ERROR: Column values pointer not associated."
|
||||||
|
else if (.not. c_associated(my_table%data)) then
|
||||||
|
print *, "ERROR: Table data pointer not associated."
|
||||||
|
else
|
||||||
|
! Access and print some data (example)
|
||||||
|
print *, "First row value: ", my_table%row_values(1)
|
||||||
|
print *, "First col value: ", my_table%col_values(1)
|
||||||
|
print *, "Data at (1,1): ", my_table%data(1,1)
|
||||||
|
|
||||||
|
! Example: Print a small part of the table
|
||||||
|
! print *, "Sample data:"
|
||||||
|
! do i = 1, min(my_table%num_rows, 3)
|
||||||
|
! write(*,'(3(F8.3,X))') (my_table%data(i,j), j = 1, min(my_table%num_cols,3))
|
||||||
|
! end do
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
|
||||||
|
! --- Free OPAT File Resources ---
|
||||||
|
print *, "Freeing OPAT file resources."
|
||||||
|
call free_opat_file()
|
||||||
|
print *, "Program finished."
|
||||||
|
|
||||||
|
end program opat_fortran_example
|
||||||
|
```
|
||||||
|
**Important Notes for Fortran Usage:**
|
||||||
|
- Ensure the OPAT file (e.g., `gs98hz.opat`) is accessible in the directory where the Fortran executable is run.
|
||||||
|
- Always check `my_table%error_code` after calling `get_opat_table`.
|
||||||
|
- Crucially, call `free_opat_file()` when you are done with the OPAT file to prevent memory leaks.
|
||||||
|
- The dimensions of `index_vec` must match the `numIndex` defined in the OPAT file's header.
|
||||||
|
- The length of the `tag` character variable should be sufficient for the tags used in your OPAT files.
|
||||||
BIN
assets/logo/GridFire.png
Normal file
BIN
assets/logo/GridFire.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 223 KiB |
98
assets/logo/GridFire.svg
Normal file
98
assets/logo/GridFire.svg
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="300mm"
|
||||||
|
height="200mm"
|
||||||
|
viewBox="0 0 300 200"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4 (e7c3feb1, 2024-10-09)"
|
||||||
|
sodipodi:docname="GridFire.svg"
|
||||||
|
inkscape:export-filename="GridFire.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:zoom="0.41489711"
|
||||||
|
inkscape:cx="861.65942"
|
||||||
|
inkscape:cy="506.14959"
|
||||||
|
inkscape:window-width="1728"
|
||||||
|
inkscape:window-height="969"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="38"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showguides="false" />
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:35.2777px;font-family:Federation;-inkscape-font-specification:'Federation Medium';text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;stroke:#000000;stroke-width:0.165"
|
||||||
|
x="126.09238"
|
||||||
|
y="247.10724"
|
||||||
|
id="text1"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan1"
|
||||||
|
style="stroke-width:0.165"
|
||||||
|
x="126.09238"
|
||||||
|
y="247.10724" /></text>
|
||||||
|
<path
|
||||||
|
d="m 83.725847,65.260425 5.92665,-13.22913 H 46.366798 l -2.43416,0.42334 c -0.74083,0.21166 -1.58749,0.63499 -2.53999,1.26999 -1.48166,1.16417 -2.75166,2.96333 -3.80999,5.39749 l -2.64582,6.13831 z M 19.802718,115.00194 h 33.972389 c 2.75166,0 5.07999,-0.74083 7.09081,-2.11666 2.2225,-1.79916 3.59832,-3.49249 4.33916,-5.29166 l 14.18162,-32.279065 h -23.60076 l -5.92665,13.22913 h 4.12749 l 1.16416,0.84666 c 0.42333,0.74084 0.635,1.37583 0.635,1.79917 l -0.42333,1.58749 -1.79916,3.70416 -1.05833,1.48166 -1.16417,1.26999 c -0.84666,0.635 -1.79916,0.952495 -2.85749,0.952495 h -7.090809 c -1.16416,0 -2.11666,-0.211665 -2.96332,-0.740825 -0.635,-0.74083 -0.9525,-1.48166 -0.9525,-2.01083 l 0.42333,-1.79916 8.99581,-20.2141 h -16.50995 l -12.80579,28.998235 c -1.05833,2.53999 -1.5875,4.65666 -1.5875,6.34999 0,2.85749 1.27,4.23332 3.80999,4.23332 z m 50.693999,0 h 16.50995 l 11.64163,-26.352425 h 8.784133 c 1.27,0 1.90499,0.74083 1.90499,2.2225 l -0.42333,1.79916 -0.42333,1.69333 -9.101633,20.637435 h 16.298283 l 9.94831,-22.542435 c 0.3175,-0.635 0.42333,-1.37583 0.42333,-2.11666 0,-1.69333 -0.635,-3.06916 -1.79916,-4.23332 -1.16417,-1.05833 -2.32833,-1.58749 -3.38666,-1.58749 2.85749,0 5.29165,-0.635 7.30248,-1.79917 2.01083,-1.58749 3.38665,-3.28082 4.23332,-5.29165 l 7.61997,-17.25077 c 0.3175,-0.52917 0.42334,-1.16417 0.42334,-1.905 0,-1.58749 -0.74083,-3.06916 -2.11666,-4.33915 -1.69333,-1.27 -3.06916,-1.905 -4.02166,-1.905 H 98.330797 Z M 112.93576,75.420395 h -8.57249 l 4.65666,-10.15997 h 7.72581 c 2.32833,0 3.49249,0.74083 3.49249,2.11666 l -0.3175,1.05833 -2.32832,5.29165 c -0.635,0.74083 -1.27,1.16416 -2.01083,1.37583 z m 10.90079,39.581545 H 139.902 L 160.01,70.022905 h -15.85351 z m 53.4456,-62.970645 -27.93991,62.970645 h 39.58154 c 3.28083,0 6.13832,-0.84666 8.36081,-2.43416 2.22249,-1.58749 3.80999,-3.59832 4.86832,-6.03249 l 20.2141,-45.825685 c 0.635,-1.90499 0.9525,-3.28082 0.9525,-4.23332 0,-2.96332 -1.27,-4.44499 -3.80999,-4.44499 z m 10.5833,13.22913 h 6.13832 c 5.18582,0 7.83164,1.16416 7.83164,3.49249 0,0.74083 -0.21167,1.58749 -0.635,2.53999 l -10.2658,23.28326 c -0.9525,2.11666 -1.90499,3.59832 -2.85749,4.33915 -0.9525,0.84667 -2.32833,1.269995 -4.12749,1.269995 h -11.53579 z"
|
||||||
|
id="text2"
|
||||||
|
style="font-weight:500;font-size:105.833px;font-family:Federation;-inkscape-font-specification:'Federation Medium';fill:#577bb7;stroke:#577bb7;stroke-width:0.165"
|
||||||
|
aria-label="Grid"
|
||||||
|
sodipodi:nodetypes="ccccccccssccccccccccccssccccccsscccsccccccscccccscscccccsccccccccccccssccssccsscccscc" />
|
||||||
|
<g
|
||||||
|
id="text3"
|
||||||
|
transform="translate(-111.65638,-152.86187)">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-weight:500;font-size:105.833px;font-family:Federation;-inkscape-font-specification:'Federation Medium';text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#567989;fill-opacity:1;stroke:#577b24;stroke-width:0.165;stroke-opacity:1"
|
||||||
|
x="205.80164"
|
||||||
|
y="334.35223"
|
||||||
|
id="text4"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan2"
|
||||||
|
style="fill:#567989;fill-opacity:1;stroke-width:0.165"
|
||||||
|
x="205.80164"
|
||||||
|
y="334.35223">FIRE</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
style="fill:#bd4700;fill-opacity:1;stroke:none;stroke-width:0.0770683"
|
||||||
|
d="m 141.91916,58.575645 c -1.87461,-9.4366 7.21572,-7.38641 14.33434,-33.5308 1.16711,-4.28649 2.69828,-13.061139 2.69828,-13.061139 3.84631,17.927789 -4.41963,36.563269 4.96316,37.240939 3.24439,0.23433 3.02126,-9.74929 3.02126,-9.74929 4.59141,4.03462 5.73365,9.57887 4.9471,14.75162 -0.55258,3.63402 -3.48315,6.74343 -6.39407,8.83063 -3.8879,2.78771 -6.92313,4.89273 -13.56517,4.05555 -5.91117,-0.7451 -9.12635,-4.11499 -10.0049,-8.53751 z"
|
||||||
|
id="path3"
|
||||||
|
sodipodi:nodetypes="aacacaasa" />
|
||||||
|
<path
|
||||||
|
style="fill:#ec7c00;fill-opacity:1;stroke:none;stroke-width:0.0575509"
|
||||||
|
d="m 143.85228,58.868835 c -0.75196,-5.96384 6.44008,-10.11284 8.92038,-15.57762 1.41841,-3.12512 2.45402,-6.43583 3.36889,-9.75366 0.87267,-3.16479 2.01148,-9.64487 2.01148,-9.64487 2.18039,7.63566 -4.587,25.99435 4.25023,28.17098 3.28029,0.80795 5.75069,-2.48662 6.04745,-8.57874 0.26249,0.2119 1.37311,6.9481 0.58871,10.29927 -0.77789,3.32336 -2.51801,6.64199 -5.04199,8.83288 -3.2352,2.80822 -6.79985,5.17467 -11.81458,4.54336 -4.46292,-0.56189 -7.82729,-4.29992 -8.33057,-8.2916 z"
|
||||||
|
id="path3-8"
|
||||||
|
sodipodi:nodetypes="aaacacaasa" />
|
||||||
|
<path
|
||||||
|
style="fill:#ebcc8e;fill-opacity:1;stroke:none;stroke-width:0.0333678"
|
||||||
|
d="m 159.83986,62.060975 c 1.20881,-3.8451 -3.41969,-7.27126 -4.28967,-11.19192 -0.45514,-2.05121 -0.58847,-4.20161 -0.45503,-6.30936 0.22192,-3.5059 2.07515,-10.33071 2.07515,-10.33071 0,0 -2.7575,7.42619 -3.39064,10.48135 -0.63315,3.05515 -0.48353,6.60628 -1.74925,9.58427 -1.32044,3.10675 -4.46542,2.86319 -2.38909,-5.52621 -1.43067,3.32391 -5.02115,5.9137 -4.66306,9.40574 0.39851,3.88602 4.06385,8.5454 7.17915,8.93857 2.73415,0.34502 6.73895,-2.05059 7.68244,-5.05173 z"
|
||||||
|
id="path3-8-1"
|
||||||
|
sodipodi:nodetypes="aaaczscasa" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffe0;fill-opacity:1;stroke:none;stroke-width:0.0770683"
|
||||||
|
d="m 152.10845,67.148685 c 1.33923,0.28225 2.8816,-0.44789 3.88763,-1.43099 1.23332,-1.2052 2.07771,-3.10429 2.00025,-4.85763 -0.1006,-2.27582 -3.13834,-5.96235 -3.13834,-5.96235 -0.50373,6.89748 -4.81734,4.21153 -5.97574,7.59737 -0.32656,0.95445 0.12493,2.11857 0.68132,2.93787 0.58438,0.86062 1.62684,1.52227 2.54488,1.71573 z"
|
||||||
|
id="path4"
|
||||||
|
sodipodi:nodetypes="saasaas" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 7.3 KiB |
37
meson.build
Normal file
37
meson.build
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# ***********************************************************************
|
||||||
|
#
|
||||||
|
# Copyright (C) 2025 -- The 4D-STAR Collaboration
|
||||||
|
# File Author: Emily Boudreaux
|
||||||
|
# Last Modified: June 21, 2025
|
||||||
|
#
|
||||||
|
# GridFire is free software; you can use it and/or modify
|
||||||
|
# it under the terms and restrictions the GNU General Library Public
|
||||||
|
# License version 3 (GPLv3) as published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# GridFire is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the GNU Library General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Library General Public License
|
||||||
|
# along with this software; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# *********************************************************************** #
|
||||||
|
project('GridFire', 'cpp', version: '0.0.1a', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0')
|
||||||
|
|
||||||
|
# Add default visibility for all C++ targets
|
||||||
|
add_project_arguments('-fvisibility=default', language: 'cpp')
|
||||||
|
# We disable these because of CppAD
|
||||||
|
add_project_arguments('-Wno-bitwise-instead-of-logical', language: 'cpp')
|
||||||
|
cpp = meson.get_compiler('cpp')
|
||||||
|
|
||||||
|
subdir('build-config')
|
||||||
|
subdir('assets/static')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
subdir('src')
|
||||||
|
subdir('tests')
|
||||||
|
|
||||||
|
|
||||||
20
meson_options.txt
Normal file
20
meson_options.txt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Build options for the project
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# -Doption_name=value
|
||||||
|
|
||||||
|
# -Dbuild_tests=true (default) build tests
|
||||||
|
# -Duser_mode=false (default) enable user mode (set mode = 0) If user mode is enabled then the optimization level is set to 3 and the build type is set to release
|
||||||
|
# -Dbuild_python=true (default) build Python bindings
|
||||||
|
option('build_tests', type: 'boolean', value: true, description: 'Build tests')
|
||||||
|
option('user_mode', type: 'boolean', value: false, description: 'Enable user mode (set mode = 0)')
|
||||||
|
option('build_python', type: 'boolean', value: true, description: 'Build Python bindings')
|
||||||
|
option(
|
||||||
|
'config_error_handling',
|
||||||
|
type: 'combo',
|
||||||
|
choices: [ 'none', 'warn', 'harsh' ],
|
||||||
|
value: 'none',
|
||||||
|
description: 'What to do if a config file fails to load: silent (none), warning (warn), or error (harsh)'
|
||||||
|
)
|
||||||
|
option('build_post_run_utils', type: 'boolean', value: true, description: 'Build Helper Utilities')
|
||||||
|
option('build_debug_utils', type: 'boolean', value: true, description: 'Build Debug Utilities')
|
||||||
0
tests/meson.build
Normal file
0
tests/meson.build
Normal file
Reference in New Issue
Block a user