Commit 55fa2d1c authored by Lefebvre, Jordan's avatar Lefebvre, Jordan

Merge branch 'trajplot' into 'master'

Adding initial trajplot workflow and testing.

See merge request nsm/haem!2
parents fe7f9968 eb38ec1d
......@@ -17,6 +17,7 @@ trajectorycontrol.hh
trajectoryoutput.hh
trajectoryoutput.i.hh
trajectoryworkflow.hh
trajplotworkflow.hh
time.hh
)
......@@ -29,6 +30,7 @@ setup.cc
trajectorycontrol.cc
trajectoryoutput.cc
trajectoryworkflow.cc
trajplotworkflow.cc
)
TRIBITS_ADD_LIBRARY(haemmodel
......
......@@ -2,6 +2,7 @@
#include "haemmodel/trajectoryoutput.hh"
#include "haemmodel/trajectoryworkflow.hh"
#include "haemmodel/trajplotworkflow.hh"
#include "radixbug/bug.hh"
#include "radixcore/system.hh"
......@@ -66,3 +67,33 @@ TEST(HAEM, TrajectoryWorkflow)
EXPECT_NEAR(point.y, trajectory.lat, 1e-3);
EXPECT_NEAR(point.z, trajectory.z, 1e-3);
}
TEST(HAEM, TrajPlotWorkflow)
{
TrajPlotWorkflow work;
work.setHysplitDirectory(radix::env("HYSPLIT"));
// assume default tdump file generated from previous file
// assume default trajplot exec path
work.setEndHour(24); // only plot for 24 of the above run time
work.setMapBackground(work.hysplitDirectory() + "/graphics/arlmap");
work.setProjection(TrajPlotMapProjection::Polar);
work.setLabelIntervals(1);
work.setVertical(TrajPlotVerticalCoordinate::None);
work.setOriginSymbol(false);
work.run();
// generates the default output file
EXPECT_TRUE(radix::file_exists("trajplot.ps"));
// radix::remove_file("trajplot.ps");
}
TEST(HAEM, TrajPlotWorkflowKML)
{
TrajPlotWorkflow work;
work.setHysplitDirectory(radix::env("HYSPLIT"));
// assume default tdump file generated from previous file
// assume default trajplot exec path
work.setEndHour(24); // only plot for 24 of the above run time
work.setKmlOutput(true);
work.run();
// trajplot is always generated
EXPECT_TRUE(radix::file_exists("trajplot.ps"));
EXPECT_TRUE(radix::file_exists("HYSPLITtraj_ps_01.kml"));
}
\ No newline at end of file
#include <memory>
#include <sstream>
#include "haemmodel/persistencemanager.hh"
#include "haemmodel/trajplotworkflow.hh"
namespace haem
{
std::string TrajPlotWorkflow::hysplitDirectory() const
{
return m_hysplit_directory;
}
void TrajPlotWorkflow::setHysplitDirectory(const std::string &hysplit_directory)
{
m_hysplit_directory = hysplit_directory;
}
std::string TrajPlotWorkflow::trajPlotExe() const { return m_trajplot_exe; }
void TrajPlotWorkflow::setTrajPlotExe(const std::string &trajectory_exe)
{
m_trajplot_exe = trajectory_exe;
}
std::string TrajPlotWorkflow::inputPath() const { return m_input_path; }
void TrajPlotWorkflow::setInputPath(const std::string &input_path)
{
m_input_path = input_path;
}
bool TrajPlotWorkflow::kmlOutput() const { return m_kml_output; }
void TrajPlotWorkflow::setKmlOutput(bool kml_output)
{
m_kml_output = kml_output;
}
std::string TrajPlotWorkflow::mapBackground() const { return m_map_background; }
void TrajPlotWorkflow::setMapBackground(const std::string &map_background)
{
m_map_background = map_background;
}
TrajPlotMapProjection TrajPlotWorkflow::projection() const
{
return m_projection;
}
void TrajPlotWorkflow::setProjection(const TrajPlotMapProjection &projection)
{
m_projection = projection;
}
int TrajPlotWorkflow::labelIntervals() const { return m_label_intervals; }
void TrajPlotWorkflow::setLabelIntervals(int label_intervals)
{
m_label_intervals = label_intervals;
}
bool TrajPlotWorkflow::separateFrames() const { return m_separate_frames; }
void TrajPlotWorkflow::setSeparateFrames(bool separate_frames)
{
m_separate_frames = separate_frames;
}
TrajPlotVerticalCoordinate TrajPlotWorkflow::vertical() const
{
return m_vertical;
}
void TrajPlotWorkflow::setVertical(const TrajPlotVerticalCoordinate &vertical)
{
m_vertical = vertical;
}
bool TrajPlotWorkflow::originSymbol() const { return m_origin_symbol; }
void TrajPlotWorkflow::setOriginSymbol(bool origin_symbol)
{
m_origin_symbol = origin_symbol;
}
TrajPlotWorkflow::TrajPlotWorkflow() {}
void TrajPlotWorkflow::run() const
{
// check if this is a file listing separated by '+'
if (m_input_path.find("+") == std::string::npos)
{
if (radix::file_exists(m_input_path) == false)
{
throw std::logic_error(
"***Error: Required input file file does not exist.");
}
}
//
// Find the trajplot executable
std::string executable =
radix::to_native_path(m_hysplit_directory + m_trajplot_exe);
if (radix::file_exists(executable) == false)
{
executable = executable + ".exe";
}
if (radix::file_exists(executable) == false)
{
throw std::logic_error("***Error: Failed to find '" + executable + "'");
}
std::ostringstream command;
command << executable;
//
// Add options
command << " -i" << m_input_path;
if (m_end_hour > 0)
{
command << " -e" << m_end_hour;
}
if (m_kml_output)
{
command << " -a3";
}
// all Postscript file plotting options
if (!m_map_background.empty())
{
if (radix::file_exists(m_map_background) == false)
{
throw std::logic_error(
"***Error: Provided map background does not exist.");
}
command << " -j" << m_map_background;
}
if (m_projection != TrajPlotMapProjection::Auto)
{
command << " -m" << static_cast<int>(m_projection);
}
if (m_label_intervals != 6)
{
command << " -l" << m_label_intervals;
}
if (m_separate_frames)
{
command << " -f1";
}
if (m_vertical != TrajPlotVerticalCoordinate::AGL)
{
command << " -v" << static_cast<int>(m_vertical);
}
if (!m_origin_symbol)
{
command << " -s0";
}
std::cout << command.str() << std::endl;
int return_code = system(command.str().c_str());
int exit_code = return_code;
#ifndef _WIN32
exit_code = exit_code >> 8;
#endif
std::cout << "HYSPLIT TrajPlot finished (" << exit_code << ")." << std::endl;
}
int TrajPlotWorkflow::endHour() const { return m_end_hour; }
void TrajPlotWorkflow::setEndHour(int end_hour) { m_end_hour = end_hour; }
} // namespace haem
#ifndef HAEM_HAEMMODEL_TRAJPLOTWORKFLOW_HH_
#define HAEM_HAEMMODEL_TRAJPLOTWORKFLOW_HH_
#include <array>
#include <memory>
#include <string>
#include <vector>
#include "radixbug/bug.hh"
#include "radixcore/system.hh"
#include "radixcore/visibility.hh"
namespace haem
{
enum class TrajPlotMapProjection
{
Auto,
Polar,
Lambert,
Mercator,
Cylindical
};
enum class TrajPlotVerticalCoordinate
{
Pressure,
AGL,
Theta,
Meteorology,
None
};
/**
* HYSPLIT TrajPlot Workflow
*
* @author jap
*/
class RADIX_PUBLIC TrajPlotWorkflow
{
protected:
std::string m_hysplit_directory;
std::string m_trajplot_exe = "/exec/trajplot";
std::string m_map_background;
std::string m_input_path = "tdump";
int m_end_hour = -1;
int m_label_intervals = 6;
bool m_kml_output = false;
bool m_separate_frames = false;
bool m_origin_symbol = true;
TrajPlotMapProjection m_projection = TrajPlotMapProjection::Auto;
TrajPlotVerticalCoordinate m_vertical = TrajPlotVerticalCoordinate::AGL;
public:
TrajPlotWorkflow();
/**
* @brief run Executes the HYSPLIT trajectory plot capability
*/
void run() const;
std::string hysplitDirectory() const;
void setHysplitDirectory(const std::string &hysplit_directory);
std::string trajPlotExe() const;
/**
* @brief setTrajPlotExe Set the trajectory executable path
* This should be relative to the HYSPLIT directory
* @param trajectory_exe
*/
void setTrajPlotExe(const std::string &trajplot_exe);
int endHour() const;
void setEndHour(int end_hour);
std::string inputPath() const;
void setInputPath(const std::string &input_path);
bool kmlOutput() const;
void setKmlOutput(bool kml_output);
std::string mapBackground() const;
void setMapBackground(const std::string &map_background);
TrajPlotMapProjection projection() const;
void setProjection(const TrajPlotMapProjection &projection);
int labelIntervals() const;
void setLabelIntervals(int label_intervals);
/**
* @brief separateFrames Generate separate frame per file
* @return
*/
bool separateFrames() const;
/**
* @brief setSeparateFrames Whether to generate separate frame per file
* @param separate_frames
*/
void setSeparateFrames(bool separate_frames);
TrajPlotVerticalCoordinate vertical() const;
void setVertical(const TrajPlotVerticalCoordinate &vertical);
bool originSymbol() const;
void setOriginSymbol(bool origin_symbol);
}; // class
} // namespace haem
#endif /** HAEM_HAEMMODEL_TRAJPLOTWORKFLOW_HH_ */
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