12
12
import pandas as pd
13
13
import pytest
14
14
from packaging .version import Version
15
- from pygmt import x2sys_cross , x2sys_init
15
+ from pygmt import config , x2sys_cross , x2sys_init
16
16
from pygmt .clib import __gmt_version__
17
17
from pygmt .datasets import load_sample_data
18
18
from pygmt .exceptions import GMTInvalidInput
@@ -52,15 +52,20 @@ def test_x2sys_cross_input_file_output_file():
52
52
output = x2sys_cross (
53
53
tracks = ["@tut_ship.xyz" ], tag = tag , coe = "i" , outfile = outfile
54
54
)
55
-
56
55
assert output is None # check that output is None since outfile is set
57
56
assert outfile .stat ().st_size > 0 # check that outfile exists at path
58
- _ = pd .read_csv (outfile , sep = "\t " , header = 2 ) # ensure ASCII text file loads ok
57
+ result = pd .read_csv (outfile , sep = "\t " , comment = ">" , header = 2 )
58
+ assert result .shape == (14374 , 12 ) if sys .platform == "darwin" else (14338 , 12 )
59
+ columns = list (result .columns )
60
+ assert columns [:6 ] == ["# x" , "y" , "i_1" , "i_2" , "dist_1" , "dist_2" ]
61
+ assert columns [6 :] == ["head_1" , "head_2" , "vel_1" , "vel_2" , "z_X" , "z_M" ]
62
+ npt .assert_allclose (result ["i_1" ].min (), 45.2099 , rtol = 1.0e-4 )
63
+ npt .assert_allclose (result ["i_1" ].max (), 82945.9370 , rtol = 1.0e-4 )
59
64
60
65
61
66
@pytest .mark .usefixtures ("mock_x2sys_home" )
62
67
@pytest .mark .xfail (
63
- condition = Version (__gmt_version__ ) < Version ("6.5.0" ) or sys . platform == "darwin" ,
68
+ condition = Version (__gmt_version__ ) < Version ("6.5.0" ),
64
69
reason = "Upstream bug fixed in https://github.com/GenericMappingTools/gmt/pull/8188" ,
65
70
)
66
71
def test_x2sys_cross_input_file_output_dataframe ():
@@ -74,39 +79,70 @@ def test_x2sys_cross_input_file_output_dataframe():
74
79
output = x2sys_cross (tracks = ["@tut_ship.xyz" ], tag = tag , coe = "i" )
75
80
76
81
assert isinstance (output , pd .DataFrame )
77
- assert output .shape == (14338 , 12 )
82
+ assert output .shape == (14374 , 12 ) if sys . platform == "darwin" else ( 14338 , 12 )
78
83
columns = list (output .columns )
79
84
assert columns [:6 ] == ["x" , "y" , "i_1" , "i_2" , "dist_1" , "dist_2" ]
80
85
assert columns [6 :] == ["head_1" , "head_2" , "vel_1" , "vel_2" , "z_X" , "z_M" ]
86
+ assert output ["i_1" ].dtype .type == np .timedelta64
87
+ assert output ["i_2" ].dtype .type == np .timedelta64
88
+ npt .assert_allclose (output ["i_1" ].min ().total_seconds (), 45.2099 , rtol = 1.0e-4 )
89
+ npt .assert_allclose (output ["i_1" ].max ().total_seconds (), 82945.937 , rtol = 1.0e-4 )
81
90
82
91
83
92
@pytest .mark .benchmark
84
93
@pytest .mark .usefixtures ("mock_x2sys_home" )
85
- def test_x2sys_cross_input_dataframe_output_dataframe (tracks ):
94
+ @pytest .mark .parametrize ("unit" , ["s" , "o" , "y" ])
95
+ def test_x2sys_cross_input_dataframe_output_dataframe (tracks , unit ):
86
96
"""
87
97
Run x2sys_cross by passing in one dataframe, and output internal crossovers to a
88
- pandas.DataFrame.
98
+ pandas.DataFrame, checking TIME_UNIT s (second), o (month), and y (year) .
89
99
"""
90
100
with TemporaryDirectory (prefix = "X2SYS" , dir = Path .cwd ()) as tmpdir :
91
101
tag = Path (tmpdir ).name
92
102
x2sys_init (tag = tag , fmtfile = "xyz" , force = True )
93
103
94
- output = x2sys_cross (tracks = tracks , tag = tag , coe = "i" )
104
+ with config (TIME_UNIT = unit ):
105
+ output = x2sys_cross (tracks = tracks , tag = tag , coe = "i" )
95
106
96
107
assert isinstance (output , pd .DataFrame )
97
108
assert output .shape == (14 , 12 )
98
109
columns = list (output .columns )
99
110
assert columns [:6 ] == ["x" , "y" , "i_1" , "i_2" , "dist_1" , "dist_2" ]
100
111
assert columns [6 :] == ["head_1" , "head_2" , "vel_1" , "vel_2" , "z_X" , "z_M" ]
101
- assert output .dtypes ["i_1" ].type == np .object_
102
- assert output .dtypes ["i_2" ].type == np .object_
112
+ assert output ["i_1" ].dtype .type == np .timedelta64
113
+ assert output ["i_2" ].dtype .type == np .timedelta64
114
+
115
+ # Scale to convert a value to second
116
+ match unit :
117
+ case "y" :
118
+ scale = 365.2425 * 86400.0
119
+ case "o" :
120
+ scale = 365.2425 / 12.0 * 86400.0
121
+ case _:
122
+ scale = 1.0
123
+ npt .assert_allclose (
124
+ output ["i_1" ].min ().total_seconds (), 0.9175 * scale , rtol = 1.0e-4
125
+ )
126
+ npt .assert_allclose (
127
+ output ["i_1" ].max ().total_seconds (), 23.9996 * scale , rtol = 1.0e-4
128
+ )
103
129
104
130
105
131
@pytest .mark .usefixtures ("mock_x2sys_home" )
106
- def test_x2sys_cross_input_two_dataframes ():
132
+ @pytest .mark .parametrize (
133
+ ("unit" , "epoch" ),
134
+ [
135
+ ("s" , "1970-01-01T00:00:00" ),
136
+ ("o" , "1970-01-01T00:00:00" ),
137
+ ("y" , "1970-01-01T00:00:00" ),
138
+ ("s" , "2012-03-04T05:06:07" ),
139
+ ],
140
+ )
141
+ def test_x2sys_cross_input_two_dataframes (unit , epoch ):
107
142
"""
108
143
Run x2sys_cross by passing in two pandas.DataFrame tables with a time column, and
109
- output external crossovers to a pandas.DataFrame.
144
+ output external crossovers to a pandas.DataFrame, checking TIME_UNIT s (second),
145
+ o (month), and y (year), and TIME_EPOCH 1970 and 2012.
110
146
"""
111
147
with TemporaryDirectory (prefix = "X2SYS" , dir = Path .cwd ()) as tmpdir :
112
148
tmpdir_p = Path (tmpdir )
@@ -127,15 +163,22 @@ def test_x2sys_cross_input_two_dataframes():
127
163
track ["time" ] = pd .date_range (start = f"2020-{ i } 1-01" , periods = 10 , freq = "min" )
128
164
tracks .append (track )
129
165
130
- output = x2sys_cross (tracks = tracks , tag = tag , coe = "e" )
166
+ with config (TIME_UNIT = unit , TIME_EPOCH = epoch ):
167
+ output = x2sys_cross (tracks = tracks , tag = tag , coe = "e" )
131
168
132
169
assert isinstance (output , pd .DataFrame )
133
170
assert output .shape == (26 , 12 )
134
171
columns = list (output .columns )
135
172
assert columns [:6 ] == ["x" , "y" , "t_1" , "t_2" , "dist_1" , "dist_2" ]
136
173
assert columns [6 :] == ["head_1" , "head_2" , "vel_1" , "vel_2" , "z_X" , "z_M" ]
137
- assert output .dtypes ["t_1" ].type == np .datetime64
138
- assert output .dtypes ["t_2" ].type == np .datetime64
174
+ assert output ["t_1" ].dtype .type == np .datetime64
175
+ assert output ["t_2" ].dtype .type == np .datetime64
176
+
177
+ tolerance = pd .Timedelta ("1ms" )
178
+ t1_min = pd .Timestamp ("2020-01-01 00:00:10.6677" )
179
+ t1_max = pd .Timestamp ("2020-01-01 00:08:29.8067" )
180
+ assert abs (output ["t_1" ].min () - t1_min ) < tolerance
181
+ assert abs (output ["t_1" ].max () - t1_max ) < tolerance
139
182
140
183
141
184
@pytest .mark .usefixtures ("mock_x2sys_home" )
@@ -159,8 +202,8 @@ def test_x2sys_cross_input_dataframe_with_nan(tracks):
159
202
columns = list (output .columns )
160
203
assert columns [:6 ] == ["x" , "y" , "i_1" , "i_2" , "dist_1" , "dist_2" ]
161
204
assert columns [6 :] == ["head_1" , "head_2" , "vel_1" , "vel_2" , "z_X" , "z_M" ]
162
- assert output .dtypes ["i_1" ].type == np .object_
163
- assert output .dtypes ["i_2" ].type == np .object_
205
+ assert output .dtypes ["i_1" ].type == np .timedelta64
206
+ assert output .dtypes ["i_2" ].type == np .timedelta64
164
207
165
208
166
209
@pytest .mark .usefixtures ("mock_x2sys_home" )
@@ -201,7 +244,7 @@ def test_x2sys_cross_invalid_tracks_input_type(tracks):
201
244
202
245
@pytest .mark .usefixtures ("mock_x2sys_home" )
203
246
@pytest .mark .xfail (
204
- condition = Version (__gmt_version__ ) < Version ("6.5.0" ) or sys . platform == "darwin" ,
247
+ condition = Version (__gmt_version__ ) < Version ("6.5.0" ),
205
248
reason = "Upstream bug fixed in https://github.com/GenericMappingTools/gmt/pull/8188" ,
206
249
)
207
250
def test_x2sys_cross_region_interpolation_numpoints ():
@@ -222,15 +265,21 @@ def test_x2sys_cross_region_interpolation_numpoints():
222
265
)
223
266
224
267
assert isinstance (output , pd .DataFrame )
225
- assert output .shape == (3882 , 12 )
226
- # Check crossover errors (z_X) and mean value of observables (z_M)
227
- npt .assert_allclose (output .z_X .mean (), - 138.66 , rtol = 1e-4 )
228
- npt .assert_allclose (output .z_M .mean (), - 2896.875915 )
268
+ if sys .platform == "darwin" :
269
+ assert output .shape == (3894 , 12 )
270
+ # Check crossover errors (z_X) and mean value of observables (z_M)
271
+ npt .assert_allclose (output .z_X .mean (), - 138.23215 , rtol = 1e-4 )
272
+ npt .assert_allclose (output .z_M .mean (), - 2897.187545 , rtol = 1e-4 )
273
+ else :
274
+ assert output .shape == (3882 , 12 )
275
+ # Check crossover errors (z_X) and mean value of observables (z_M)
276
+ npt .assert_allclose (output .z_X .mean (), - 138.66 , rtol = 1e-4 )
277
+ npt .assert_allclose (output .z_M .mean (), - 2896.875915 , rtol = 1e-4 )
229
278
230
279
231
280
@pytest .mark .usefixtures ("mock_x2sys_home" )
232
281
@pytest .mark .xfail (
233
- condition = Version (__gmt_version__ ) < Version ("6.5.0" ) or sys . platform == "darwin" ,
282
+ condition = Version (__gmt_version__ ) < Version ("6.5.0" ),
234
283
reason = "Upstream bug fixed in https://github.com/GenericMappingTools/gmt/pull/8188" ,
235
284
)
236
285
def test_x2sys_cross_trackvalues ():
@@ -243,7 +292,12 @@ def test_x2sys_cross_trackvalues():
243
292
output = x2sys_cross (tracks = ["@tut_ship.xyz" ], tag = tag , trackvalues = True )
244
293
245
294
assert isinstance (output , pd .DataFrame )
246
- assert output .shape == (14338 , 12 )
247
- # Check mean of track 1 values (z_1) and track 2 values (z_2)
248
- npt .assert_allclose (output .z_1 .mean (), - 2422.418556 , rtol = 1e-4 )
249
- npt .assert_allclose (output .z_2 .mean (), - 2402.268364 , rtol = 1e-4 )
295
+ if sys .platform == "darwin" :
296
+ assert output .shape == (14374 , 12 )
297
+ # Check mean of track 1 values (z_1) and track 2 values (z_2)
298
+ npt .assert_allclose (output .z_1 .mean (), - 2422.973372 , rtol = 1e-4 )
299
+ npt .assert_allclose (output .z_2 .mean (), - 2402.87476 , rtol = 1e-4 )
300
+ else :
301
+ assert output .shape == (14338 , 12 )
302
+ npt .assert_allclose (output .z_1 .mean (), - 2422.418556 , rtol = 1e-4 )
303
+ npt .assert_allclose (output .z_2 .mean (), - 2402.268364 , rtol = 1e-4 )
0 commit comments