Diwan
Diwan

Reputation: 1

how to subset a netcdf file using latlong details and rewrite to a new nc file?

I am trying to subset a netcdf file using latlong. I have created the file but it is not opening by ncdump

I tried like this

from netCDF4 import *
from numpy import *
import time

#Read and subset
nc_file = Dataset('D:\\R_Workspace\\19971207.nc','r')

latbound = [16,20]
longbound = [73,77]

lats = nc_file.variables['Latitude'][:]
lons = nc_file.variables['Longitude'][:]

lat_lb = argmin(abs(lats-latbound[0]))
lat_ub = argmin(abs(lats-latbound[1]))

lon_lb = argmin(abs(lons-longbound[0]))
lon_ub = argmin(abs(lons-longbound[1]))

sm_sub = nc_file.variables['soil_moisture_x'][lon_lb:lon_ub,lat_ub:lat_lb]
lat_sub = nc_file.variables['Latitude'][lat_ub:lat_lb]
lon_sub = nc_file.variables['Longitude'][lon_lb:lon_ub]
nc_file.close()

#write to new file
my_file = Dataset('D:\\R_Workspace\\subset\\19971207.nc','w', format = 'NETCDF4')

my_file.discription = 'SM-TRMM-night_UB-subset'
my_file.history = 'Created on: ' +time.ctime(time.time())

#Dimensions
ldim = lat_lb-lat_ub # getting the no of element
lndim = lon_ub-lon_lb

lon = my_file.createDimension('lon',lndim)
lat = my_file.createDimension('lat',ldim)

#Variables
latitude = my_file.createVariable('Latitude',float32,('lat',))
latitude.units = 'Degree_north'
longitude = my_file.createVariable('Longitude',float32,('lon',))
longitude.units = 'Degree_east'

sm = my_file.createVariable('SM',float32,('lon','lat'),fill_value = -9999.0)
sm.units = 'percent'

#Load values to the variables
latitude[:] = lat_sub
longitude[:] = lon_sub
sm[:] = sm_sub
my_file.close()

the code is not giving any error but created nc file is not proper and ncdump is also failed to open it. Pls help me to sort out this problem. Thank you for your valuable time.

Upvotes: 0

Views: 1320

Answers (3)

Robert Wilson
Robert Wilson

Reputation: 3397

This can be done on Unix systems in a few lines using my nctoolkit (https://nctoolkit.readthedocs.io/en/latest/) package:

import nctoolkit as nc
ds = nc.open_data("infile.nc")

latbound = [16,20]
longbound = [73,77]

ds.crop(lon = longbound, lat = latbound)
ds.to_nc("outfile.nc")

Upvotes: 1

N1B4
N1B4

Reputation: 3453

sm_sub is 2D:

sm_sub = nc_file.variables['soil_moisture_x'][lon_lb:lon_ub,lat_ub:lat_lb]

You're correctly declaring the output variable sm as a 2D variable (lat x lon) here:

sm = my_file.createVariable('SM',float32,('lon','lat'),fill_value = -9999.0)

but only writing out 1-dimension:

sm[:] = sm_sub

So that line needs to change to:

sm[:,:] = sm_sub[:,:]

Upvotes: 1

Eric Bridger
Eric Bridger

Reputation: 3794

I'd try copying over the global attributes from ncfile to myfile

 g_attdict = ncfile.__dict__

...

myfile.setncatts(g_attdict)

Upvotes: 1

Related Questions