@@ -137,6 +137,39 @@ def extend_years(cube):
137137 return cubelist .concatenate_cube ()
138138
139139
140+ def _interpolate_months_separately (cube , tpoints ):
141+ # Perform linear time-interpolation
142+ new_cube = cube .interpolate ([("time" , tpoints )], iris .analysis .Linear ())
143+ new_cube .data = np .ma .asarray (new_cube .data )
144+
145+ # Add month categorisation to extract each month's series
146+ if not cube .coords ("month_number" ):
147+ iris .coord_categorisation .add_month_number (
148+ cube , "time" , name = "month_number"
149+ )
150+
151+ # Interpolate each month separately and interleave the data
152+ for m in range (1 , MONTHS_IN_A_YEAR + 1 ):
153+ month_constraint = iris .Constraint (month_number = m )
154+ m_cube = cube .extract (month_constraint )
155+ if m_cube is not None :
156+ # Select target time points for this month across all years
157+ m_tpoints = tpoints [m - 1 :: MONTHS_IN_A_YEAR ]
158+ # Interpolate across the years for this month
159+ m_interpolated = m_cube .interpolate (
160+ [("time" , m_tpoints )], iris .analysis .Linear ()
161+ )
162+ # Place the interpolated data back
163+ # into the interleaved target indices
164+ new_cube .data [m - 1 :: MONTHS_IN_A_YEAR ] = m_interpolated .data
165+
166+ # Clean up month_number coordinate if added
167+ if cube .coords ("month_number" ):
168+ cube .remove_coord ("month_number" )
169+
170+ return new_cube
171+
172+
140173def interpolate_monthly (cube , beg_year , end_year ):
141174 # Get original time units and calendar
142175 time_coord = cube .coord ("time" )
@@ -166,34 +199,8 @@ def interpolate_monthly(cube, beg_year, end_year):
166199 dtype = np .float64 ,
167200 )
168201
169- # Perform linear time-interpolation
170- new_cube = cube .interpolate ([("time" , tpoints )], iris .analysis .Linear ())
171- new_cube .data = np .ma .asarray (new_cube .data )
172-
173- # Add month categorisation to extract each month's series
174- if not cube .coords ("month_number" ):
175- iris .coord_categorisation .add_month_number (
176- cube , "time" , name = "month_number"
177- )
178-
179202 # Interpolate each month separately and interleave the data
180- for m in range (1 , MONTHS_IN_A_YEAR + 1 ):
181- month_constraint = iris .Constraint (month_number = m )
182- m_cube = cube .extract (month_constraint )
183- if m_cube is not None :
184- # Select target time points for this month across all years
185- m_tpoints = tpoints [m - 1 :: MONTHS_IN_A_YEAR ]
186- # Interpolate across the years for this month
187- m_interpolated = m_cube .interpolate (
188- [("time" , m_tpoints )], iris .analysis .Linear ()
189- )
190- # Place the interpolated data back
191- # into the interleaved target indices
192- new_cube .data [m - 1 :: MONTHS_IN_A_YEAR ] = m_interpolated .data
193-
194- # Clean up month_number coordinate if added
195- if cube .coords ("month_number" ):
196- cube .remove_coord ("month_number" )
203+ new_cube = _interpolate_months_separately (cube , tpoints )
197204
198205 # Create new DimCoord with contiguous bounds
199206 new_time_coord = iris .coords .DimCoord (
@@ -232,7 +239,6 @@ def interpolate_monthly(cube, beg_year, end_year):
232239 target_idx = tbounds_dict [key ]
233240 new_cube .data [target_idx ] = cube .data [i ]
234241
235- new_cube .data = np .ma .asarray (new_cube .data )
236242 return new_cube
237243
238244
0 commit comments