@@ -34,7 +34,9 @@ def to_2d(self, obs_dim='obs'):
34
34
time = ds [self .time_varname ].rename ({
35
35
self .time_varname : obs_dim
36
36
}).expand_dims (
37
- dim = {self .trajectory_dim : ds .sizes [self .trajectory_dim ]})
37
+ dim = {
38
+ self .trajectory_dim : ds .sizes [self .trajectory_dim ]
39
+ }).assign_coords ({self .trajectory_dim : ds [self .trajectory_dim ]})
38
40
# TODO should also add cf_role here
39
41
ds = ds .rename ({self .time_varname : obs_dim })
40
42
ds [self .time_varname ] = time
@@ -119,19 +121,23 @@ def skill_along_trajectory(self, expected, **kwargs):
119
121
120
122
def skill_matching (traj , expected ):
121
123
traj = traj .where (np .isfinite (traj .lon ), drop = True )
122
- expected_overlap = expected .sel (time = slice (traj .time [0 ], traj .time [- 1 ]))
124
+ expected_overlap = expected .sel (
125
+ time = slice (traj .time [0 ], traj .time [- 1 ]))
123
126
mask = False
124
- if traj .sizes [self .obs_dim ] != expected_overlap .sizes [expected_overlap .traj .obs_dim ]:
125
- traj = traj .sel (time = slice (expected_overlap .time [0 ], expected_overlap .time [- 1 ]))
127
+ if traj .sizes [self .obs_dim ] != expected_overlap .sizes [
128
+ expected_overlap .traj .obs_dim ]:
129
+ traj = traj .sel (time = slice (expected_overlap .time [0 ],
130
+ expected_overlap .time [- 1 ]))
126
131
mask = True
127
132
s = traj .traj .skill (expected_overlap , ** kwargs )
128
133
if mask is True :
129
- s = s * np .nan # Mask out the skill score if the trajectories are not of equal length
134
+ s = s * np .nan # Mask out the skill score if the trajectories are not of equal length
130
135
s ['start_time' ] = traj .time [0 ]
131
136
s ['end_time' ] = traj .time [- 1 ]
132
137
return s
133
138
134
- s = self .ds .groupby (self .trajectory_dim ).apply (skill_matching , expected = expected )
139
+ s = self .ds .groupby (self .trajectory_dim ).apply (skill_matching ,
140
+ expected = expected )
135
141
s ['start_lon' ] = start_lon
136
142
s ['start_lat' ] = start_lat
137
143
s ['end_lon' ] = end_lon
@@ -151,8 +157,7 @@ def skill(self, expected, method='liu-weissberg', **kwargs) -> xr.Dataset:
151
157
if numtraj_self > 1 and numtraj_expected > 1 and numtraj_self != numtraj_expected :
152
158
raise ValueError (
153
159
'Datasets must have the same number of trajectories, or a single trajectory. '
154
- f'This dataset: { numtraj_self } , expected: { numtraj_expected } .'
155
- )
160
+ f'This dataset: { numtraj_self } , expected: { numtraj_expected } .' )
156
161
157
162
numobs_self = self .ds .sizes [self .obs_dim ]
158
163
numobs_expected = expected .ds .sizes [expected .obs_dim ]
@@ -162,9 +167,10 @@ def skill(self, expected, method='liu-weissberg', **kwargs) -> xr.Dataset:
162
167
)
163
168
164
169
diff = np .max (
165
- np .abs ((self .ds [self .obs_dim ] -
166
- expected .ds [expected .obs_dim ]).astype ('timedelta64[s]' ).astype (
167
- np .float64 )))
170
+ np .abs ((
171
+ self .ds [self .obs_dim ] -
172
+ expected .ds [expected .obs_dim ]).astype ('timedelta64[s]' ).astype (
173
+ np .float64 )))
168
174
if not np .isclose (diff , 0 ):
169
175
raise ValueError (
170
176
f"The two datasets must have approximately equal time coordinates, maximum difference: { diff } seconds. Consider using `gridtime` to interpolate one of the datasets."
@@ -193,7 +199,8 @@ def skill(self, expected, method='liu-weissberg', **kwargs) -> xr.Dataset:
193
199
else :
194
200
raise ValueError (f"Unknown skill-score method: { method } ." )
195
201
196
- s = skill_method (expected .traj .tlon , expected .traj .tlat , ds .traj .tlon , ds .traj .tlat , ** kwargs )
202
+ s = skill_method (expected .traj .tlon , expected .traj .tlat , ds .traj .tlon ,
203
+ ds .traj .tlat , ** kwargs )
197
204
198
205
newcoords = dict (ds .lon .sizes )
199
206
newcoords .pop ('time' )
0 commit comments