On 10/25/10 2:27 AM, John wrote:
> Hello,
>
> I'm trying to take a npstereographic grid of points and reproject it
> so that I can save out a file in regular 0.5 degree lat lon grid
> coordinates. The description of the grid points in the current
> projection is here:
> http://nsidc.org/data/docs/daac/nsidc0051_gsfc_seaice.gd.html
>
> I've written the following class for handling the data:
>
> class NSIDC(object):
>      """ Maybe a set of functions for NSIDC data """
>
>      def __init__(self,infile):
>          self.infile = infile
>          self.data = self.readseaice()
>
>      def readseaice(self):
>          """ reads the binary sea ice data and returns
>              the header and the data
>              see: 
> http://nsidc.org/data/docs/daac/nsidc0051_gsfc_seaice.gd.html
>          """
>          #use the BinaryFile class to access data
>          from francesc import BinaryFile
>          raw = BinaryFile(self.infile,'r')
>
>          #start reading header values
>          """
>          File Header
>          Bytes    Description
>          1-6    Missing data integer value
>          7-12    Number of columns in polar stereographic grid
>          13-18    Number of rows in polar stereographic grid
>          19-24    Unused/internal
>          25-30    Latitude enclosed by pointslar stereographic grid
>          31-36    Greenwich orientation of polar stereographicic grid
>          37-42    Unused/internal
>          43-48    J-coordinate of the grid intersection at the pole
>          49-54    I-coordinate of the grid intersection at the pole
>          55-60    Five-character instrument descriptor (SMMR, SSM/I)
>          61-66    Two descriptionriptors of two characters each that
> describe the data;
>              for example, 07 cn = Nimbus-7 SMMR ice concentration
>          67-72    Starting Julian day of grid dayta
>          73-78    Starting hour of grid data (if available)
>          79-84    Starting minute of grid data (if available)
>          85-90    Ending Julian day of grid data
>          91-916    Ending hour of grid data (if available)
>          97-102    Ending minute of grid             data (if available)
>          103-108    Year of grid data
>          109-114    Julian day of gridarea(xld data
>          115-120    Three-digit channel descriptor (000 for ice 
> concentrationns)
>          121-126    Integer scaling factor
>          127-150    24-character file name
>          151-24    Unused3080-character image title
>          231-300   70-character data information (creation date, data
> source, etc.)
>          """
>          hdr = raw.read(np.dtype('a1'),(300))
>          header = {}
>          header['baddata'] = int(''.join(hdr[:6]))
>          header['COLS'] = int(''.join(hdr[6:12]))
>          header['ROWS'] = int(''.join(hdr[12:18]))
>          header['lat'] = float(''.join(hdr[24:30]))
>          header['lon0'] = float(''.join(hdr[30:36]))
>          header['jcoord'] = float(''.join(hdr[42:48]))
>          header['icoord'] = float(''.join(hdr[48:54]))
>          header['instrument'] = ''.join(hdr[54:60])
>          header['descr'] = ''.join(hdr[60:66])
>          header['startjulday'] = int(''.join(hdr[66:72]))
>          header['starthour'] = int(''.join(hdr[72:78]))
>          header['startminute'] = int(''.join(hdr[78:84]))
>          header['endjulday'] = int(''.join(hdr[84:90]))
>          header['endhour'] = int(''.join(hdr[90:96]))
>          header['endminute'] = int(''.join(hdr[96:102]))
>          header['year'] = int(''.join(hdr[102:108]))
>          header['julday'] = int(''.join(hdr[108:114]))
>          header['chan'] = int(''.join(hdr[114:120]))
>          header['scale'] = int(''.join(hdr[120:126]))
>          header['filename'] = ''.join(hdr[126:150])
>          header['imagetitle'] = ''.join(hdr[150:230])
>          header['datainfo'] = ''.join(hdr[230:300])
>
>          #pdb.set_trace()
>
>
>          seaiceconc = raw.read(np.uint8,(header['COLS'],header['ROWS']))
>
>          return {'header':header,'data':seaiceconc}
>
>      def conv2percentage(self):
>          self.seaicepercentage = self.data['data']/2.5
>
>      def classify(self):
>          """ classify the data into land, coast, missing, hole """
>          data = self.data['data']
>          self.header = self.data['header']
>
>          for a in [('land',254),('coast',253),('hole',251),('missing',255)]:
>              zeros = np.zeros(data.shape)
>              zeros[np.where(data==a[1])] = 1
>              exec('self.%s = zeros' % a[0])
>
>          #filter data
>          data[data>250] = 0
>          self.ice = data
>
>      def geocoordinate(self):
>          """ use NSIDC grid files to assign lats/lons to grid.
>          see: 
> http://nsidc.org/data/polar_stereo/tools_geo_pixel.html#psn25_pss25_lats
>          """
>
>          try:
>              ROWS = self.header['ROWS']
>              COLS = self.header['COLS']
>          except:
>              raise AttributeError('object needs to have header, \
>                      did you run self.classify?')
>
>          datadir = 'nsidc0081_ssmi_nrt_seaice'
>
>          lonfile = os.path.join(datadir,'psn25lons_v2.dat')
>          lons = np.fromfile(lonfile,dtype=np.dtype('i4'))/100000.
>          self.lons = lons.reshape(COLS,ROWS)
>
>          latfile = os.path.join(datadir,'psn25lats_v2.dat')
>          lats = np.fromfile(latfile,dtype=np.dtype('i4'))/100000.
>          self.lats = lats.reshape(COLS,ROWS)
>
>          areafile = os.path.join(datadir,'psn25area_v2.dat')
>          area = np.fromfile(latfile,dtype=np.dtype('i4'))/100000.
>          self.area = area.reshape(COLS,ROWS)
>
>
>
>
> Once I have the data in python, I've done some plotting with some
> weird results, I'm clearly not doing something correctly. I'd like to
> know the best way to do this, and I suspect it would require GDAL.
> Here's what I'm trying to do:
>
> from NSIDC import NSIDC
> import numpy as np
> from matplotlib import mlab, pyplot as plt
>
> #load the data
> d = jfb.NSIDC('nsidc0081_ssmi_nrt_seaice/nt_20080827_f17_nrt_n.bin')
> d.classify()
> d.geocoordinate()
>
> x = d.lons.ravel(); y = d.lats.ravel(); z = d.ice.ravel()
>
> #create a regular lat/lon grid 0.5 degrees
> dres=0.5
> reg_lon = np.arange(-180,180,dres,'f')
> reg_lat=np.arange(-90,90,dres,'f')
>
> #regrid the data into the regular grid
> Z = mlab.griddata(x,y,z,reg_lon,reg_lat)
>
>
>
> My result is confusing:
> plotting the data as imshow, demonstrates I'm loading it okay:
> plt.imshow(d.ice)
> yields:
> http://picasaweb.google.com/washakie/Temp#5531888474069952818
>
> however, if I try to plot the reprojected grid on to a map, I get
> something strange:
> http://picasaweb.google.com/washakie/Temp#5531888480458500386
>
> But if I use the same map object to plot my original data using the
> scatter function:
> m.scatter(x,y,c=z)
> I also get a strange result, so possibly I'm not reading the grid in
> properly, but it seems strange, since all the 'points' are where they
> are supposed to be, but I would not expect this color pattern:
> http://picasaweb.google.com/washakie/Temp#5531895787146118914
>
>
> Is anyone willing to write a quick tutorial or script on how this
> would be achieved properly in gdal or basemap?
>
> Thanks,
> john
>
>
John:  Basemap provides an 'interp' function that can be used to 
reproject data from one projection grid to another using bilinear 
interpolation.

