ARTS 2.5.10 (git: 2f1c442c)
artstime.cc
Go to the documentation of this file.
1/* Copyright (C) 2020
2 * Richard Larsson <ric.larsson@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2, or (at your option) any
7 * later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA. */
18
27#include "artstime.h"
28#include "arts_options.h"
29#include <cstdlib>
30#include <ctime>
31
32Time::Time(const String& t) {
33 auto s = std::istringstream(t);
34 s >> *this;
35}
36
38{
39 std::istringstream x(time_step);
40 Index length;
41 String type;
42 x >> length >> type;
43 type.tolower();
44
45 const Options::TimeStep t = Options::toTimeStep(type);
46 check_enum_error(t, "bad time step: ", time_step);
47
48 switch (t) {
49 case Options::TimeStep::hour:
50 case Options::TimeStep::hours:
51 case Options::TimeStep::h:
52 return TimeStep(std::chrono::hours(length ));
53 case Options::TimeStep::minute:
54 case Options::TimeStep::minutes:
55 case Options::TimeStep::min:
56 return TimeStep(std::chrono::minutes(length));
57 case Options::TimeStep::second:
58 case Options::TimeStep::seconds:
59 case Options::TimeStep::s:
60 return TimeStep(std::chrono::seconds(length));
61 case Options::TimeStep::FINAL: {
62 /* Leave empty and last */
63 }
64 }
65 return {};
66}
67
68Time next_even(const Time& t, const TimeStep& dt)
69{
70 auto dt_internal = std::chrono::duration_cast<Time::InternalTimeStep>(dt);
71
72 if (dt_internal.count())
73 return t + dt_internal - t.EpochTime() % dt_internal;
74 return t;
75}
76
78{
79 Index N = times.nelem();
81 "Can only find time steps for 2-long or longer time grids");
82
83 // algorithm only works with absolute times
84 const TimeStep dt = std::chrono::abs(DT);
85
87
88 if (N > 2) {
89 Time tupp = next_even(times[0], dt);
90 time_steps.emplace_back(1);
91
92 for (; time_steps.back() < N; time_steps.back()++) {
93 if (not (times[time_steps.back()] < tupp)) {
94 tupp = next_even(tupp, dt);
95 time_steps.emplace_back(time_steps.back());
96 }
97 }
98 } else {
99 time_steps.emplace_back(N);
100 }
101 return time_steps;
102}
103
104std::ostream& operator<<(std::ostream& os, const Time& t)
105{
106 // FIXME: C++20 has much better calendar handling
107 std::tm x = t.toStruct();
108
109 // Deal with seconds
110 std::array <char, 2 + 1 + 9 + 100> sec;
111 Numeric seconds = Numeric(x.tm_sec) + t.PartOfSecond();
112 snprintf(sec.data(), sec.size(), "%.9lf", seconds);
113
114 // Print based on std::tm specs
115 return os << 1900 + x.tm_year << '-' << std::setfill('0') << std::setw(2)
116 << 1 + x.tm_mon << '-' << std::setfill('0') << std::setw(2)
117 << x.tm_mday << ' ' << std::setfill('0') << std::setw(2)
118 << x.tm_hour << ':' << std::setfill('0') << std::setw(2)
119 << x.tm_min <<':' << std::setfill('0') << std::setw(12) << sec.data();
120}
121
122std::istream& operator>>(std::istream& is, Time& t)
123{
124 String ymd, hms;
125 is >> ymd >> hms;
126
127 ArrayOfString YMD, HMS;
128 ymd.split(YMD, "-");
129 hms.split(HMS, ":");
130
131 ARTS_USER_ERROR_IF (YMD.nelem() not_eq HMS.nelem() and YMD.nelem() not_eq 3,
132 "Time stream must look like \"year-month-day hour:min:seconds\"\n"
133 "\"year-month-day\" looks like: ", ymd, '\n',
134 "\"hour:min:seconds\" looks like: ", hms);
135
136 // FIXME: C++20 has much better calendar handling
137 std::tm x;
138 x.tm_year = std::stoi(YMD[0]) - 1900;
139 x.tm_mon = std::stoi(YMD[1]) - 1;
140 x.tm_mday = std::stoi(YMD[2]);
141 x.tm_hour = std::stoi(HMS[0]);
142 x.tm_min = std::stoi(HMS[1]);
143 x.tm_sec = 0;
144 x.tm_isdst = -1;
145
146 t = Time(x) + TimeStep(std::stod(HMS[2]));
147
148 return is;
149}
150
152{
153 Index e=0;
154 if (e == -1) e = ts.nelem();
155 ARTS_USER_ERROR_IF (e < 0 or e > ts.nelem(),
156 "Bad last index, valid options are [-1, ts.nelem()], got: ", E);
157
158 ARTS_USER_ERROR_IF (s < 0 or s > ts.nelem(),
159 "Bad first index, valid options are [0, ts.nelem()], got: ", s);
160
162 for (Index i=s+1; i<e; i++)
163 dt += (ts[i] - ts[s]) / (e - s);
164 return ts[s] + dt;
165}
166
168 Vector t(times.nelem());
169 for (Index i=0; i<times.nelem(); i++) t[i] = Numeric(times[i]);
170 return t;
171}
172
174 ArrayOfTime t(times.nelem());
175 for (Index i=0; i<times.nelem(); i++) t[i].Seconds(times[i]);
176 return t;
177}
178
180 const auto n = dt.size();
181 if (n) {
182 std::sort(dt.begin(), dt.end());
183 if (n % 2)
184 return dt[n / 2];
185 return (dt[(n-1)/2] + dt[n/2]) / 2;
186 }
187 return TimeStep(0);
188}
189
191 TimeStep t(0);
192 const auto n = dt.size();
193 for (std::size_t i=0; i<n; i++) {
194 t += dt[i] / n;
195 }
196 return t;
197}
198
199std::ostream& operator<<(std::ostream& os, const TimeStep& dt) {
200 return os << dt.count() << " seconds";
201}
Options for ARTS from enumeration (including error handling)
TimeStep mean(const ArrayOfTimeStep &dt)
Returns the mean time step.
Definition: artstime.cc:190
ArrayOfIndex time_steps(const ArrayOfTime &times, const TimeStep &DT)
Finds the index matching demands in a list of times.
Definition: artstime.cc:77
TimeStep time_stepper_selection(const String &time_step)
Returns a time step from valid string.
Definition: artstime.cc:37
Vector time_vector(const ArrayOfTime &times)
Converts from each Time to seconds and returns as Vector.
Definition: artstime.cc:167
Time mean_time(const ArrayOfTime &ts, Index s, Index E)
Computes the average time in a list.
Definition: artstime.cc:151
TimeStep median(ArrayOfTimeStep dt)
Returns the median time step.
Definition: artstime.cc:179
std::istream & operator>>(std::istream &is, Time &t)
Definition: artstime.cc:122
std::ostream & operator<<(std::ostream &os, const Time &t)
Definition: artstime.cc:104
Time next_even(const Time &t, const TimeStep &dt)
Returns the next time after t with an even time-step.
Definition: artstime.cc:68
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:40
Index nelem() const ARTS_NOEXCEPT
Definition: array.h:92
Index nelem() const noexcept
Returns the number of elements.
Definition: matpackI.h:547
The Vector class.
Definition: matpackI.h:910
void split(Array< my_basic_string< charT > > &aos, const my_basic_string< charT > &delim) const
Definition: mystring.h:129
void tolower()
Convert to lower case.
Definition: mystring.h:158
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:153
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
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
#define N
Definition: rng.cc:164
Class to handle time in ARTS.
Definition: artstime.h:43
InternalTimeStep EpochTime() const
Definition: artstime.h:80
Numeric PartOfSecond() const
Definition: artstime.h:127
Time()
Definition: artstime.h:51
decltype(time)::duration InternalTimeStep
Definition: artstime.h:45
std::tm toStruct() const
Definition: artstime.h:61