...
 
Commits (9)
......@@ -9,9 +9,14 @@ ENDIF()
SET(HEADERS
ascdata.hh
concentrationcontrol.hh
concentrationworkflow.hh
control.hh
emission.hh
meteorology.hh
outputgridrequest.hh
persistencemanager.hh
pollutantdefinition.hh
setup.hh
trajectorycontrol.hh
trajectoryoutput.hh
......@@ -19,18 +24,25 @@ trajectoryoutput.i.hh
trajectoryworkflow.hh
trajplotworkflow.hh
time.hh
workflow.hh
)
SET(SOURCES
ascdata.cc
concentrationcontrol.cc
concentrationworkflow.cc
control.cc
emission.cc
meteorology.cc
outputgridrequest.cc
persistencemanager.cc
pollutantdefinition.cc
setup.cc
trajectorycontrol.cc
trajectoryoutput.cc
trajectoryworkflow.cc
trajplotworkflow.cc
workflow.cc
)
TRIBITS_ADD_LIBRARY(haemmodel
......
#include "haemmodel/concentrationcontrol.hh"
namespace haem
{
ConcentrationControl::ConcentrationControl()
: Control()
{
}
const std::vector<Emission::SP> &ConcentrationControl::emissions() const
{
return m_emissions;
}
std::vector<Emission::SP> &ConcentrationControl::emissions()
{
return m_emissions;
}
void ConcentrationControl::setEmissions(
const std::vector<Emission::SP> &emissions)
{
m_emissions = emissions;
}
const std::vector<OutputGridRequest::SP>
&ConcentrationControl::outputGridRequests() const
{
return m_output_grid_requests;
}
std::vector<OutputGridRequest::SP> &ConcentrationControl::outputGridRequests()
{
return m_output_grid_requests;
}
void ConcentrationControl::setOutputGridRequests(
const std::vector<OutputGridRequest::SP> &output_grid_requests)
{
m_output_grid_requests = output_grid_requests;
}
const std::vector<PollutantDefinition::SP>
&ConcentrationControl::depositionDefinitions() const
{
return m_deposition_definitions;
}
std::vector<PollutantDefinition::SP>
&ConcentrationControl::depositionDefinitions()
{
return m_deposition_definitions;
}
void ConcentrationControl::setDepositionDefinitions(
const std::vector<PollutantDefinition::SP> &deposition_definitions)
{
m_deposition_definitions = deposition_definitions;
}
} // namespace haem
\ No newline at end of file
#ifndef HAEM_HAEMMODEL_CONCENTRATIONCONTROL_HH_
#define HAEM_HAEMMODEL_CONCENTRATIONCONTROL_HH_
#include <string>
#include "haemmodel/control.hh"
#include "haemmodel/emission.hh"
#include "haemmodel/outputgridrequest.hh"
#include "haemmodel/pollutantdefinition.hh"
#include "radixcore/visibility.hh"
namespace haem
{
/**
* HYSPLIT ConcentrationControl
*
* @author mpurves
*/
class RADIX_PUBLIC ConcentrationControl : public Control
{
protected:
std::vector<Emission::SP> m_emissions;
std::vector<OutputGridRequest::SP> m_output_grid_requests;
std::vector<PollutantDefinition::SP> m_deposition_definitions;
public:
typedef std::shared_ptr<ConcentrationControl> SP;
ConcentrationControl();
const std::vector<Emission::SP> &emissions() const;
std::vector<Emission::SP> &emissions();
void setEmissions(const std::vector<Emission::SP> &emissions);
const std::vector<OutputGridRequest::SP> &outputGridRequests() const;
std::vector<OutputGridRequest::SP> &outputGridRequests();
void setOutputGridRequests(
const std::vector<OutputGridRequest::SP> &output_grid_requests);
const std::vector<PollutantDefinition::SP> &depositionDefinitions() const;
std::vector<PollutantDefinition::SP> &depositionDefinitions();
void setDepositionDefinitions(
const std::vector<PollutantDefinition::SP> &deposition_definitions);
}; // class
} // namespace haem
#endif // HAEM_HAEMMODEL_CONCENTRATIONCONTROL_HH_
\ No newline at end of file
#include "haemmodel/concentrationworkflow.hh"
#include "haemmodel/persistencemanager.hh"
#include "radixbug/bug.hh"
namespace haem
{
ConcentrationWorkflow::ConcentrationWorkflow()
: Workflow()
{
m_asc_data = std::make_shared<ASCData>();
m_control = std::make_shared<ConcentrationControl>();
m_setup = std::make_shared<Setup>();
}
std::string ConcentrationWorkflow::concentrationExe() const
{
return m_concentration_exe;
}
void ConcentrationWorkflow::setConcentrationExe(
const std::string &concentration_exe)
{
m_concentration_exe = concentration_exe;
}
ConcentrationControl::SP ConcentrationWorkflow::control() const
{
return m_control;
}
void ConcentrationWorkflow::setControl(const ConcentrationControl::SP &control)
{
m_control = control;
}
void ConcentrationWorkflow::generateInput() const
{
radix_check(m_asc_data.get());
radix_check(!m_asc_data_file_path.empty());
// Write the ASCDATA.CFG file
PersistenceManager::write(*m_asc_data.get(), m_asc_data_file_path);
// Write the SETUP.CFG file
PersistenceManager::write(*m_setup.get(), m_setup_file_path);
// Write the CONTROL file
PersistenceManager::write(*m_control.get(), m_control_file_path);
}
int ConcentrationWorkflow::run() const
{
if (!radix::file_exists(m_asc_data_file_path))
{
throw std::logic_error(
"***Error: Required ASCDATA.CFG file does not exist.");
}
if (!radix::file_exists(m_control_file_path))
{
throw std::logic_error("***Error: Require CONTROL file does not exist.");
}
// Find the hycs_std executable
std::string executable =
radix::to_native_path(m_hysplit_directory + m_concentration_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::string prev_directory;
if (!m_working_directory.empty())
{
radix_line("Setting working directory to: " + m_working_directory);
prev_directory = radix::current_dir();
radix::set_current_dir(m_working_directory);
}
radix_line("SETUP: " << m_setup_file_path);
radix_line("CONTROL: " << m_control_file_path);
radix_line("ASCDATA: " << m_asc_data_file_path);
radix_line("HYSPLIT: " << executable);
int return_code = system(executable.c_str());
int exit_code = return_code;
#ifndef _WIN32
exit_code = exit_code >> 8;
#endif
std::cout << "HYSPLIT Concentration finished (" << exit_code << ")."
<< std::endl;
if (!prev_directory.empty())
{
radix_line("Reverting working directory to: " + prev_directory);
radix::set_current_dir(prev_directory);
}
return exit_code;
}
} // namespace haem
\ No newline at end of file
#ifndef HAEM_HAEMMODEL_CONCENTRATIONWORKFLOW_HH_
#define HAEM_HAEMMODEL_CONCENTRATIONWORKFLOW_HH_
#include <memory>
#include <string>
#include "haemmodel/ascdata.hh"
#include "haemmodel/concentrationcontrol.hh"
#include "haemmodel/setup.hh"
#include "haemmodel/workflow.hh"
#include "radixcore/visibility.hh"
namespace haem
{
/**
* HYSPLIT Concentration Workflow
*
* @author mpurves
*/
class RADIX_PUBLIC ConcentrationWorkflow : public Workflow
{
protected:
std::string m_concentration_exe = "/exec/hycs_std";
ConcentrationControl::SP m_control;
public:
ConcentrationWorkflow();
std::string concentrationExe() const;
void setConcentrationExe(const std::string &concentration_exe);
ConcentrationControl::SP control() const;
void setControl(const ConcentrationControl::SP &control);
void generateInput() const;
int run() const;
}; // class
} // namespace haem
#endif // HAEM_HAEMMODEL_CONCENTRATIONWORKFLOW_HH_
......@@ -46,6 +46,7 @@ class RADIX_PUBLIC Control
void setDomainTop(const size_t &domain_top);
int runtime() const;
void setRuntime(int runtime);
}; // class
} // namespace haem
......
#include "haemmodel/emission.hh"
namespace haem
{
Emission::Emission() {}
std::string Emission::pollutantName() const { return m_pollutant_name; }
void Emission::setPollutantName(const std::string &pollutant_name)
{
m_pollutant_name = pollutant_name;
}
double Emission::emissionRate() const { return m_emission_rate; }
void Emission::setEmissionRate(double emission_rate)
{
m_emission_rate = emission_rate;
}
double Emission::emissionDuration() const { return m_emission_duration; }
void Emission::setEmissionDuration(double emission_duration)
{
m_emission_duration = emission_duration;
}
time Emission::emissionStartTime() const { return m_emission_start_time; }
void Emission::setEmissionStartTime(const time &emission_start_time)
{
m_emission_start_time = emission_start_time;
}
} // namespace haem
\ No newline at end of file
#ifndef HAEM_HAEMMODEL_EMISSION_HH_
#define HAEM_HAEMMODEL_EMISSION_HH_
#include <memory>
#include <string>
#include "haemmodel/time.hh"
namespace haem
{
class Emission
{
public:
typedef std::shared_ptr<Emission> SP;
Emission();
std::string pollutantName() const;
void setPollutantName(const std::string &pollutant_name);
double emissionRate() const;
void setEmissionRate(double emission_rate);
double emissionDuration() const;
void setEmissionDuration(double emission_duration);
time emissionStartTime() const;
void setEmissionStartTime(const time &emission_start_time);
private:
std::string m_pollutant_name;
double m_emission_rate = 0.0;
double m_emission_duration = 0.0;
time m_emission_start_time;
}; // class
} // namespace haem
#endif // HAEM_HAEMMODEL_EMISSION_HH_
\ No newline at end of file
#include "haemmodel/outputgridrequest.hh"
namespace haem
{
OutputGridRequest::OutputGridRequest()
{
m_sample_start_time.year = 0;
m_sample_start_time.month = 0;
m_sample_start_time.day = 0;
m_sample_start_time.hour = 0;
m_sample_start_time.minute = 0;
m_sample_start_time.second = 0;
m_sample_end_time.year = 0;
m_sample_end_time.month = 0;
m_sample_end_time.day = 0;
m_sample_end_time.hour = 0;
m_sample_end_time.minute = 0;
m_sample_end_time.second = 0;
}
std::pair<double, double> OutputGridRequest::gridCenter() const
{
return m_grid_center;
}
void OutputGridRequest::setGridCenter(
const std::pair<double, double> grid_center)
{
m_grid_center = grid_center;
}
std::pair<double, double> OutputGridRequest::gridSpacing() const
{
return m_grid_spacing;
}
void OutputGridRequest::setGridSpacing(
const std::pair<double, double> grid_spacing)
{
m_grid_spacing = grid_spacing;
}
std::pair<double, double> OutputGridRequest::gridSpan() const
{
return m_grid_span;
}
void OutputGridRequest::setGridSpan(const std::pair<double, double> grid_span)
{
m_grid_span = grid_span;
}
std::string OutputGridRequest::gridFileName() const { return m_grid_file_name; }
void OutputGridRequest::setGridFileName(const std::string &grid_file_name)
{
m_grid_file_name = grid_file_name;
}
const std::vector<int> &OutputGridRequest::verticalLevels() const
{
return m_vertical_levels;
}
std::vector<int> &OutputGridRequest::verticalLevels()
{
return m_vertical_levels;
}
void OutputGridRequest::setVerticalLevels(
const std::vector<int> &vertical_levels)
{
m_vertical_levels = vertical_levels;
}
time OutputGridRequest::sampleStartTime() const { return m_sample_start_time; }
void OutputGridRequest::setSampleStartTime(const time &sample_start_time)
{
m_sample_start_time = sample_start_time;
}
time OutputGridRequest::sampleEndTime() const { return m_sample_end_time; }
void OutputGridRequest::setSampleEndTime(const time &sample_end_time)
{
m_sample_end_time = sample_end_time;
}
OutputGridRequest::SampleType OutputGridRequest::sampleType() const
{
return m_sample_type;
}
int OutputGridRequest::sampleTypeInteger() const
{
if (m_sample_type == SampleType::MAXIMUM)
{
return 1;
}
else if (m_sample_type == SampleType::NOW)
{
return 2;
}
else
{
// Default to SampleType::AVERAGE
return 0;
}
}
void OutputGridRequest::setSampleType(SampleType sample_type)
{
m_sample_type = sample_type;
}
int OutputGridRequest::sampleIntervalHours() const
{
return m_sample_interval_hours;
}
int OutputGridRequest::sampleIntervalMinutes() const
{
return m_sample_interval_minutes;
}
void OutputGridRequest::setSampleIntervalHours(int sample_interval_hours)
{
m_sample_interval_hours = sample_interval_hours;
}
void OutputGridRequest::setSampleIntervalMinutes(int sample_interval_minutes)
{
m_sample_interval_minutes = sample_interval_minutes;
}
void OutputGridRequest::setSampleInterval(int sample_interval_hours,
int sample_interval_minutes)
{
m_sample_interval_hours = sample_interval_hours;
m_sample_interval_minutes = sample_interval_minutes;
}
} // namespace haem
\ No newline at end of file
#ifndef HAEM_HAEMMODEL_OUTPUTGRIDREQUEST_HH_
#define HAEM_HAEMMODEL_OUTPUTGRIDREQUEST_HH_
#include <memory>
#include <string>
#include <vector>
#include "haemmodel/time.hh"
namespace haem
{
class OutputGridRequest
{
public:
typedef std::shared_ptr<OutputGridRequest> SP;
enum SampleType
{
AVERAGE,
NOW,
MAXIMUM
};
OutputGridRequest();
std::pair<double, double> gridCenter() const;
void setGridCenter(const std::pair<double, double> grid_center);
std::pair<double, double> gridSpacing() const;
void setGridSpacing(const std::pair<double, double> grid_spacing);
std::pair<double, double> gridSpan() const;
void setGridSpan(const std::pair<double, double> grid_span);
std::string gridFileName() const;
void setGridFileName(const std::string &grid_file_name);
const std::vector<int> &verticalLevels() const;
std::vector<int> &verticalLevels();
void setVerticalLevels(const std::vector<int> &vertical_levels);
time sampleStartTime() const;
void setSampleStartTime(const time &sample_start_time);
time sampleEndTime() const;
void setSampleEndTime(const time &sample_end_time);
SampleType sampleType() const;
int sampleTypeInteger() const;
void setSampleType(SampleType sample_type);
int sampleIntervalHours() const;
int sampleIntervalMinutes() const;
void setSampleIntervalHours(int sample_interval_hours);
void setSampleIntervalMinutes(int sample_interval_minutes);
void setSampleInterval(int sample_interval_hours,
int sample_interval_minutes);
private:
std::pair<double, double> m_grid_center =
std::make_pair<double, double>(0.0, 0.0);
std::pair<double, double> m_grid_spacing =
std::make_pair<double, double>(0.025, 0.025);
std::pair<double, double> m_grid_span =
std::make_pair<double, double>(20.0, 20.0);
std::string m_grid_file_name = "./cdump";
std::vector<int> m_vertical_levels;
time m_sample_start_time;
time m_sample_end_time;
SampleType m_sample_type = SampleType::AVERAGE;
int m_sample_interval_hours = 1;
int m_sample_interval_minutes = 0;
}; // class
} // namespace haem
#endif // HAEM_HAEMMODEL_OUTPUTGRIDREQUEST_HH_
\ No newline at end of file
......@@ -79,6 +79,122 @@ void PersistenceManager::write(const TrajectoryControl &data,
fclose(os);
}
void PersistenceManager::write(const ConcentrationControl &data,
const std::string &file)
{
FILE *os = nullptr;
os = fopen(file.c_str(), "w");
if (!os)
{
throw std::runtime_error(std::string("***Error: Failed to open file: ") +
file);
}
time start = data.startTime();
// First record
fprintf(os, "%02d %02d %02d %02d %02d # Starting date/time\n",
start.year2digit(), start.month, start.day, start.hour, start.minute);
const std::vector<radix::Point3D> &points = data.points();
// Second record
fprintf(os, "%ld # number of locations\n", points.size());
// Record for each starting position
for (const auto &point : points)
{
fprintf(os, "%f %f %f # lat lon z-msl\n", point.y, point.x, point.z);
}
// runtime record
fprintf(os, "%d # number of hours\n", data.runtime());
// use vertical velocity record
fprintf(os, "%d # use vertical vel\n", data.useVerticalVelocity());
// top of domain record
fprintf(os, "%ld # top of domain\n", data.domainTop());
Meteorology::SP met = data.meteorology();
const std::vector<std::string> &met_files = met->paths();
//
// Number of files
fprintf(os, "%ld\n", met_files.size());
for (const auto &file : met_files)
{
std::string dir = radix::to_native_path(radix::dirname(file) + "/");
std::string basename = radix::basename(file);
fprintf(os, "%s\n", dir.c_str());
fprintf(os, "%s\n", basename.c_str());
}
// Concentration specific section
// Pollutants
const std::vector<Emission::SP> pollutants = data.emissions();
fprintf(os, "%ld\n", pollutants.size());
for (const auto &pollutant : pollutants)
{
fprintf(os, "%s\n", pollutant->pollutantName().c_str());
fprintf(os, "%f\n", pollutant->emissionRate());
fprintf(os, "%f\n", pollutant->emissionDuration());
time emission_start = pollutant->emissionStartTime();
fprintf(os, "%02d %02d %02d %02d %02d\n", emission_start.year2digit(),
emission_start.month, emission_start.day, emission_start.hour,
emission_start.minute);
}
// Output grids
const std::vector<OutputGridRequest::SP> output_grid_requests =
data.outputGridRequests();
fprintf(os, "%ld\n", output_grid_requests.size());
for (const auto &grid : output_grid_requests)
{
fprintf(os, "%f %f\n", grid->gridCenter().first, grid->gridCenter().second);
fprintf(os, "%f %f\n", grid->gridSpacing().first,
grid->gridSpacing().second);
fprintf(os, "%f %f\n", grid->gridSpan().first, grid->gridSpan().second);
std::string dir =
radix::to_native_path(radix::dirname(grid->gridFileName()) + "/");
std::string basename = radix::basename(grid->gridFileName());
fprintf(os, "%s\n", dir.c_str());
fprintf(os, "%s\n", basename.c_str());
// Vertical levels
fprintf(os, "%ld\n", grid->verticalLevels().size());
for (const auto &level : grid->verticalLevels())
{
fprintf(os, "%d ", level);
}
fprintf(os, "\n");
time sample_start = grid->sampleStartTime();
fprintf(os, "%02d %02d %02d %02d %02d\n", sample_start.year2digit(),
sample_start.month, sample_start.day, sample_start.hour,
sample_start.minute);
time sample_end = grid->sampleEndTime();
fprintf(os, "%02d %02d %02d %02d %02d\n", sample_end.year2digit(),
sample_end.month, sample_end.day, sample_end.hour,
sample_end.minute);
fprintf(os, "%d %d %d\n", grid->sampleTypeInteger(),
grid->sampleIntervalHours(), grid->sampleIntervalMinutes());
}
// Deposition definitions
const std::vector<PollutantDefinition::SP> depositions =
data.depositionDefinitions();
fprintf(os, "%ld\n", depositions.size());
for (const auto &deposition : depositions)
{
fprintf(os, "%f %f %f\n", deposition->diameter(), deposition->density(),
deposition->shape());
fprintf(os, "%f %f %f %f %f\n", deposition->depositionVelocity(),
deposition->molecularWeight(), deposition->aRatio(),
deposition->dRatio(), deposition->henry());
fprintf(os, "%f %g %g\n", deposition->henrys(), deposition->inCloud(),
deposition->belowCloud());
fprintf(os, "%f\n", deposition->radioactiveHalfLife());
fprintf(os, "%f\n", deposition->resuspensionFactor());
}
fprintf(os, "\n");
fclose(os);
}
void PersistenceManager::write(const Setup &data, const std::string &file)
{
FILE *os = nullptr;
......
......@@ -2,6 +2,7 @@
#define HAEM_HAEMMODEL_PERSISTENCEMANAGER_HH_
#include "haemmodel/ascdata.hh"
#include "haemmodel/concentrationcontrol.hh"
#include "haemmodel/setup.hh"
#include "haemmodel/trajectorycontrol.hh"
......@@ -14,6 +15,7 @@ class RADIX_PUBLIC PersistenceManager
public:
static void write(const ASCData &data, const std::string &file);
static void write(const TrajectoryControl &data, const std::string &file);
static void write(const ConcentrationControl &data, const std::string &file);
static void write(const Setup &data, const std::string &file);
}; // class
......
#include "haemmodel/pollutantdefinition.hh"
namespace haem
{
PollutantDefinition::PollutantDefinition() {}
double PollutantDefinition::diameter() const { return m_diameter; }
void PollutantDefinition::setDiameter(double diameter)
{
m_diameter = diameter;
}
double PollutantDefinition::density() const { return m_density; }
void PollutantDefinition::setDensity(double density) { m_density = density; }
double PollutantDefinition::shape() const { return m_shape; }
void PollutantDefinition::setShape(double shape) { m_shape = shape; }
double PollutantDefinition::depositionVelocity() const
{
return m_deposition_velocity;
}
void PollutantDefinition::setDepositionVelocity(double deposition_velocity)
{
m_deposition_velocity = deposition_velocity;
}
double PollutantDefinition::molecularWeight() const
{
return m_molecular_weight;
}
void PollutantDefinition::setMolecularWeight(double molecular_weight)
{
m_molecular_weight = molecular_weight;
}
double PollutantDefinition::aRatio() const { return m_a_ratio; }
void PollutantDefinition::setARatio(double a_ratio) { m_a_ratio = a_ratio; }
double PollutantDefinition::dRatio() const { return m_d_ratio; }
void PollutantDefinition::setDRatio(double d_ratio) { m_d_ratio = d_ratio; }
double PollutantDefinition::henry() const { return m_henry; }
void PollutantDefinition::setHenry(double henry) { m_henry = henry; }
double PollutantDefinition::henrys() const { return m_henrys; }
void PollutantDefinition::setHenrys(double henrys) { m_henrys = henrys; }
double PollutantDefinition::inCloud() const { return m_in_cloud; }
void PollutantDefinition::setInCloud(double in_cloud) { m_in_cloud = in_cloud; }
double PollutantDefinition::belowCloud() const { return m_below_cloud; }
void PollutantDefinition::setBelowCloud(double below_cloud)
{
m_below_cloud = below_cloud;
}
double PollutantDefinition::radioactiveHalfLife() const
{
return m_radioactive_half_life;
}
void PollutantDefinition::setRadioactiveHalfLife(double radioactive_half_life)
{
m_radioactive_half_life = radioactive_half_life;
}
double PollutantDefinition::resuspensionFactor() const
{
return m_resuspension_factor;
}
void PollutantDefinition::setResuspensionFactor(double resuspension_factor)
{
m_resuspension_factor = resuspension_factor;
}
} // namespace haem
\ No newline at end of file
#ifndef HAEM_HAEMMODEL_POLLUTANTDEFINITION_HH_
#define HAEM_HAEMMODEL_POLLUTANTDEFINITION_HH_
#include <memory>
namespace haem
{
class PollutantDefinition
{
public:
typedef std::shared_ptr<PollutantDefinition> SP;
PollutantDefinition();
double diameter() const;
void setDiameter(double diameter);
double density() const;
void setDensity(double density);
double shape() const;
void setShape(double shape);
double depositionVelocity() const;
void setDepositionVelocity(double deposition_velocity);
double molecularWeight() const;
void setMolecularWeight(double molecular_weight);
double aRatio() const;
void setARatio(double a_ratio);
double dRatio() const;
void setDRatio(double d_ratio);
double henry() const;
void setHenry(double henry);
double henrys() const;
void setHenrys(double henrys);
double inCloud() const;
void setInCloud(double in_cloud);
double belowCloud() const;
void setBelowCloud(double below_cloud);
double radioactiveHalfLife() const;
void setRadioactiveHalfLife(double radioactive_half_life);
double resuspensionFactor() const;
void setResuspensionFactor(double resuspension_factor);
private:
double m_diameter = 2.5;
double m_density = 2.0;
double m_shape = 1.0;
double m_deposition_velocity = 0.006;
double m_molecular_weight = 0.0;
double m_a_ratio = 0.0;
double m_d_ratio = 0.0;
double m_henry = 0.0;
double m_henrys = 0.0;
double m_in_cloud = 8.0E-5;
double m_below_cloud = 8.0E-5;
double m_radioactive_half_life = 0.0;
double m_resuspension_factor = 0.0;
}; // class
} // namespace haem
#endif // HAEM_HAEMMODEL_POLLUTANTDEFINITION_HH_
\ No newline at end of file
......@@ -28,6 +28,7 @@ class RADIX_PUBLIC TrajectoryControl : public Control
std::string outputFile() const;
void setOutputFile(const std::string &output_file);
}; // class
} // namespace haem
......
......@@ -6,24 +6,6 @@
namespace haem
{
std::string TrajectoryWorkflow::ascDataFilePath() const
{
return m_asc_data_file_path;
}
void TrajectoryWorkflow::setAscDataFilePath(
const std::string &asc_data_file_path)
{
m_asc_data_file_path = asc_data_file_path;
}
ASCData::SP TrajectoryWorkflow::ascData() const { return m_asc_data; }
void TrajectoryWorkflow::setAscData(const ASCData::SP &asc_data)
{
m_asc_data = asc_data;
}
TrajectoryControl::SP TrajectoryWorkflow::control() const { return m_control; }
void TrajectoryWorkflow::setControl(const TrajectoryControl::SP &control)
......@@ -31,28 +13,6 @@ void TrajectoryWorkflow::setControl(const TrajectoryControl::SP &control)
m_control = control;
}
std::string TrajectoryWorkflow::controlFilePath() const
{
return m_control_file_path;
}
void TrajectoryWorkflow::setControlFilePath(
const std::string &control_file_path)
{
m_control_file_path = control_file_path;
}
std::string TrajectoryWorkflow::hysplitDirectory() const
{
return m_hysplit_directory;
}
void TrajectoryWorkflow::setHysplitDirectory(
const std::string &hysplit_directory)
{
m_hysplit_directory = hysplit_directory;
}
std::string TrajectoryWorkflow::trajectoryExe() const
{
return m_trajectory_exe;
......@@ -76,31 +36,16 @@ void TrajectoryWorkflow::processOutput()
TrajectoryOutput::SP TrajectoryWorkflow::output() const { return m_output; }
Setup::SP TrajectoryWorkflow::setup() const { return m_setup; }
void TrajectoryWorkflow::setSetup(const Setup::SP &setup) { m_setup = setup; }
std::string TrajectoryWorkflow::setupFilePath() const
{
return m_setup_file_path;
}
void TrajectoryWorkflow::setSetupFilePath(const std::string &setup_file_path)
{
m_setup_file_path = setup_file_path;
}
TrajectoryWorkflow::TrajectoryWorkflow()
: Workflow()
{
m_asc_data = std::make_shared<ASCData>();
m_control = std::make_shared<TrajectoryControl>();
m_output = std::make_shared<TrajectoryOutput>();
m_setup = std::make_shared<Setup>();
m_control = std::make_shared<TrajectoryControl>();
m_output = std::make_shared<TrajectoryOutput>();
}
void TrajectoryWorkflow::generateInput() const
{
radix_check(m_ask_data.get());
radix_check(m_asc_data.get());
radix_check(!m_asc_data_file_path.empty());
//
// Write HYSPLIT's ASCDATA.CFG file
......@@ -110,7 +55,7 @@ void TrajectoryWorkflow::generateInput() const
PersistenceManager::write(*m_setup.get(), m_setup_file_path);
//
// Write
// Write HYSPLIT's CONTROL file
const std::vector<radix::Point3D> &points = m_control->points();
if (points.size() < 1)
{
......@@ -123,7 +68,7 @@ void TrajectoryWorkflow::generateInput() const
PersistenceManager::write(*m_control.get(), m_control_file_path);
}
void TrajectoryWorkflow::run() const
int TrajectoryWorkflow::run() const
{
if (radix::file_exists(m_asc_data_file_path) == false)
{
......@@ -147,6 +92,14 @@ void TrajectoryWorkflow::run() const
throw std::logic_error("***Error: Failed to find '" + executable + "'");
}
std::string prev_directory;
if (!m_working_directory.empty())
{
radix_line("Setting working directory to: " + m_working_directory);
prev_directory = radix::current_dir();
radix::set_current_dir(m_working_directory);
}
int return_code = system(executable.c_str());
int exit_code = return_code;
#ifndef _WIN32
......@@ -155,6 +108,14 @@ void TrajectoryWorkflow::run() const
std::cout << "HYSPLIT Trajectory finished (" << exit_code << ")."
<< std::endl;
if (!prev_directory.empty())
{
radix_line("Reverting working directory to: " + prev_directory);
radix::set_current_dir(prev_directory);
}
return exit_code;
}
} // namespace haem
......@@ -10,6 +10,7 @@
#include "haemmodel/setup.hh"
#include "haemmodel/trajectorycontrol.hh"
#include "haemmodel/trajectoryoutput.hh"
#include "haemmodel/workflow.hh"
#include "radixbug/bug.hh"
#include "radixcore/system.hh"
......@@ -18,31 +19,19 @@
namespace haem
{
/**
* HYSPLIT Workflow
* HYSPLIT Trajectory Workflow
*
* @author jap
*/
class RADIX_PUBLIC TrajectoryWorkflow
class RADIX_PUBLIC TrajectoryWorkflow : public Workflow
{
protected:
std::string m_asc_data_file_path = "ASCDATA.CFG";
std::string m_control_file_path = "CONTROL";
std::string m_setup_file_path = "SETUP.CFG";
std::string m_hysplit_directory;
std::string m_trajectory_exe = "/exec/hyts_std";
ASCData::SP m_asc_data;
TrajectoryControl::SP m_control;
TrajectoryOutput::SP m_output;
Setup::SP m_setup;
public:
TrajectoryWorkflow();
......@@ -54,40 +43,11 @@ class RADIX_PUBLIC TrajectoryWorkflow
/**
* @brief run Executes the HYSPLIT trajectory capability
*/
void run() const;
/**
* @brief ascDataFilePath Get the file path for the ASCDATA.CFG
* @return std::string
*/
std::string ascDataFilePath() const;
/**
* @brief setAscDataFilePath Set the file path for the ASCDATA.CFG
* Required file name be ASCDATA.CFG
* @param asc_data_file_path
*/
void setAscDataFilePath(const std::string &asc_data_file_path);
int run() const;
std::string controlFilePath() const;
void setControlFilePath(const std::string &control_file_path);
std::string setupFilePath() const;
void setSetupFilePath(const std::string &setup_file_path);
/**
* @brief ascData Get the HYSPLIT ASC Data
* @return
*/
ASCData::SP ascData() const;
void setAscData(const ASCData::SP &asc_data);
TrajectoryControl::SP control() const;
void setControl(const TrajectoryControl::SP &control);
Setup::SP setup() const;
void setSetup(const Setup::SP &setup);
std::string hysplitDirectory() const;
void setHysplitDirectory(const std::string &hysplit_directory);
std::string trajectoryExe() const;
/**
* @brief setTrajectoryExe Set the trajectory executable path
......
#include <memory>
#include "haemmodel/persistencemanager.hh"
#include "haemmodel/workflow.hh"
namespace haem
{
std::string Workflow::ascDataFilePath() const { return m_asc_data_file_path; }
void Workflow::setAscDataFilePath(const std::string &asc_data_file_path)
{
m_asc_data_file_path = asc_data_file_path;
}
ASCData::SP Workflow::ascData() const { return m_asc_data; }
void Workflow::setAscData(const ASCData::SP &asc_data)
{
m_asc_data = asc_data;
}
std::string Workflow::hysplitDirectory() const { return m_hysplit_directory; }
void Workflow::setHysplitDirectory(const std::string &hysplit_directory)
{
m_hysplit_directory = hysplit_directory;
}
std::string Workflow::workingDirectory() const { return m_working_directory; }
void Workflow::setWorkingDirectory(const std::string &working_directory)
{
m_working_directory = working_directory;
}
Setup::SP Workflow::setup() const { return m_setup; }
void Workflow::setSetup(const Setup::SP &setup) { m_setup = setup; }
std::string Workflow::controlFilePath() const { return m_control_file_path; }
void Workflow::setControlFilePath(const std::string &control_file_path)
{
m_control_file_path = control_file_path;
}
std::string Workflow::setupFilePath() const { return m_setup_file_path; }
void Workflow::setSetupFilePath(const std::string &setup_file_path)
{
m_setup_file_path = setup_file_path;
}
Workflow::Workflow()
{
m_asc_data = std::make_shared<ASCData>();
m_setup = std::make_shared<Setup>();
}
} // namespace haem
#ifndef HAEM_HAEMMODEL_WORKFLOW_HH_
#define HAEM_HAEMMODEL_WORKFLOW_HH_
#include <array>
#include <memory>
#include <string>
#include <vector>
#include "haemmodel/ascdata.hh"
#include "haemmodel/setup.hh"
#include "haemmodel/trajectorycontrol.hh"
#include "haemmodel/trajectoryoutput.hh"
#include "radixbug/bug.hh"
#include "radixcore/system.hh"
#include "radixcore/visibility.hh"
namespace haem
{
/**
* HYSPLIT Workflow
*
* @author jap
*/
class RADIX_PUBLIC Workflow
{
protected:
std::string m_asc_data_file_path = "ASCDATA.CFG";
std::string m_control_file_path = "CONTROL";
std::string m_setup_file_path = "SETUP.CFG";
std::string m_hysplit_directory;
std::string m_working_directory;
ASCData::SP m_asc_data;
Setup::SP m_setup;
public:
Workflow();
/**
* @brief ascDataFilePath Get the file path for the ASCDATA.CFG
* @return std::string
*/
std::string ascDataFilePath() const;
/**
* @brief setAscDataFilePath Set the file path for the ASCDATA.CFG
* Required file name be ASCDATA.CFG
* @param asc_data_file_path
*/
void setAscDataFilePath(const std::string &asc_data_file_path);
std::string controlFilePath() const;
void setControlFilePath(const std::string &control_file_path);
std::string setupFilePath() const;
void setSetupFilePath(const std::string &setup_file_path);
/**
* @brief ascData Get the HYSPLIT ASC Data
* @return
*/
ASCData::SP ascData() const;
void setAscData(const ASCData::SP &asc_data);
Setup::SP setup() const;
void setSetup(const Setup::SP &setup);
std::string hysplitDirectory() const;
void setHysplitDirectory(const std::string &hysplit_directory);
std::string workingDirectory() const;
void setWorkingDirectory(const std::string &working_directory);
// Input generator/run abstract methods
virtual void generateInput() const = 0;
virtual int run() const = 0;
}; // class
} // namespace haem
#endif /** HAEM_HAEMMODEL_WORKFLOW_HH_ */