diff --git a/src/motions/base.cpp b/src/motions/base.cpp index 4b36f8e..992d6f1 100644 --- a/src/motions/base.cpp +++ b/src/motions/base.cpp @@ -7,6 +7,7 @@ #include "tetrahedral.h" #include +#include Motion::Motion(std::string name, const double delta, const double eta, std::mt19937_64& rng) : m_name(std::move(name)), m_delta(delta), m_eta(eta), m_rng(rng) { m_uni_dist = std::uniform_real_distribution(0., 1.); @@ -57,6 +58,12 @@ void Motion::setParameters(const std::unordered_map ¶me m_eta = parameters.at("eta"); } +std::unordered_map Motion::getParameters() const { + return std::unordered_map{ + {"delta", m_delta}, + {"eta", m_eta} + }; +} std::ostream& operator<<(std::ostream& os, const Motion& m) { os << m.getName(); diff --git a/src/motions/base.h b/src/motions/base.h index bd5056f..fc5cc1a 100644 --- a/src/motions/base.h +++ b/src/motions/base.h @@ -21,7 +21,7 @@ public: virtual double jump() = 0; virtual void setParameters(const std::unordered_map&); - + [[nodiscard]] virtual std::unordered_map getParameters() const; [[nodiscard]] double getDelta() const { return m_delta; } void setDelta(const double delta) { m_delta = delta; } [[nodiscard]] double getEta() const { return m_eta; } @@ -29,6 +29,8 @@ public: [[nodiscard]] std::string getName() const { return m_name; } [[nodiscard]] double getInitOmega() const { return m_initial_omega; }; + [[nodiscard]] virtual std::string toString() const = 0; + static Motion* createFromInput(const std::string& input, std::mt19937_64& rng); protected: diff --git a/src/motions/bimodalangle.cpp b/src/motions/bimodalangle.cpp index cf0952f..f0f55b7 100644 --- a/src/motions/bimodalangle.cpp +++ b/src/motions/bimodalangle.cpp @@ -29,3 +29,15 @@ void BimodalAngle::setParameters(const std::unordered_map & m_angle2 = parameter.at("angle2") * M_PI / 180.; m_prob = parameter.at("probability1"); } + +std::unordered_map BimodalAngle::getParameters() const { + auto parameter = Motion::getParameters(); + parameter["angle1"] = m_angle1 * 180 / M_PI; + parameter["angle2"] = m_angle2 * 180 / M_PI; + parameter["probality1"] = m_prob; + return parameter; +} + +std::string BimodalAngle::toString() const { + return std::string{"BimodalAngle/angle1=" + std::to_string(m_angle1 * 180 / M_PI) + "/angle2=" + std::to_string(m_angle2 * 180 / M_PI) + "/probability1=" + std::to_string(m_prob)}; +} diff --git a/src/motions/bimodalangle.h b/src/motions/bimodalangle.h index a46afb7..8df624a 100644 --- a/src/motions/bimodalangle.h +++ b/src/motions/bimodalangle.h @@ -12,6 +12,8 @@ public: void initialize() override; double jump() override; void setParameters(const std::unordered_map &) override; + [[nodiscard]] std::unordered_map getParameters() const override; + [[nodiscard]] std::string toString() const override; protected: double m_angle1{0}; diff --git a/src/motions/isosmallangle.cpp b/src/motions/isosmallangle.cpp index b633e92..8fb815f 100644 --- a/src/motions/isosmallangle.cpp +++ b/src/motions/isosmallangle.cpp @@ -25,3 +25,13 @@ void SmallAngle::setParameters(const std::unordered_map &pa m_chi = parameters.at("angle") * M_PI / 180.0; Motion::setParameters(parameters); } + +std::unordered_map SmallAngle::getParameters() const { + auto parameter = Motion::getParameters(); + parameter["angle"] = m_chi * 180 / M_PI; + return parameter; +} + +std::string SmallAngle::toString() const { + return std::string{"IsotropicAngle/angle=" + std::to_string(m_chi * 180 / M_PI)}; +} diff --git a/src/motions/isosmallangle.h b/src/motions/isosmallangle.h index 0f26130..66f805e 100644 --- a/src/motions/isosmallangle.h +++ b/src/motions/isosmallangle.h @@ -13,6 +13,8 @@ public: void initialize() override; double jump() override; void setParameters(const std::unordered_map &) override; + [[nodiscard]] std::unordered_map getParameters() const override; + [[nodiscard]] std::string toString() const override; private: double m_chi{0}; diff --git a/src/motions/random.cpp b/src/motions/random.cpp index 5139241..8a2f52f 100644 --- a/src/motions/random.cpp +++ b/src/motions/random.cpp @@ -6,6 +6,10 @@ RandomJump::RandomJump(const double delta, const double eta, std::mt19937_64 &rn RandomJump::RandomJump(std::mt19937_64 &rng) : Motion(std::string("RandomJump"), rng) {} +std::string RandomJump::toString() const { + return {"RandomJump"}; +} + void RandomJump::initialize() { m_initial_omega = RandomJump::jump(); } diff --git a/src/motions/random.h b/src/motions/random.h index eca43e0..82e4c64 100644 --- a/src/motions/random.h +++ b/src/motions/random.h @@ -10,6 +10,8 @@ public: RandomJump(double, double, std::mt19937_64&); explicit RandomJump(std::mt19937_64&); + [[nodiscard]] std::string toString() const override; + void initialize() override; double jump() override; }; diff --git a/src/motions/tetrahedral.cpp b/src/motions/tetrahedral.cpp index c9ef5c5..8dfea40 100644 --- a/src/motions/tetrahedral.cpp +++ b/src/motions/tetrahedral.cpp @@ -28,3 +28,7 @@ double TetrahedralJump::jump() { return m_corners[m_corner_idx]; } + +std::string TetrahedralJump::toString() const { + return {"FourSiteTetrahedral"}; +} diff --git a/src/motions/tetrahedral.h b/src/motions/tetrahedral.h index 1872b0e..8c07c77 100644 --- a/src/motions/tetrahedral.h +++ b/src/motions/tetrahedral.h @@ -14,6 +14,8 @@ public: void initialize() override; double jump() override; + [[nodiscard]] std::string toString() const override; + private: const double m_beta{std::acos(-1/3.)}; @@ -24,5 +26,4 @@ private: }; - #endif //RWSIM_MOTIONTETRAHEDRAL_H diff --git a/src/simulation/sims.cpp b/src/simulation/sims.cpp index e6adf20..77b3dc6 100644 --- a/src/simulation/sims.cpp +++ b/src/simulation/sims.cpp @@ -72,8 +72,9 @@ void run_spectrum( } // write fid to files - save_parameter_to_file("timesignal", motion.getName(), dist.getName(), parameter, optional); - save_data_to_file("timesignal", motion.getName(), dist.getName(), t_fid, fid_dict, optional); + const auto path = make_directory(motion, dist); + save_parameter_to_file(std::string("timesignal"), path, parameter, optional); + save_data_to_file(std::string("timesignal"), path, t_fid, fid_dict, optional); printEnd(start); } @@ -163,10 +164,11 @@ void run_ste( } // write to files - save_parameter_to_file("ste", motion.getName(), dist.getName(), parameter, optional); - save_data_to_file("coscos", motion.getName(), dist.getName(), mixing_times, cc_dict, optional); - save_data_to_file("sinsin", motion.getName(), dist.getName(), mixing_times, ss_dict, optional); - save_data_to_file("f2", motion.getName(), dist.getName(), mixing_times, f2, optional); + const auto folders = make_directory(motion, dist); + save_parameter_to_file(std::string("ste"), folders, parameter, optional); + save_data_to_file(std::string("coscos"), folders, mixing_times, cc_dict, optional); + save_data_to_file(std::string("sinsin"), folders, mixing_times, ss_dict, optional); + save_data_to_file(std::string("f2"), folders, mixing_times, f2, optional); printEnd(start); } diff --git a/src/times/base.cpp b/src/times/base.cpp index bd6f993..1d36462 100644 --- a/src/times/base.cpp +++ b/src/times/base.cpp @@ -16,6 +16,13 @@ void Distribution::setParameters(const std::unordered_map & m_tau = parameters.at("tau"); } +std::unordered_map Distribution::getParameters() const { + return std::unordered_map{ + {"tau", m_tau}, + }; +} + + Distribution* Distribution::createFromInput(const std::string& input, std::mt19937_64& rng) { if (input == "Delta") return new DeltaDistribution(rng); diff --git a/src/times/base.h b/src/times/base.h index 4fa08bb..b826798 100644 --- a/src/times/base.h +++ b/src/times/base.h @@ -16,11 +16,14 @@ public: [[nodiscard]] std::string getName() const { return m_name; }; virtual void setParameters(const std::unordered_map&); + [[nodiscard]] virtual std::unordered_map getParameters() const; virtual void initialize() = 0; virtual void draw_tau() = 0; [[nodiscard]] double tau_wait() const; + [[nodiscard]] virtual std::string toString() const = 0; + static Distribution* createFromInput(const std::string& input, std::mt19937_64& rng); protected: diff --git a/src/times/delta.cpp b/src/times/delta.cpp index 9946ff7..f8201e8 100644 --- a/src/times/delta.cpp +++ b/src/times/delta.cpp @@ -9,3 +9,7 @@ void DeltaDistribution::initialize() { void DeltaDistribution::draw_tau() {} +std::string DeltaDistribution::toString() const { + return {"Delta/tau=" + std::to_string(m_tau)}; +} + diff --git a/src/times/delta.h b/src/times/delta.h index 463fefc..4b0b35a 100644 --- a/src/times/delta.h +++ b/src/times/delta.h @@ -10,6 +10,8 @@ public: void initialize() override; void draw_tau() override; + + [[nodiscard]] std::string toString() const override; }; #endif //RWSIM_TIMESDELTA_H diff --git a/src/times/lognormal.cpp b/src/times/lognormal.cpp index e6c2b5a..43fa0d2 100644 --- a/src/times/lognormal.cpp +++ b/src/times/lognormal.cpp @@ -9,6 +9,12 @@ void LogNormalDistribution::setParameters(const std::unordered_map LogNormalDistribution::getParameters() const { + auto parameter = Distribution::getParameters(); + parameter["sigma"] = m_sigma; + return parameter; +} + void LogNormalDistribution::initialize() { m_distribution = std::lognormal_distribution(std::log(m_tau), m_sigma); m_tau_jump = m_distribution(m_rng); @@ -17,3 +23,7 @@ void LogNormalDistribution::initialize() { void LogNormalDistribution::draw_tau() { m_tau_jump = m_distribution(m_rng); } + +std::string LogNormalDistribution::toString() const { + return {"LogNormal/tau=" + std::to_string(m_tau) + "/sigma=" + std::to_string(m_sigma)}; +} diff --git a/src/times/lognormal.h b/src/times/lognormal.h index da89503..e41e984 100644 --- a/src/times/lognormal.h +++ b/src/times/lognormal.h @@ -3,7 +3,6 @@ #include "base.h" #include -#include class LogNormalDistribution final : public Distribution { public: @@ -11,6 +10,9 @@ public: explicit LogNormalDistribution(std::mt19937_64 &rng); void setParameters(const std::unordered_map &) override; + [[nodiscard]] std::unordered_map getParameters() const override; + + [[nodiscard]] std::string toString() const override; void initialize() override; void draw_tau() override; diff --git a/src/utils/io.cpp b/src/utils/io.cpp index c9875c5..0dd5740 100644 --- a/src/utils/io.cpp +++ b/src/utils/io.cpp @@ -7,11 +7,15 @@ #include #include #include -#include #include #include #include +#include "../motions/base.h" +#include "../times/base.h" + + +class Motion; std::pair get_optional_parameter(std::vector::const_iterator &it) { std::string stripped_arg; @@ -124,16 +128,30 @@ std::unordered_map read_parameter(const std::filesystem::pa } +std::string make_directory( + const Motion& motion, + const Distribution& distribution + ) { + std::ostringstream path_name; + path_name << motion.toString() << "/" << distribution.toString(); + + if (!std::filesystem::create_directories(path_name.str())) { + std::cout << "Created directory " << path_name.str() << std::endl; + } + + + return path_name.str(); +} + + void save_parameter_to_file( const std::string& resulttype, - const std::string& motiontype, - const std::string& disttype, - std::unordered_map& parameter, - std::unordered_map& optional + const std::string& directory, + const std::unordered_map& parameter, + const std::unordered_map& optional ) { - std::ostringstream parameter_filename; - parameter_filename << resulttype << "_" << motiontype << "_" << disttype; + parameter_filename << directory << "/" << resulttype; parameter_filename << std::setprecision(6) << std::scientific; for (const auto& [key, value]: optional) { @@ -155,15 +173,15 @@ void save_parameter_to_file( void save_data_to_file( const std::string& resulttype, - const std::string& motiontype, - const std::string& disttype, + const std::string& directory, const std::vector& x, const std::map>& y, - std::unordered_map& optional + const std::unordered_map& optional ) { // make file name std::ostringstream datafile_name; - datafile_name << resulttype << "_" << motiontype << "_" << disttype; + datafile_name << directory << "/" << resulttype; + datafile_name << std::setprecision(6) << std::scientific; for (const auto& [key, value]: optional) { datafile_name << "_" << key << "=" << value; @@ -196,15 +214,15 @@ void save_data_to_file( void save_data_to_file( const std::string& resulttype, - const std::string& motiontype, - const std::string& disttype, + const std::string& directory, const std::vector& x, const std::vector& y, - std::unordered_map& optional + const std::unordered_map& optional ) { // make file name std::ostringstream datafile_name; - datafile_name << resulttype << "_" << motiontype << "_" << disttype; + datafile_name << directory << "/" << resulttype; + datafile_name << std::setprecision(6) << std::scientific; for (const auto& [key, value]: optional) { datafile_name << "_" << key << "=" << value; diff --git a/src/utils/io.h b/src/utils/io.h index 525f494..772a52e 100644 --- a/src/utils/io.h +++ b/src/utils/io.h @@ -7,6 +7,9 @@ #include #include +#include "../motions/base.h" +#include "../times/base.h" + struct Arguments { std::string parameter_file{}; bool ste = false; @@ -18,12 +21,12 @@ struct Arguments { Arguments parse_args(int argc, char* argv[]); std::pair get_optional_parameter(std::vector::const_iterator &it); - std::unordered_map read_parameter(const std::filesystem::path&); +std::string make_directory(const Motion&, const Distribution&); -void save_parameter_to_file(const std::string&, const std::string&, const std::string&, std::unordered_map&, std::unordered_map&); -void save_data_to_file(const std::string&, const std::string&, const std::string&, const std::vector&, const std::map>&, std::unordered_map&); -void save_data_to_file(const std::string&, const std::string&, const std::string&, const std::vector&, const std::vector&, std::unordered_map&); +void save_parameter_to_file(const std::string&, const std::string&, const std::unordered_map&, const std::unordered_map&); +void save_data_to_file(const std::string&, const std::string&, const std::vector&, const std::map>&, const std::unordered_map&); +void save_data_to_file(const std::string&, const std::string&, const std::vector&, const std::vector&, const std::unordered_map&); #endif