Skip to content

Commit 804b884

Browse files
committed
use lon w [-180,180] for ERA5
The constraint of [0, 360] for longitude is not native to the ERA5 dataset, and it cause problems for dataset crossing 0 deg lon (insarlab/MintPy#447). Thus, I revert it back to [-180, 180] for ERA5/ERAINT/HRES dataset. + era.py: comment the lons range conversion and use the native [-180, 180] range instead, which is more Earth friendly. + objects.py: - for grib in ERA5, ERAINT, and HRES, make sure the longitude are within [-180, 180] range - remote the commented out code body as it's not been used and one could always go back to the git history for reference if needed.
1 parent 187797f commit 804b884

File tree

2 files changed

+25
-149
lines changed

2 files changed

+25
-149
lines changed

pyaps3/era.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ def get_era(fname,minlat,maxlat,minlon,maxlon,cdic, humidity='Q',verbose=False):
8989
grbs = pygrib.open(fname)
9090
grbs.seek(gphind[0])
9191
grb=grbs.read(1)[0]
92-
lats,lons = grb.latlons()
93-
g = cdic['g']
92+
lats, lons = grb.latlons()
93+
g = cdic['g']
9494
mask = (lats > minlat) & (lats < maxlat) & (lons > minlon) & (lons < maxlon)
9595
[ii,jj] = np.where(mask == True)
9696
del mask
@@ -99,20 +99,20 @@ def get_era(fname,minlat,maxlat,minlon,maxlon,cdic, humidity='Q',verbose=False):
9999
nstn = len(ii)
100100

101101
####Create arrays for 3D storage
102-
gph = np.zeros((nlvls, nstn)) #Potential height
102+
gph = np.zeros((nlvls, nstn)) #Potential height
103103
tmp = gph.copy() #Temperature
104104
vpr = gph.copy() #Vapor pressure
105105
if verbose:
106106
print('Number of stations:', nstn)
107107

108-
lvls = 100.0*lvls #Conversion to absolute pressure
108+
lvls = 100.0*lvls #Conversion to absolute pressure
109109
for i in range(nlvls):
110-
grbs.seek(gphind[i]) #Reading potential height.
110+
grbs.seek(gphind[i]) #Reading potential height.
111111
grb = grbs.read(3)
112112
val = grb[0].values
113113
gph[i,:] = val[ii,jj]/g
114114

115-
val = grb[1].values #Reading temperature
115+
val = grb[1].values #Reading temperature
116116
temp = val[ii,jj]
117117
tmp[i,:] = temp
118118

@@ -125,7 +125,7 @@ def get_era(fname,minlat,maxlat,minlon,maxlon,cdic, humidity='Q',verbose=False):
125125
vpr[i,:] = temp*esat
126126

127127
elif humidity in ('Q'):
128-
val = grb[2].values #Specific humidity
128+
val = grb[2].values #Specific humidity
129129
temp = val[ii,jj]
130130
vpr[i,:] = temp*lvls[i]*alpha/(1+(alpha - 1)*temp)
131131

@@ -138,7 +138,7 @@ def get_era(fname,minlat,maxlat,minlon,maxlon,cdic, humidity='Q',verbose=False):
138138

139139
########Read in ERA data from a given ERA Interim file##################
140140
def get_ecmwf(model,fname,minlat,maxlat,minlon,maxlon,cdic, humidity='Q',verbose=False):
141-
'''Read data from ERA Interim, ERA-5 or HRES grib file. Note that Lon values should be between [0-360].
141+
'''Read data from ERA Interim, ERA-5 or HRES grib file. Note that Lon values should be between [-180, 180].
142142
Modified by A. Benoit, January 2019.
143143
144144
Args:
@@ -189,19 +189,18 @@ def get_ecmwf(model,fname,minlat,maxlat,minlon,maxlon,cdic, humidity='Q',verbose
189189
grbs = pygrib.open(fname)
190190
grbs.seek(gphind[0])
191191
grb = grbs.read(1)[0]
192-
lats,lons = grb.latlons()
193-
if model == 'ERA5':
194-
lons[lons < 0.] += 360.
192+
lats, lons = grb.latlons()
193+
#if model == 'ERA5':
194+
# lons[lons < 0.] += 360.
195195
g = cdic['g']
196-
196+
197+
#extract indices
197198
mask = ((lats > minlat) & (lats < maxlat)) & ((lons > minlon) & (lons < maxlon))
198-
#extrqct indices
199199
uu = [i for i in list(range(np.shape(mask)[0])) if any(mask[i,:])]
200200
vv = [j for j in list(range(np.shape(mask)[1])) if any(mask[:,j])]
201201

202202
latlist = lats[uu,:][:,vv]
203203
lonlist = lons[uu,:][:,vv]
204-
#nstn = len(lat.flatten())
205204
nlat, nlon = latlist.shape
206205

207206
####Create arrays for 3D storage

pyaps3/objects.py

Lines changed: 12 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,21 @@ def __init__(self, gribfile, dem, lat, lon, inc=0.0, mask=None,
103103
self.dict = processor.initconst()
104104

105105
# Get some scales
106-
if grib in ('ERA5','ERAINT','HRES'):
106+
if self.grib in ('ERA5','ERAINT','HRES'):
107107
self.hgtscale = ((self.dict['maxAlt']-self.dict['minAlt'])/self.dict['nhgt'])/0.703
108108
self.bufspc = 1.2
109-
elif grib in ('NARR'):
109+
elif self.grib in ('NARR'):
110110
self.hgtscale = ((self.dict['maxAlt']-self.dict['minAlt'])/self.dict['nhgt'])/0.3
111111
self.bufspc = 1.2
112-
elif grib in ('MERRA'):
112+
elif self.grib in ('MERRA'):
113113
self.hgtscale = ((self.dict['maxAlt']-self.dict['minAlt'])/self.dict['nhgt'])/0.5
114114
self.bufspc = 1.0
115115

116116
# Problems in isce when lon and lat arrays have weird numbers
117-
self.lon[self.lon < 0.] += 360.0
117+
if self.grib in ('ERA5','ERAINT','HRES'):
118+
self.lon[self.lon > 180.] -= 360.
119+
else:
120+
self.lon[self.lon < 0.] += 360.0
118121
self.minlon = np.nanmin(self.lon[np.nonzero(self.mask)]) - self.bufspc
119122
self.maxlon = np.nanmax(self.lon[np.nonzero(self.mask)]) + self.bufspc
120123
self.minlat = np.nanmin(self.lat[np.nonzero(self.mask)]) - self.bufspc
@@ -288,8 +291,11 @@ def getdelay(self, dataobj, wvl=np.pi*4., writeStations=True):
288291
loni = self.lon[m,:]*self.mask[m,:]
289292

290293
# Remove negative values
291-
loni[loni<0.] += 360.
292-
294+
if self.grib in ('ERA5','ERAINT','HRES'):
295+
loni[loni > 180.] -= 360.
296+
else:
297+
loni[loni < 0.] += 360.
298+
293299
# Remove NaN values
294300
ii = np.where(np.isnan(lati))
295301
jj = np.where(np.isnan(loni))
@@ -322,132 +328,3 @@ def getdelay(self, dataobj, wvl=np.pi*4., writeStations=True):
322328
# All done
323329
return
324330

325-
#######################################################################################
326-
# WRITE STATIONS INFOS TO FILE
327-
328-
#if writeStations:
329-
# stations_latfile = os.path.join(os.path.dirname(self.gfile),'latStations.txt')
330-
# stations_lonfile = os.path.join(os.path.dirname(self.gfile),'lonStations.txt')
331-
# if self.verb:
332-
# print('SAVING STATIONS LATITUDES in: {}'.format(stations_latfile))
333-
# print('SAVING STATIONS LONGITUDES in: {}'.format(stations_lonfile))
334-
# np.savetxt(stations_latfile, self.latlist, fmt=['%1.2f'])
335-
# np.savetxt(stations_lonfile, self.lonlist, fmt=['%1.2f'])
336-
337-
# for station in range(0,len(self.lonlist)):
338-
# # Open file output
339-
# sfile = 'station{}_{}.txt'.format(station,
340-
# os.path.splitext(os.path.basename(self.gfile))[0])
341-
# stationFile = os.path.join(os.path.dirname(self.gfile), sfile)
342-
# myfile = open(stationFile, 'w')
343-
# # Iterate over altitude level
344-
# for i in range(self.Delfn_1m.shape[0]):
345-
# altitudeValue = kh[i]
346-
# phaseValue = self.Delfn_1m[i,:,:].flatten()[station]
347-
# # Write file
348-
# myfile.write("{} {}\n".format(altitudeValue, phaseValue))
349-
# myfile.close()
350-
#
351-
# # Save kh into file
352-
# khfile = os.path.join(os.path.dirname(self.gfile), 'kh.txt')
353-
# np.savetxt(khfile, kh, newline='\n', fmt="%s")
354-
355-
########################################################################################
356-
## CUBIC INTERPOLATION
357-
358-
## Create bicubic interpolator
359-
#if self.verb:
360-
# print('PROGRESS: CREATE THE CUBIC INTERPOLATION FUNCTION')
361-
362-
## Resize
363-
#lonn, hgtn = np.meshgrid(self.lonlist, self.hgt)
364-
#latn, hgtn = np.meshgrid(self.latlist, self.hgt)
365-
366-
## Define a cubic interpolating function on the 3D grid: ((x, y, z), data)
367-
#cubicint = si.Rbf(lonn.flatten(), latn.flatten(), hgtn.flatten(), self.Delfn.flatten(),kind='cubic',fill_value = 0.0)
368-
369-
## Show progress bar
370-
#if self.verb:
371-
# toto = utils.ProgressBar(maxValue=self.ny)
372-
# print('PROGRESS: MAPPING THE DELAY')
373-
374-
## Loop on the lines
375-
#for m in range(self.ny):
376-
377-
# # Update progress bar
378-
# if self.verb:
379-
# toto.update(m+1, every=5)
380-
381-
# ###############################################
382-
# ## Get values of the m line
383-
384-
# ## Longitude
385-
# #print(self.lonlist.shape)
386-
# #Lonu = np.unique(self.lonlist)
387-
# #nLon = len(Lonu)
388-
# #lonlisti = Lonu
389-
390-
# ## Latitude by iterating over self.latlist
391-
# #if m == 0:
392-
# # pos1 = 0
393-
# # pos2 = nLon
394-
# #else:
395-
# # pos1 = pos1 + nLon
396-
# # pos2 = pos2 + nLon
397-
# #lonlisti = Lonu
398-
# #latlisti = self.latlist[pos1:pos2]
399-
400-
# ## Height
401-
# #hgtlisti = self.hgt
402-
# #
403-
# ## Delay by iterating over self.Delfn
404-
# #print(self.Delfn.shape)
405-
# #Delfni = (self.Delfn[pos1:pos2,:]).T
406-
407-
# ###############################################
408-
# ## Define a cubic interpolating function on the 3D grid: ((x, y, z), data)
409-
# #
410-
# #lonn, hgtn = np.meshgrid(lonlisti, hgtlisti)
411-
# #latn, hgtn = np.meshgrid(latlisti, hgtlisti)
412-
# #cubicint = si.Rbf(lonn.flatten(), latn.flatten(), hgtn.flatten(), Delfni.flatten(), kind='cubic',fill_value = 0.0)
413-
# #
414-
# ###############################################
415-
416-
# # Get latitude and longitude arrays
417-
# lati = self.lat[m,:]*self.mask[m,:]
418-
# loni = self.lon[m,:]*self.mask[m,:]
419-
420-
# # Remove negative values
421-
# loni[loni<0.] += 360.
422-
#
423-
# # Remove NaN values
424-
# ii = np.where(np.isnan(lati))
425-
# jj = np.where(np.isnan(loni))
426-
# xx = np.union1d(ii,jj)
427-
# lati[xx]=0.0
428-
# loni[xx]=0.0
429-
430-
# # Get incidence if file provided
431-
# if incFileFlag=='array':
432-
# cinc = np.cos(self.mask[m,:]*self.inc[m,:]*np.pi/180.)
433-
434-
# # Make the interpolation
435-
# hgti = self.dem[m,:]
436-
# val = cubicint(loni.flatten(), lati.flatten(), hgti.flatten())
437-
# val[xx] = np.nan
438-
439-
# # Write outfile
440-
# if outFile:
441-
# resy = val.astype(np.float32)
442-
# resy.tofile(fout)
443-
# else:
444-
# dataobj[m,:] = val
445-
446-
#if self.verb:
447-
# toto.close()
448-
449-
#if outFile:
450-
# fout.close()
451-
452-
## All done
453-
#return

0 commit comments

Comments
 (0)