Commit 99e6ea75 authored by Lefebvre, Jordan's avatar Lefebvre, Jordan
Browse files

WIP #13. Adding initial hysplit POD.

parent 7c4e68e7
Pipeline #10615 passed with stage
in 3 minutes and 43 seconds
......@@ -8,6 +8,7 @@ SET(SOURCE
endian.cc
gfsfile.cc
hcdump.cc
hysplitcdump.cc
)
SET(HEADERS
......
#include "radixio/hysplitcdump.hh"
namespace radix
{
std::string HysplitCDump::id() const
{
return mId;
}
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;
}
int HysplitCDump::forecastHour() const
{
return mForecastHour;
}
void HysplitCDump::setForecastHour(int forecastHour)
{
mForecastHour = forecastHour;
}
int HysplitCDump::numLocations() const
{
return int(mStartLocations.size());
}
void HysplitCDump::locations(int i, int &year, int &month, int &day, int &hour, float &lat, float &lon, float &z, int &minutes) const
{
radix_check(i < mStartLocations.size());
radix_check(i >= 0);
Location loc = mStartLocations[i];
year = loc.year;
month = loc.month;
day = loc.day;
hour = loc.hour;
minutes = loc.minutes;
lat = loc.lat;
lon = loc.lon;
z = loc.z;
}
void HysplitCDump::addLocation(int year, int month, int day, int hour, float lat, float lon, float z, int minutes)
{
Location loc;
loc.year = year;
loc.month = month;
loc.day = day;
loc.hour = hour;
loc.minutes = minutes;
loc.lat = lat;
loc.lon = lon;
loc.z = z;
}
int HysplitCDump::numLat() const
{
return mNumLat;
}
void HysplitCDump::setNumLat(int numLat)
{
mNumLat = numLat;
}
int HysplitCDump::numLon() const
{
return mNumLon;
}
void HysplitCDump::setNumLon(int numLon)
{
mNumLon = numLon;
}
float HysplitCDump::deltaLat() const
{
return mDeltaLat;
}
void HysplitCDump::setDeltaLat(float deltaLat)
{
mDeltaLat = deltaLat;
}
float HysplitCDump::deltaLon() const
{
return mDeltaLon;
}
void HysplitCDump::setDeltaLon(float deltaLon)
{
mDeltaLon = deltaLon;
}
float HysplitCDump::cornerLat() const
{
return mCLat;
}
void HysplitCDump::setCornerLat(float cLat)
{
mCLat = cLat;
}
float HysplitCDump::cornerLon() const
{
return mCLon;
}
void HysplitCDump::setCornerLon(float cLon)
{
mCLon = cLon;
}
void HysplitCDump::addLevel(int altitude)
{
mLevels.push_back(altitude);
}
int HysplitCDump::level(int index) const
{
radix_check(index >= 0);
radix_check(index < mLevels.size());
return mLevels[index];
}
int HysplitCDump::numPollutants() const
{
return mPollutants.size();
}
void HysplitCDump::addPollutant(const std::string &pol)
{
mPollutants.push_back(pol);
}
std::string HysplitCDump::pollutant(int index) const
{
radix_check(index >= 0);
radix_check(index < mPollutants.size());
return mPollutants[index];
}
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;
t.year = year;
t.month = month;
t.day = day;
t.hour = hour;
t.minutes = minute;
t.forecast = forecast;
mStartTimes.push_back(t);
}
void HysplitCDump::startTime(int i, int &year, int &month, int &day, int &hour, int &minute, int &forecast) const
{
radix_check(i >= 0);
radix_check(i < mStartTimes.size());
Time t = mStartTimes[i];
year = t.year;
month = t.month;
day = t.day;
hour = t.hour;
minute = t.minutes;
forecast = t.minutes;
}
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;
t.year = year;
t.month = month;
t.day = day;
t.hour = hour;
t.minutes = minute;
t.forecast = forecast;
mEndTimes.push_back(t);
}
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());
Time t = mEndTimes[i];
year = t.year;
month = t.month;
day = t.day;
hour = t.hour;
minute = t.minutes;
forecast = t.minutes;
}
int HysplitCDump::numNonZeroPoints(int timeIndex, int pollutantIndex, int levelIndex) 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(mXList[timeIndex][pollutantIndex][levelIndex].size()
== mYList[timeIndex][pollutantIndex][levelIndex].size());
return int(mXList[timeIndex][pollutantIndex][levelIndex].size());
}
void HysplitCDump::setNumNonZeroPoints(int timeIndex, int pollutantIndex, int levelIndex, int nxyp)
{
radix_check(timeIndex >= 0);
radix_check(pollutantIndex >= 0);
radix_check(levelIndex >= 0);
// resize according to timeIndex
if(timeIndex >= mXList.size())
{
mXList.push_back(std::vector<std::vector<std::vector<short>>>());
}
if(timeIndex >= mYList.size())
{
mYList.push_back(std::vector<std::vector<std::vector<short>>>());
}
if(timeIndex >= mConcList.size())
{
mConcList.push_back(std::vector<std::vector<std::vector<float>>>());
}
// resize according to pollutantIndex
if(pollutantIndex >= mXList[timeIndex].size())
{
mXList[timeIndex].resize(mPollutants.size());
}
if(pollutantIndex >= mYList[timeIndex].size())
{
mYList[timeIndex].resize(mPollutants.size());
}
if(pollutantIndex >= mConcList[timeIndex].size())
{
mConcList[timeIndex].resize(mPollutants.size());
}
// resize according to levelIndex
if(levelIndex >= mXList[timeIndex][pollutantIndex].size())
{
mXList[timeIndex][pollutantIndex].resize(mLevels.size());
}
if(levelIndex >= mYList[timeIndex][pollutantIndex].size())
{
mYList[timeIndex][pollutantIndex].resize(mLevels.size());
}
if(levelIndex >= mConcList[timeIndex][pollutantIndex].size())
{
mConcList[timeIndex][pollutantIndex].resize(mLevels.size());
}
// resize according to number xy points
if( nxyp >= mXList[timeIndex][pollutantIndex][levelIndex].size())
{
mXList[timeIndex][pollutantIndex][levelIndex].resize(nxyp);
}
if( nxyp >= mYList[timeIndex][pollutantIndex][levelIndex].size())
{
mYList[timeIndex][pollutantIndex][levelIndex].resize(nxyp);
}
if( nxyp >= mConcList[timeIndex][pollutantIndex][levelIndex].size())
{
mConcList[timeIndex][pollutantIndex][levelIndex].resize(nxyp);
}
}
void HysplitCDump::setPoint(int timeIndex, int pollutantIndex, int levelIndex, int nonZeroIndex, short xi, short yi, float concentration)
{
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());
mXList[timeIndex][pollutantIndex][levelIndex][nonZeroIndex] = xi;
mYList[timeIndex][pollutantIndex][levelIndex][nonZeroIndex] = yi;
mConcList[timeIndex][pollutantIndex][levelIndex][nonZeroIndex] = concentration;
}
void HysplitCDump::point(int timeIndex, int pollutantIndex, int levelIndex, int nonZeroIndex, short &xi, short &yi, float &concentration)
{
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());
xi = mXList[timeIndex][pollutantIndex][levelIndex][nonZeroIndex];
yi = mYList[timeIndex][pollutantIndex][levelIndex][nonZeroIndex];
concentration = mConcList[timeIndex][pollutantIndex][levelIndex][nonZeroIndex];
}
} // namespace
......@@ -9,24 +9,148 @@
namespace radix
{
class RADIX_PUBLIC HysplitCDump
{
public:
/**
* @brief The Location struct
* Contains date (year, month, day)
* and time (hour minutes) with
* the location (lat, lon) and altitude (meters).
*/
struct Location
{
int year, month, day, hour, minutes;
float lat, lon, z;
}; // struct Location
struct Time
{
int year, month, day, hour, minutes, forecast;
std::string pretty() const
{
std::stringstream ss;
ss << month << "/" << day << "/" << year << " "
<< hour << " " << minutes;
return ss.str();
}
}; // struct Time
private:
// identification
std::string mId;
// initial year;
int mYear;
// initial month
int mMonth;
// initial day
int mDay;
// initial hour
int mHour;
// initial forecast hour
int mForecastHour;
// number of starting locations
int mNumLocations;
// Array of particle starting locations
std::vector<Location> mStartLocations;
// Grid number latitudes
int mNumLat;
// Grid number longitutde
int mNumLon;
// Size of latitude grid cell
float mDeltaLat;
// Size of longitude grid cell
float mDeltaLon;
// Lower left corner latitude
float mCLat;
// Lower left corner longitude
float mCLon;
// output levels in meters
std::vector<int> mLevels;
// Pollutant identifiers
std::vector<std::string> mPollutants;
// starting times
std::vector<Time> mStartTimes;
// ending times
std::vector<Time> mEndTimes;
// x grid points for concentrations
// x(short) = [time][pollutant][level][#]
std::vector<std::vector<std::vector<std::vector<short>>>> mXList;
// y grid points for concentrations
// y(short) = [time][pollutant][level][#]
std::vector<std::vector<std::vector<std::vector<short>>>> mYList;
// value for concentrations
// concentration(float) = [time][pollutant][level][#]
std::vector<std::vector<std::vector<std::vector<float>>>> mConcList;
public:
std::string id() const;
void setId(const std::string &id);
void dateTime(int &year, int &month, int &day, int &hour) const;
int forecastHour() const;
void setForecastHour(int forecastHour);
int numLocations() const;
void locations(int i, int &year, int &month, int& day, int &hour
, float &lat, float &lon, float &z
, int &minutes) const;
void addLocation(int year, int month, int day, int hour
, float lat, float lon, float z
, int minutes);
int numLat() const;
void setNumLat(int numLat);
int numLon() const;
void setNumLon(int numLat);
float deltaLat() const;
void setDeltaLat(float deltaLat);
float deltaLon() const;
void setDeltaLon(float deltaLon);
float cornerLat() const;
void setCornerLat(float cLat);
float cornerLon() const;
void setCornerLon(float cLon);
void addLevel(int altitude);
int level(int index) const;
int numPollutants() const;
void addPollutant(const std::string& pol);
std::string pollutant(int index) const;
int numStartTimes() const;
void addStartTime(int year, int month, int day, int hour, int minute, int forecast);
void startTime(int i, int &year, int &month, int &day
, int &hour, int &minute, int &forecast) const;
int numEndTimes() const;
void addEndTime(int year, int month, int day, int hour, int minute, int forecast);
void endTime(int i, int &year, int &month, int &day
, int &hour, int &minute, int &forecast) const;
int numNonZeroPoints(int timeIndex, int pollutantIndex, int levelIndex) const;
void setNumNonZeroPoints(int timeIndex, int pollutantIndex, int levelIndex, int nxyp);
void setPoint(int timeIndex, int pollutantIndex, int levelIndex, int nonZeroIndex, short xi, short yi, float concentration);
void point(int timeIndex, int pollutantIndex, int levelIndex, int nonZeroIndex, short &xi, short &yi, float &concentration);
}; // class HysplitCDump
/**
* @class HysplitCDump
* @brief HYSPLIT Concentration file interface
*/
template<typename data_type>
class RADIX_PUBLIC HysplitCDump
class RADIX_PUBLIC HysplitCDumpStream
{
private:
data_type mData;
public:
HysplitCDump(data_type container);
HysplitCDumpStream(data_type container);
/**
* @brief read_from a hysplit concentration file
* @param file Path to hysplit concentration file
*
* Requires data_type to have the following methods:
* setId(const std::string&)
* setDateTime(int year, int month, int day, int hour, int minute)
* setDateTime(int year, int month, int day, int hour)
* setForcastHour(int)
* addLocation(int year, int month, int day, int hour, float lat, float lon, float z, int minutes)
* setNumLat(int)
......@@ -40,7 +164,7 @@ public:
* addStartTime(int year, int month, int day, int hour, int minute, int forecast)
* addEndTime(int year, int month, int day, int hour, int minute, int forecast)
* setNumNonZeroPoints(int timeIndex, int pollutantIndex, int levelIndex, int numPoints)
* addPoint(int timeIndex, int pollutantIndex, int levelIndex, int nonZeroIndex, short xIndex, short yIndex, float concentration)
* setPoint(int timeIndex, int pollutantIndex, int levelIndex, int nonZeroIndex, short xIndex, short yIndex, float concentration)
* @return true on success, false otherwise
*/
bool read_from(const std::string& file);
......@@ -50,7 +174,7 @@ public:
*
* Requires data_type to have the following methods:
* id() const
* int dateTime(int& year, int& month, int& day, int& hour, int& minute) const
* int dateTime(int& year, int& month, int& day, int& hour) const
* int forecastHour() const
* int numLocations() const
* void location(int i, int& year, int& month, int& day, int& hour, float& lat, float& lon, float& z, int& minutes) const
......
......@@ -8,13 +8,13 @@ namespace radix
{
template<typename data_type>
HysplitCDump<data_type>::HysplitCDump(data_type container)
HysplitCDumpStream<data_type>::HysplitCDumpStream(data_type container)
{
mData = container;
}
template<typename data_type>
bool HysplitCDump<data_type>::read_from(const std::string& file)
bool HysplitCDumpStream<data_type>::read_from(const std::string& file)
{
bool result = false;
eafstream fstr(file.c_str()
......@@ -38,7 +38,8 @@ bool HysplitCDump<data_type>::read_from(const std::string& file)
>> numLocations
>> packing;
fstr.readFooter();
mData->setDateTime(year, month, day, hour, forecastHour);
mData->setDateTime(year, month, day, hour);
mData->setForecastHour(forecastHour);
float lat, lon, z;
int minutes;
......@@ -140,7 +141,7 @@ bool HysplitCDump<data_type>::read_from(const std::string& file)
short xi = fstr.readShort();
short yi = fstr.readShort();
float c = fstr.readFloat();
mData->addPoint(timeIndex,i,j,np,xi,yi,c);
mData->setPoint(timeIndex,i,j,np,xi,yi,c);
}
} // if packing is enabled
fstr.readFooter();
......@@ -154,7 +155,7 @@ bool HysplitCDump<data_type>::read_from(const std::string& file)
} // HysplitCDump::read_from
template<typename data_type>
bool HysplitCDump<data_type>::write_to(const std::string& file) const
bool HysplitCDumpStream<data_type>::write_to(const std::string& file) const
{
bool result = false;
eafstream fstr(file.c_str()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment