Skip to content

Commit dbdc081

Browse files
authored
Merge pull request #347 from physycom/refactorOutputs
2 parents 36c2c03 + eb2a88e commit dbdc081

File tree

6 files changed

+42
-32
lines changed

6 files changed

+42
-32
lines changed

src/dsf/binding.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ PYBIND11_MODULE(dsf_cpp, m) {
410410
.def("time_step",
411411
&dsf::FirstOrderDynamics::time_step,
412412
dsf::g_docstrings.at("dsf::Dynamics::time_step").c_str())
413+
.def("datetime",
414+
&dsf::FirstOrderDynamics::strDateTime,
415+
dsf::g_docstrings.at("dsf::Dynamics::strDateTime").c_str())
413416
.def("meanTravelTime",
414417
&dsf::FirstOrderDynamics::meanTravelTime,
415418
pybind11::arg("clearData") = false,

src/dsf/dsf.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
#include <format>
66

77
static constexpr uint8_t DSF_VERSION_MAJOR = 3;
8-
static constexpr uint8_t DSF_VERSION_MINOR = 12;
9-
static constexpr uint8_t DSF_VERSION_PATCH = 1;
8+
static constexpr uint8_t DSF_VERSION_MINOR = 13;
9+
static constexpr uint8_t DSF_VERSION_PATCH = 0;
1010

1111
static auto const DSF_VERSION =
1212
std::format("{}.{}.{}", DSF_VERSION_MAJOR, DSF_VERSION_MINOR, DSF_VERSION_PATCH);

src/dsf/headers/Dynamics.hpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <algorithm>
1515
#include <cassert>
16+
#include <chrono>
1617
#include <concepts>
1718
#include <vector>
1819
#include <random>
@@ -28,7 +29,6 @@
2829
#include <filesystem>
2930
#include <functional>
3031
#include <iomanip>
31-
#include <sstream>
3232

3333
#include <tbb/tbb.h>
3434

@@ -96,14 +96,10 @@ namespace dsf {
9696
inline std::time_t time_step() const { return m_timeStep; }
9797
/// @brief Get the current simulation time as formatted string (YYYY-MM-DD HH:MM:SS)
9898
/// @return std::string, The current simulation time as formatted string
99-
inline auto strTime() const {
100-
if (m_timeInit == 0) {
101-
return std::to_string(m_timeStep);
102-
}
103-
std::time_t const t = time();
104-
std::ostringstream oss;
105-
oss << std::put_time(std::localtime(&t), "%Y-%m-%d %H:%M:%S");
106-
return oss.str();
99+
inline auto strDateTime() const {
100+
return std::format(
101+
"{:%Y-%m-%d %H:%M:%S}", std::chrono::floor<std::chrono::seconds>(std::chrono::current_zone()->to_local(
102+
std::chrono::system_clock::from_time_t(time()))));
107103
}
108104
};
109105

src/dsf/headers/RoadDynamics.hpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,13 +2170,13 @@ namespace dsf {
21702170
throw std::runtime_error("Error opening file \"" + filename + "\" for writing.");
21712171
}
21722172
if (bEmptyFile) {
2173-
file << "time";
2173+
file << "datetime" << separator << "time_step";
21742174
for (auto const& [streetId, pStreet] : this->graph().edges()) {
21752175
file << separator << streetId;
21762176
}
21772177
file << std::endl;
21782178
}
2179-
file << this->strTime();
2179+
file << this->strDateTime() << separator << this->time_step();
21802180
for (auto const& [streetId, pStreet] : this->graph().edges()) {
21812181
// keep 2 decimal digits;
21822182
file << separator << std::scientific << std::setprecision(2)
@@ -2200,7 +2200,7 @@ namespace dsf {
22002200
throw std::runtime_error("Error opening file \"" + filename + "\" for writing.");
22012201
}
22022202
if (bEmptyFile) {
2203-
file << "time";
2203+
file << "datetime" << separator << "time_step";
22042204
for (auto const& [streetId, pStreet] : this->graph().edges()) {
22052205
if (!pStreet->isSpire()) {
22062206
continue;
@@ -2213,7 +2213,7 @@ namespace dsf {
22132213
}
22142214
file << std::endl;
22152215
}
2216-
file << this->strTime();
2216+
file << this->strDateTime() << separator << this->time_step();
22172217
for (auto const& [streetId, pStreet] : this->graph().edges()) {
22182218
int value{0};
22192219
if (pStreet->isSpire()) {
@@ -2243,7 +2243,7 @@ namespace dsf {
22432243
throw std::runtime_error("Error opening file \"" + filename + "\" for writing.");
22442244
}
22452245
if (bEmptyFile) {
2246-
file << "time";
2246+
file << "datetime" << separator << "time_step";
22472247
for (auto const& [streetId, pStreet] : this->graph().edges()) {
22482248
if (!pStreet->isSpire()) {
22492249
continue;
@@ -2256,7 +2256,7 @@ namespace dsf {
22562256
}
22572257
file << std::endl;
22582258
}
2259-
file << this->strTime();
2259+
file << this->strDateTime() << separator << this->time_step();
22602260
for (auto const& [streetId, pStreet] : this->graph().edges()) {
22612261
int value{0};
22622262
if (pStreet->isSpire()) {
@@ -2284,7 +2284,7 @@ namespace dsf {
22842284
throw std::runtime_error("Error opening file \"" + filename + "\" for writing.");
22852285
}
22862286
if (bEmptyFile) {
2287-
file << "time;distances;times;speeds" << std::endl;
2287+
file << "datetime;time_step;distances;times;speeds" << std::endl;
22882288
}
22892289

22902290
// Construct strings efficiently with proper formatting
@@ -2318,8 +2318,8 @@ namespace dsf {
23182318
}
23192319

23202320
// Write all data at once
2321-
file << this->strTime() << ';' << strTravelDistances << ';' << strTravelTimes << ';'
2322-
<< strTravelSpeeds << std::endl;
2321+
file << this->strDateTime() << ';' << this->time_step() << ';' << strTravelDistances
2322+
<< ';' << strTravelTimes << ';' << strTravelSpeeds << std::endl;
23232323

23242324
file.close();
23252325
if (reset) {
@@ -2340,10 +2340,10 @@ namespace dsf {
23402340
throw std::runtime_error("Error opening file \"" + filename + "\" for writing.");
23412341
}
23422342
if (bEmptyFile) {
2343-
file << "time;n_ghost_agents;n_agents;mean_speed;mean_speed_std;mean_density;mean_"
2344-
"density_std;mean_flow;mean_flow_std;mean_traveltime;mean_traveltime_std;"
2345-
"mean_traveldistance;mean_traveldistance_"
2346-
"err;mean_travelspeed;mean_travelspeed_std\n";
2343+
file << "datetime;time_step;n_ghost_agents;n_agents;mean_speed_kph;std_speed_kph;"
2344+
"mean_density_vpk;std_density_vpk;mean_flow_vph;std_flow_vph;mean_"
2345+
"traveltime_m;std_traveltime_m;mean_traveldistance_km;std_traveldistance_"
2346+
"km;mean_travelspeed_kph;std_travelspeed_kph\n";
23472347
}
23482348
double mean_speed{0.}, mean_density{0.}, mean_flow{0.}, mean_travel_distance{0.},
23492349
mean_travel_time{0.}, mean_travel_speed{0.};
@@ -2390,7 +2390,8 @@ namespace dsf {
23902390
std_travel_speed =
23912391
std::sqrt(std_travel_speed / nData - mean_travel_speed * mean_travel_speed);
23922392

2393-
file << this->strTime() << separator;
2393+
file << this->strDateTime() << separator;
2394+
file << this->time_step() << separator;
23942395
file << m_agents.size() << separator;
23952396
file << this->nAgents() << separator;
23962397
file << std::scientific << std::setprecision(2);

src/dsf/python/cartography.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ def get_cartography(
129129
else:
130130
G[u][v][k][key] = value
131131

132+
# Add id to edges
133+
for i, (u, v, k) in enumerate(G.edges(keys=True)):
134+
G[u][v][k]["id"] = i
135+
132136
# Standardize node attributes in the graph
133137
nodes_to_update = []
134138
for node, data in G.nodes(data=True):
@@ -188,9 +192,8 @@ def get_cartography(
188192
# Convert back to MultiDiGraph temporarily for ox.graph_to_gdfs compatibility
189193
gdf_nodes, gdf_edges = ox.graph_to_gdfs(G)
190194

191-
# Reset index and add edge id
195+
# Reset index and rename columns (id already exists from graph)
192196
gdf_edges.reset_index(inplace=True)
193-
gdf_edges["id"] = gdf_edges.index
194197
gdf_edges.rename(columns={"u": "source", "v": "target"}, inplace=True)
195198
gdf_edges.drop(columns=["key"], inplace=True, errors="ignore")
196199

test/Test_dynamics.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,11 @@ TEST_CASE("FirstOrderDynamics") {
225225
graph.importMatrix("./data/matrix.dat", false);
226226
// graph.adjustNodeCapacities();
227227
FirstOrderDynamics dynamics{graph, false, 69, 0., dsf::PathWeight::LENGTH};
228-
CHECK_EQ(dynamics.strTime(), "0");
228+
CHECK_EQ(dynamics.strDateTime(),
229+
std::format("{:%Y-%m-%d %H:%M:%S}",
230+
std::chrono::floor<std::chrono::seconds>(
231+
std::chrono::current_zone()->to_local(
232+
std::chrono::system_clock::from_time_t(0)))));
229233
auto const epochStart{
230234
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())};
231235
dynamics.setInitTime(epochStart);
@@ -240,10 +244,13 @@ TEST_CASE("FirstOrderDynamics") {
240244
CHECK(dynamics.nAgents() < n);
241245
CHECK_EQ(dynamics.time_step(), 40);
242246
CHECK_EQ(dynamics.time() - epochStart, 40);
243-
std::ostringstream oss;
244-
auto currentTime = epochStart + 40;
245-
oss << std::put_time(std::localtime(&currentTime), "%Y-%m-%d %H:%M:%S");
246-
CHECK_EQ(dynamics.strTime(), oss.str());
247+
CHECK_EQ(
248+
dynamics.strDateTime(),
249+
std::format(
250+
"{:%Y-%m-%d %H:%M:%S}",
251+
std::chrono::floor<std::chrono::seconds>(
252+
std::chrono::current_zone()->to_local(
253+
std::chrono::system_clock::from_time_t(dynamics.time())))));
247254
}
248255
}
249256
}

0 commit comments

Comments
 (0)