http://matplotlib.sourceforge.net/basemap/doc/html/api/basemap_api.html#mpl_toolkits.basemap.interp

griddata is really for unstructured, scattered data.  Since you have a 
regular grid, interp should be much faster.  In your case, this should 
do it (untested).

import numpy as np
from mpl_toolkits.basemap import Basemap, interp
# from http://nsidc.org/data/polar_stereo/ps_grids.html
a = 6378.273e3
ec = 0.081816153
b = a*np.sqrt(1.-ec**2)
map =\
Basemap(projection='stere',lat_0=90,lon_0=315,lat_ts=70,
         llcrnrlat=33.92,llcrnrlon=279.96,urcrnrlon=102.34,urcrnrlat=31.37,
         rsphere=(a,b))
# Basemap coordinate system starts with 0,0 at lower left corner
xin = np.linspace(map.xmin,map.xmax,nx) # nx is the number of x points 
on the grid
yin = np.linspace(map.ymin,map.ymax,ny) # ny in the number of y points 
on the grid
# 0.5 degree grid
lons = np.arange(-180,180.01,0.5)
lats  = np.arange(-90,90.01,0.5)
lons, lats = np.meshgrid(lons,lats)
xout,yout = map(lons, lats)
# datain is the data on the nx,ny stereographic grid.
# masked=True returns masked values for points outside projection grid
dataout = interp(datain, xin, yin, xout, yout,masked=True)

-Jeff




------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in  U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store 
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to