ARTS 2.5.11 (git: 725533f0)
artstime.cc
Go to the documentation of this file.
1
9#include "artstime.h"
10#include "arts_options.h"
11#include <cstdlib>
12#include <ctime>
13
14Time::Time(const String& t) {
15 auto s = std::istringstream(t);
16 s >> *this;
17}
18
20{
21 std::istringstream x(time_step);
22 Index length;
23 String type;
24 x >> length >> type;
25 type.tolower();
26
27 const Options::TimeStep t = Options::toTimeStep(type);
28 check_enum_error(t, "bad time step: ", time_step);
29
30 switch (t) {
31 case Options::TimeStep::hour:
32 case Options::TimeStep::hours:
33 case Options::TimeStep::h:
34 return TimeStep(std::chrono::hours(length ));
35 case Options::TimeStep::minute:
36 case Options::TimeStep::minutes:
37 case Options::TimeStep::min:
38 return TimeStep(std::chrono::minutes(length));
39 case Options::TimeStep::second:
40 case Options::TimeStep::seconds:
41 case Options::TimeStep::s:
42 return TimeStep(std::chrono::seconds(length));
43 case Options::TimeStep::FINAL: {
44 /* Leave empty and last */
45 }
46 }
47 return {};
48}
49
50Time next_even(const Time& t, const TimeStep& dt)
51{
52 auto dt_internal = std::chrono::duration_cast<Time::InternalTimeStep>(dt);
53
54 if (dt_internal.count())
55 return t + dt_internal - t.EpochTime() % dt_internal;
56 return t;
57}
58
60{
61 Index N = times.nelem();
62 ARTS_USER_ERROR_IF (N < 2,
63 "Can only find time steps for 2-long or longer time grids");
64
65 // algorithm only works with absolute times
66 const TimeStep dt = std::chrono::abs(DT);
67
69
70 if (N > 2) {
71 Time tupp = next_even(times[0], dt);
72 time_steps.emplace_back(1);
73
74 for (; time_steps.back() < N; time_steps.back()++) {
75 if (not (times[time_steps.back()] < tupp)) {
76 tupp = next_even(tupp, dt);
77 time_steps.emplace_back(time_steps.back());
78 }
79 }
80 } else {
81 time_steps.emplace_back(N);
82 }
83 return time_steps;
84}
85
86std::ostream& operator<<(std::ostream& os, const Time& t)
87{
88 // FIXME: C++20 has much better calendar handling
89 std::tm x = t.toStruct();
90
91 // Deal with seconds
92 std::array <char, 2 + 1 + 9 + 100> sec;
93 Numeric seconds = Numeric(x.tm_sec) + t.PartOfSecond();
94 snprintf(sec.data(), sec.size(), "%.9lf", seconds);
95
96 // Print based on std::tm specs
97 return os << 1900 + x.tm_year << '-' << std::setfill('0') << std::setw(2)
98 << 1 + x.tm_mon << '-' << std::setfill('0') << std::setw(2)
99 << x.tm_mday << ' ' << std::setfill('0') << std::setw(2)
100 << x.tm_hour << ':' << std::setfill('0') << std::setw(2)
101 << x.tm_min <<':' << std::setfill('0') << std::setw(12) << sec.data();
102}
103
104std::istream& operator>>(std::istream& is, Time& t)
105{
106 String ymd, hms;
107 is >> ymd >> hms;
108
109 ArrayOfString YMD, HMS;
110 ymd.split(YMD, "-");
111 hms.split(HMS, ":");
112
113 ARTS_USER_ERROR_IF (YMD.nelem() not_eq HMS.nelem() and YMD.nelem() not_eq 3,
114 "Time stream must look like \"year-month-day hour:min:seconds\"\n"
115 "\"year-month-day\" looks like: ", ymd, '\n',
116 "\"hour:min:seconds\" looks like: ", hms);
117
118 // FIXME: C++20 has much better calendar handling
119 std::tm x;
120 x.tm_year = std::stoi(YMD[0]) - 1900;
121 x.tm_mon = std::stoi(YMD[1]) - 1;
122 x.tm_mday = std::stoi(YMD[2]);
123 x.tm_hour = std::stoi(HMS[0]);
124 x.tm_min = std::stoi(HMS[1]);
125 x.tm_sec = 0;
126 x.tm_isdst = -1;
127
128 t = Time(x) + TimeStep(std::stod(HMS[2]));
129
130 return is;
131}
132
133Time mean_time(const ArrayOfTime& ts, Index s, Index E)
134{
135 Index e=0;
136 if (e == -1) e = ts.nelem();
137 ARTS_USER_ERROR_IF (e < 0 or e > ts.nelem(),
138 "Bad last index, valid options are [-1, ts.nelem()], got: ", E);
139
140 ARTS_USER_ERROR_IF (s < 0 or s > ts.nelem(),
141 "Bad first index, valid options are [0, ts.nelem()], got: ", s);
142
144 for (Index i=s+1; i<e; i++)
145 dt += (ts[i] - ts[s]) / (e - s);
146 return ts[s] + dt;
147}
148
149Vector time_vector(const ArrayOfTime& times) {
150 Vector t(times.nelem());
151 for (Index i=0; i<times.nelem(); i++) t[i] = Numeric(times[i]);
152 return t;
153}
154
155ArrayOfTime time_vector(const Vector& times) {
156 ArrayOfTime t(times.nelem());
157 for (Index i=0; i<times.nelem(); i++) t[i].Seconds(times[i]);
158 return t;
159}
160
162 const auto n = dt.size();
163 if (n) {
164 std::sort(dt.begin(), dt.end());
165 if (n % 2)
166 return dt[n / 2];
167 return (dt[(n-1)/2] + dt[n/2]) / 2;
168 }
169 return TimeStep(0);
170}
171
173 TimeStep t(0);
174 const auto n = dt.size();
175 for (std::size_t i=0; i<n; i++) {
176 t += dt[i] / n;
177 }
178 return t;
179}
180
181std::ostream& operator<<(std::ostream& os, const TimeStep& dt) {
182 return os << dt.count() << " seconds";
183}
Options for ARTS from enumeration (including error handling)
TimeStep mean(const ArrayOfTimeStep &dt)
Returns the mean time step.
Definition artstime.cc:172
ArrayOfIndex time_steps(const ArrayOfTime &times, const TimeStep &DT)
Finds the index matching demands in a list of times.
Definition artstime.cc:59
TimeStep time_stepper_selection(const String &time_step)
Returns a time step from valid string.
Definition artstime.cc:19
Vector time_vector(const ArrayOfTime &times)
Converts from each Time to seconds and returns as Vector.
Definition artstime.cc:149
Time mean_time(const ArrayOfTime &ts, Index s, Index E)
Computes the average time in a list.
Definition artstime.cc:133
TimeStep median(ArrayOfTimeStep dt)
Returns the median time step.
Definition artstime.cc:161
std::istream & operator>>(std::istream &is, Time &t)
Definition artstime.cc:104
std::ostream & operator<<(std::ostream &os, const Time &t)
Definition artstime.cc:86
Time next_even(const Time &t, const TimeStep &dt)
Returns the next time after t with an even time-step.
Definition artstime.cc:50
Stuff related to time in ARTS.
std::chrono::duration< Numeric > TimeStep
A duration of time, 1 full tick should be 1 second.
Definition artstime.h:22
Index nelem() const ARTS_NOEXCEPT
Definition array.h:75
void split(Array< my_basic_string< charT > > &aos, const my_basic_string< charT > &delim) const
Definition mystring.h:112
void tolower()
Convert to lower case.
Definition mystring.h:141
#define ARTS_USER_ERROR_IF(condition,...)
Definition debug.h:137
constexpr void check_enum_error(EnumType type, Messages... args)
Checks if the enum class type is good and otherwise throws an error message composed by variadic inpu...
Definition enums.h:90
Class to handle time in ARTS.
Definition artstime.h:25
InternalTimeStep EpochTime() const
Definition artstime.h:62
Numeric PartOfSecond() const
Definition artstime.h:109
Time()
Definition artstime.h:33
decltype(time)::duration InternalTimeStep
Definition artstime.h:27
std::tm toStruct() const
Definition artstime.h:43