Commit 44002393 authored by LEFEBVREJP email's avatar LEFEBVREJP email
Browse files

radixio python bindings

gitlab coverage and test report integration
build status and coverage report badge in README.md
parent 5a25768f
......@@ -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
class RADIX_PUBLIC HysplitCDump
{
public: