Commit 592ab5db authored by LEFEBVREJP email's avatar LEFEBVREJP email
Browse files

Merge branch 'radixio-swig' into 'master'

radixio python bindings

See merge request !113
parents 5a25768f 44002393
Pipeline #155215 passed with stages
in 17 minutes and 27 seconds
......@@ -8,80 +8,120 @@ stages:
mac_gcc_testing:
tags:
- mac
artifacts:
reports:
junit: build/ctest-results.xml
script:
- which git
- git --version
- module load cmake gcc/4.8.5 qt/5.9.1 vtk/8.1.0
- module load cmake/3.21.0 gcc/4.8.5 qt/5.9.1 vtk/8.1.0
- which cmake
- mkdir build
- cd build
- cmake -DTasmanian_DIR=/opt/tasmanian/6.0 ^
-DBUILDNAME=$(uname -s)-GCC-4.8.5-Debug-${CI_BUILD_REF_NAME} ^
-DCMAKE_BUILD_TYPE=DEBUG ^
-Dradix_ENABLE_TESTS=ON ^
-Dradix_ENABLE_SECONDARY_TESTED_CODE=ON ^
-Dradix_ENABLE_TESTS=ON ^
-DTPL_ENABLE_VTK=ON ^
-Dradix_ENABLE_radixplot=OFF ^
- cmake -DTasmanian_DIR=/opt/tasmanian/6.0
-DBUILDNAME=$(uname -s)-GCC-4.8.5-Debug-${CI_BUILD_REF_NAME}
-DCMAKE_BUILD_TYPE=DEBUG
-Dradix_ENABLE_TESTS=ON
-Dradix_ENABLE_SECONDARY_TESTED_CODE=ON
-Dradix_ENABLE_TESTS=ON
-DTPL_ENABLE_VTK=ON
-Dradix_ENABLE_radixplot=OFF
-Dradix_ENABLE_radixwidgets=OFF ..
- ctest --verbose --output-on-failure ^
-D ExperimentalStart ^
-D ExperimentalBuild ^
- ctest --output-on-failure
-D ExperimentalStart
-D ExperimentalBuild
-D ExperimentalTest
--output-junit ctest-results.xml
mac_llvm_testing:
tags:
- mac
artifacts:
reports:
junit: build/ctest-results.xml
script:
- which git
- git --version
- module load cmake qt/5.9.1 vtk/8.1.0
- module load cmake/3.21.0 qt/5.9.1 vtk/8.1.0
- mkdir build
- cd build
- which cmake
- export radix_ENABLE_Fortran=OFF
- cmake -DTasmanian_DIR=/opt/tasmanian/6.0 ^
-DBUILDNAME=$(uname -s)-LLVM-Debug-${CI_BUILD_REF_NAME} ^
-DCMAKE_BUILD_TYPE=DEBUG ^
-Dradix_ENABLE_TESTS=ON ^
-Dradix_ENABLE_SECONDARY_TESTED_CODE=ON ^
-Dradix_ENABLE_TESTS=ON ^
-DTPL_ENABLE_VTK=ON ^
-Dradix_ENABLE_radixplot=OFF ^
- cmake -DTasmanian_DIR=/opt/tasmanian/6.0
-DBUILDNAME=$(uname -s)-LLVM-Debug-${CI_BUILD_REF_NAME}
-DCMAKE_BUILD_TYPE=DEBUG
-Dradix_ENABLE_TESTS=ON
-Dradix_ENABLE_SECONDARY_TESTED_CODE=ON
-Dradix_ENABLE_TESTS=ON
-DTPL_ENABLE_VTK=ON
-Dradix_ENABLE_radixplot=OFF
-Dradix_ENABLE_radixwidgets=OFF ..
- ctest --verbose --output-on-failure ^
-D ExperimentalStart ^
-D ExperimentalBuild ^
- ctest --output-on-failure
-D ExperimentalStart
-D ExperimentalBuild
-D ExperimentalTest
--output-junit ctest-results.xml
linux_python_bindings:
tags:
- linux
artifacts:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}-python-bindings
paths:
- lib/
- python/
script:
- which git
- git --version
- mkdir build
- cd build
- module load swig/4.0.2 cmake
- which cmake
- cmake
-DCMAKE_INSTALL_PREFIX=${CI_PROJECT_DIR}
-DBUILD_SHARED_LIBS=ON
-DCMAKE_BUILD_TYPE=Release
-Dradix_ENABLE_TESTS=ON
-DENABLE_PYTHON_WRAPPERS=ON
-Dradix_ENABLE_radixmath=ON
-Dradix_ENABLE_radixio=ON
-Dradix_ENABLE_TESTS=OFF ..
- cmake --build . --target install
linux_gcc_testing:
tags:
- linux
artifacts:
reports:
junit: build/ctest-results.xml
script:
- which git
- git --version
- mkdir build
- cd build
- module load cmake qt/5.9.0 vtk/8.1.0
- module load swig/4.0.2 cmake/3.21.0 qt/5.9.0 vtk/8.1.0
- which cmake
- cmake -DTasmanian_DIR=/opt/vendors/tasmanian/6.0 ^
-DBUILDNAME=$(uname -s)-GCC-4.8.5-Release-${CI_BUILD_REF_NAME} ^
-DCMAKE_BUILD_TYPE=Release ^
-Dradix_ENABLE_TESTS=ON ^
-DENABLE_PYTHON_WRAPPERS=ON ^
-Dradix_ENABLE_SECONDARY_TESTED_CODE=ON ^
-Dradix_ENABLE_TESTS=ON -DTPL_ENABLE_VTK=ON ^
-Dradix_ENABLE_radixplot=OFF ^
- cmake -DTasmanian_DIR=/opt/vendors/tasmanian/6.0
-DBUILDNAME=$(uname -s)-GCC-4.8.5-Release-${CI_BUILD_REF_NAME}
-DBUILD_SHARED_LIBS=ON
-DCMAKE_BUILD_TYPE=Release
-Dradix_ENABLE_TESTS=ON
-DENABLE_PYTHON_WRAPPERS=ON
-Dradix_ENABLE_SECONDARY_TESTED_CODE=ON
-Dradix_ENABLE_TESTS=ON -DTPL_ENABLE_VTK=ON
-Dradix_ENABLE_radixplot=OFF
-Dradix_ENABLE_radixwidgets=OFF ..
- ctest --verbose --output-on-failure ^
-D ExperimentalStart ^
-D ExperimentalBuild ^
-D ExperimentalTest
- cmake --build .
- ctest --output-junit ctest-results.xml
linux_analysis:
stage: analysis
tags:
- linux
artifacts:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}-analysis
reports:
cobertura: build/coverage.xml
script:
- which git
- git --version
......@@ -89,23 +129,28 @@ linux_analysis:
- cd build
- module load cmake valgrind
- which cmake
- cmake -DTasmanian_DIR=/opt/vendors/tasmanian/6.0/ ^
-DCOVERAGE_EXTRA_FLAGS="-s ${CI_PROJECT_DIR}/googletest -d" ^
-DMEMCHECK_COMMAND=$(which valgrind) ^
-DBUILDNAME=$(uname -s)-GCC-4.8.5-Debug-${CI_BUILD_REF_NAME} ^
-DCMAKE_BUILD_TYPE=DEBUG ^
-Dradix_ENABLE_COVERAGE_TESTING=ON ^
-Dradix_ENABLE_TESTS=ON ^
-Dradix_ENABLE_SECONDARY_TESTED_CODE=ON ^
-Dradix_ENABLE_TESTS=ON ^
-Dradix_ENABLE_radixplot=OFF ^
- cmake -DTasmanian_DIR=/opt/vendors/tasmanian/6.0/
-DCOVERAGE_EXTRA_FLAGS="-s ${CI_PROJECT_DIR}/googletest -d"
-DMEMCHECK_COMMAND=$(which valgrind)
-DBUILDNAME=$(uname -s)-GCC-4.8.5-Debug-${CI_BUILD_REF_NAME}
-DCMAKE_BUILD_TYPE=DEBUG
-Dradix_ENABLE_COVERAGE_TESTING=ON
-Dradix_ENABLE_TESTS=ON
-Dradix_ENABLE_SECONDARY_TESTED_CODE=ON
-Dradix_ENABLE_TESTS=ON
-Dradix_ENABLE_radixplot=OFF
-Dradix_ENABLE_radixwidgets=OFF ..
- ctest --verbose --output-on-failure^
-D ExperimentalStart ^
-D ExperimentalBuild ^
-D ExperimentalTest ^
-D ExperimentalMemCheck ^
-D ExperimentalCoverage
- ctest --output-on-failure
-D ExperimentalStart
-D ExperimentalBuild
-D ExperimentalTest
-D ExperimentalMemCheck
- gcovr --filter=".*/radix.*"
--xml-pretty
--print-summary
-o coverage.xml
-r $CI_PROJECT_DIR
coverage: /^\s*lines:\s*\d+.\d+\%/
allow_failure: true
linux_openmpi_testing:
......@@ -127,7 +172,7 @@ linux_openmpi_testing:
-Dradix_ENABLE_googletest=ON ^
-Dradix_ENABLE_radixdl=ON ^
-Dradix_ENABLE_radixcore=ON ..
- ctest --verbose --output-on-failure ^
- ctest --output-on-failure ^
-D ExperimentalStart ^
-D ExperimentalBuild ^
-D ExperimentalTest
......
......@@ -14,6 +14,9 @@ IF (NOT TRIBITS_PROCESSING_PACKAGE)
SET(radix_ENABLE_CXX11 ON CACHE BOOL "Compile using the C++11 standard" FORCE)
#SET(USE_QT5 TRUE)
# Disable SONAME VERSION
SET(CMAKE_PLATFORM_NO_VERSIONED_SONAME 1)
# disable generating HTML dependencies webpage and xml files
SET(${PROJECT_NAME}_DEPS_XML_OUTPUT_FILE OFF CACHE BOOL "")
# disable TriBITS export system to save time configuring
......@@ -32,6 +35,9 @@ IF (NOT TRIBITS_PROCESSING_PACKAGE)
IF(RADIX_DBC)
ADD_DEFINITIONS("-DRADIX_DBC=${RADIX_DBC}")
ENDIF()
IF(ENABLE_PYTHON_WRAPPERS AND NOT BUILD_SHARED_LIBS)
MESSAGE(FATAL_ERROR "ENABLE_PYTHON_WRAPPERS=ON requires BUILD_SHARED_LIBS=ON")
ENDIF()
#
# For windows with BUILD_SHARED_LIBS we must use CMAKE_RUNTIME_OUTPUT_DIRECTORY
# to place all *dll and *exe in the same directory so unit tests will work
......
[![pipeline status](https://code.ornl.gov/jap/radix/badges/master/pipeline.svg)](https://code.ornl.gov/jap/radix/-/commits/master)
[![coverage report](https://code.ornl.gov/jap/radix/badges/master/coverage.svg)](https://code.ornl.gov/jap/radix/-/commits/master)
# Requirements
* C compiler. gcc 4.8 tested
* Git
* CMake. 2.8.12.2 tested.
* CMake. 3.8.0 tested.
# Getting Started
* You will need to save your ssh-key in [code.ornl.gov](https://code.ornl.gov/profile/keys).
......@@ -43,3 +46,22 @@ cmake ^
`../configure.sh or ..\configure.bat`
* I place the configure script in the build directory as opposed to the build/radix directory because it allows me to delete the build/radix
directory without removing my script.
# Enable Python Bindings
Example configuration enabling python bindings
```
#!/bin/bash
# Linux bash file example
rm -rf CMake*
cmake \
-D CMAKE_INSTALL_PREFIX=`pwd`/install \
-D CMAKE_BUILD_TYPE:STRING=RELEASE \
-D radix_ENABLE_radixio:BOOL=ON \
-D radix_ENABLE_radixmath:BOOL=ON \
-D radix_ENABLE_TESTS:BOOL=OFF \
-G "Unix Makefiles" \
~/radix
```
After configuration, compilation, and installation, you need to add the python directory to PYTHONPATH.
`export PYTHONPATH=~/build/radix/install/python/`
......@@ -9,6 +9,9 @@ FIND_PACKAGE(PythonLibsFromExe REQUIRED)
# Find the SWIG package for language bindings
FIND_PACKAGE(SWIG REQUIRED)
IF(CMAKE_VERSION VERSION_GREATER "3.8.0")
include(UseSWIG)
ENDIF()
#
# Ensure that PYTHON wrappers are enabled
IF (ENABLE_PYTHON_WRAPPERS)
......@@ -45,8 +48,10 @@ IF (ENABLE_PYTHON_WRAPPERS)
SET(SWIG_CXX_FLAGS "${SWIG_CXX_FLAGS} -diag-disable 955")
ENDIF()
IF(CMAKE_VERSION VERSION_LESS "3.8.0")
# Tell SWIG to use modern Python code
LIST(APPEND CMAKE_SWIG_FLAGS "-modern" "-noproxydel")
ENDIF()
# If python version is high enough, add -py3 flag
IF(PYTHON_VERSION_STRING VERSION_GREATER 3.0)
......@@ -122,9 +127,7 @@ IF(ENABLE_PYTHON_WRAPPERS)
# Bug fix: version of CMake older than 2.8.8 don't support the
# INCLUDE_DIRECTORIES property
IF(CMAKE_MAJOR_VERSION LESS 3
AND CMAKE_MINOR_VERSION LESS 9
AND CMAKE_PATCH_VERSION LESS 9)
IF(CMAKE_VERSION VERSION_LESS "2.8.8")
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR})
ENDIF()
ELSE()
......@@ -173,10 +176,11 @@ FUNCTION(_RADIX_ADD_SWIG)
SET(SWIG_MODULE_${MODULE_NAME}_EXTRA_DEPS ${DEPENDENCIES} )
# Add the new python target
IF("${CMAKE_VERSION}" VERSION_LESS "3.8.0")
IF(CMAKE_VERSION VERSION_LESS "3.8.0")
SWIG_ADD_MODULE(${MODULE_NAME} python
${SRC_FILE} ${MKSWIG_EXTRASRC})
ELSE()
SET_PROPERTY(SOURCE ${SRC_FILE} PROPERTY CPLUSPLUS ON)
SWIG_ADD_LIBRARY(${MODULE_NAME}
LANGUAGE python
TYPE MODULE
......
......@@ -49,5 +49,10 @@ TRIBITS_ADD_TEST_DIRECTORIES(tests)
# Add example directory
TRIBITS_ADD_EXAMPLE_DIRECTORIES(examples)
IF(ENABLE_PYTHON_WRAPPERS)
ADD_SUBDIRECTORY(python)
ENDIF()
INSTALL(FILES ${HEADERS} DESTINATION "include/radixio/")
TRIBITS_SUBPACKAGE_POSTPROCESS()
......@@ -13517,7 +13517,7 @@ const std::unordered_map<int, DecayDBEntry>& DecayDb::activations() const
{
return mActivation;
}
const DecayDBEntry& DecayDb::light_element(const int zaid) const
const DecayDBEntry& DecayDb::light_element(int zaid) const
{
const auto& it = mActivation.find(zaid);
return it->second;
......@@ -13530,7 +13530,7 @@ const std::unordered_map<int, DecayDBEntry>& DecayDb::actinides() const
{
return mActinide;
}
const DecayDBEntry& DecayDb::actinide(const int zaid) const
const DecayDBEntry& DecayDb::actinide(int zaid) const
{
const auto& it = mActinide.find(zaid);
return it->second;
......@@ -13543,14 +13543,14 @@ const std::unordered_map<int, DecayDBEntry>& DecayDb::fission_products() const
{
return mFissionProduct;
}
const DecayDBEntry& DecayDb::fission_product(const int zaid) const
const DecayDBEntry& DecayDb::fission_product(int zaid) const
{
const auto& it = mFissionProduct.find(zaid);
return it->second;
}
const std::unordered_map<int, DecayDBEntry>::iterator DecayDb::find_decayer(
const int zaid)
std::unordered_map<int, DecayDBEntry>::const_iterator DecayDb::find_decayer(
int zaid)
{
std::unordered_map<int, DecayDBEntry>::iterator decayer;
const auto& fpI = mFissionProduct.find(zaid);
......@@ -13575,7 +13575,7 @@ const std::unordered_map<int, DecayDBEntry>::iterator DecayDb::find_decayer(
return decayer;
}
const DecayDBEntry& DecayDb::find_entry(const int zaid) const
const DecayDBEntry& DecayDb::find_entry(int zaid) const
{
if (mFissionProduct.find(zaid) != mFissionProduct.end())
{
......
......@@ -10,7 +10,7 @@
namespace radix
{
struct DecayDBEntry
struct RADIX_PUBLIC DecayDBEntry
{
/**
* symbol
......@@ -140,16 +140,15 @@ class RADIX_PUBLIC DecayDb
void set_fission_product_title(const std::string& title);
std::unordered_map<int, DecayDBEntry>& activations();
const std::unordered_map<int, DecayDBEntry>& activations() const;
const DecayDBEntry& light_element(const int zaid) const;
const DecayDBEntry& light_element(int zaid) const;
std::unordered_map<int, DecayDBEntry>& actinides();
const std::unordered_map<int, DecayDBEntry>& actinides() const;
const DecayDBEntry& actinide(const int zaid) const;
const DecayDBEntry& actinide(int zaid) const;
std::unordered_map<int, DecayDBEntry>& fission_products();
const std::unordered_map<int, DecayDBEntry>& fission_products() const;
const DecayDBEntry& fission_product(const int zaid) const;
const std::unordered_map<int, DecayDBEntry>::iterator find_decayer(
const int zaid);
const DecayDBEntry& find_entry(const int zaid) const;
const DecayDBEntry& fission_product(int zaid) const;
std::unordered_map<int, DecayDBEntry>::const_iterator find_decayer(int zaid);
const DecayDBEntry& find_entry(int zaid) const;
}; // class
} // namespace radix
......
......@@ -139,7 +139,8 @@ bool system_is_big_endian()
#ifdef _WIN32
typedef unsigned __int32 uint32_t;
#endif
union {
union
{
uint32_t i;
char c[4];
} bint = {0x01020304};
......
......@@ -9,25 +9,28 @@ void HysplitCDump::setId(const std::string &id) { mId = id; }
void HysplitCDump::dateTime(int &year, int &month, int &day, int &hour) const
{
year = mYear;
month = mMonth;
day = mDay;
hour = mHour;
year = mTime.year;
month = mTime.month;
day = mTime.day;
hour = mTime.hour;
}
const HysplitTime &HysplitCDump::dateTime() const { return mTime; }
void HysplitCDump::setDateTime(int year, int month, int day, int hour)
{
mYear = year;
mMonth = month;
mDay = day;
mHour = hour;
mTime.year = year;
mTime.month = month;
mTime.day = day;
mTime.hour = hour;
mTime.forecast = 0;
}
int HysplitCDump::forecastHour() const { return mForecastHour; }
int HysplitCDump::forecastHour() const { return mTime.forecast; }
void HysplitCDump::setForecastHour(int forecastHour)
{
mForecastHour = forecastHour;
mTime.forecast = forecastHour;
}
int HysplitCDump::numLocations() const { return int(mStartLocations.size()); }
......@@ -39,7 +42,7 @@ void HysplitCDump::location(int i, int &year, int &month, int &day, int &hour,
radix_check(i < mStartLocations.size());
radix_check(i >= 0);
size_t i_ = size_t(i);
Location loc = mStartLocations[i_];
const HysplitLocation &loc = mStartLocations[i_];
year = loc.year;
month = loc.month;
day = loc.day;
......@@ -50,10 +53,18 @@ void HysplitCDump::location(int i, int &year, int &month, int &day, int &hour,
z = loc.z;
}
const HysplitLocation &HysplitCDump::location(int i) const
{
radix_check(i < mStartLocations.size());
radix_check(i >= 0);
size_t i_ = size_t(i);
return mStartLocations[i_];
}
void HysplitCDump::addLocation(int year, int month, int day, int hour,
float lat, float lon, float z, int minutes)
{
Location loc;
HysplitLocation loc;
loc.year = year;
loc.month = month;
loc.day = day;
......@@ -119,7 +130,7 @@ int HysplitCDump::numStartTimes() const { return int(mStartTimes.size()); }
void HysplitCDump::addStartTime(int year, int month, int day, int hour,
int minute, int forecast)
{
Time t;
HysplitTime t;
t.year = year;
t.month = month;
t.day = day;
......@@ -135,7 +146,7 @@ void HysplitCDump::startTime(int i, int &year, int &month, int &day, int &hour,
radix_check(i >= 0);
radix_check(i < mStartTimes.size());
size_t i_ = size_t(i);
Time t = mStartTimes[i_];
const HysplitTime &t = mStartTimes[i_];
year = t.year;
month = t.month;
day = t.day;
......@@ -144,12 +155,20 @@ void HysplitCDump::startTime(int i, int &year, int &month, int &day, int &hour,
forecast = t.forecast;
}
const HysplitTime &HysplitCDump::startTime(int i) const
{
radix_check(i >= 0);
radix_check(i < mStartTimes.size());
size_t i_ = size_t(i);
return mStartTimes[i_];
}
int HysplitCDump::numEndTimes() const { return int(mEndTimes.size()); }
void HysplitCDump::addEndTime(int year, int month, int day, int hour,
int minute, int forecast)
{
Time t;
HysplitTime t;
t.year = year;
t.month = month;
t.day = day;
......@@ -159,13 +178,20 @@ void HysplitCDump::addEndTime(int year, int month, int day, int hour,
mEndTimes.push_back(t);
}
const HysplitTime &HysplitCDump::endTime(int i) const
{
radix_check(i >= 0);
radix_check(i < mEndTimes.size());
size_t i_ = size_t(i);
return mEndTimes[i_];
}
void HysplitCDump::endTime(int i, int &year, int &month, int &day, int &hour,
int &minute, int &forecast) const
{
radix_check(i >= 0);
radix_check(i < mEndTimes.size());
size_t i_ = size_t(i);
Time t = mEndTimes[i_];
const HysplitTime &t = mEndTimes[i_];
year = t.year;
month = t.month;
day = t.day;
......@@ -303,7 +329,7 @@ void HysplitCDump::setPoint(int timeIndex, int pollutantIndex, int levelIndex,
}
void HysplitCDump::point(int timeIndex, int pollutantIndex, int levelIndex,
int nonZeroIndex, short &xi, short &yi,
float &concentration)
float &concentration) const
{
radix_check(timeIndex >= 0);
radix_check(pollutantIndex >= 0);
......@@ -333,4 +359,37 @@ void HysplitCDump::point(int timeIndex, int pollutantIndex, int levelIndex,
concentration = mConcList[ti][pi][li][ni];
}
HysplitPoint HysplitCDump::point(int timeIndex, int pollutantIndex,
int levelIndex, int nonZeroIndex) const
{
radix_check(timeIndex >= 0);
radix_check(pollutantIndex >= 0);
radix_check(levelIndex >= 0);
radix_check(timeIndex < mXList.size());
radix_check(timeIndex < mYList.size());
radix_check(timeIndex < mConcList.size());
radix_check(pollutantIndex < mXList[timeIndex].size());
radix_check(pollutantIndex < mYList[timeIndex].size());
radix_check(pollutantIndex < mConcList[timeIndex].size());
radix_check(levelIndex < mXList[timeIndex][pollutantIndex].size());
radix_check(levelIndex < mYList[timeIndex][pollutantIndex].size());
radix_check(levelIndex < mConcList[timeIndex][pollutantIndex].size());
radix_check(nonZeroIndex <
mXList[timeIndex][pollutantIndex][levelIndex].size());
radix_check(nonZeroIndex <
mYList[timeIndex][pollutantIndex][levelIndex].size());
radix_check(nonZeroIndex <
mConcList[timeIndex][pollutantIndex][levelIndex].size());
size_t ti = size_t(timeIndex);
size_t pi = size_t(pollutantIndex);
size_t li = size_t(levelIndex);
size_t ni = size_t(nonZeroIndex);
HysplitPoint p;
p.xi = mXList[ti][pi][li][ni];
p.yi = mYList[ti][pi][li][ni];
p.concentration = mConcList[ti][pi][li][ni];
return p;
}
} // namespace radix
......@@ -10,48 +10,50 @@
namespace radix
{
class RADIX_PUBLIC HysplitCDump
{
public:
typedef std::shared_ptr<HysplitCDump> SP;
/**
* @brief The Location struct
/**
* @brief The HysplitLocation struct
* Contains date (year, month, day)
* and time (hour minutes) with
* the location (lat, lon) and altitude (meters).
*/
struct Location
{
struct RADIX_PUBLIC HysplitLocation
{
int year, month, day, hour, minutes;
float lat, lon, z;
}; // struct Location
struct Time
{
}; // struct HysplitLocation
struct RADIX_PUBLIC HysplitTime
{
int year, month, day, hour, minutes, forecast;
std::string pretty() const
{
std::stringstream ss;
std::ostringstream ss;
ss << month << "/" << day << "/" << year << " " << hour << " " << minutes;
return ss.str();
}
}; // struct Time
}; // struct Time
struct RADIX_PUBLIC HysplitPoint
{
short xi;
short yi;
float concentration;
}; // struct HysplitPoint