source: trunk/src/useCorrTb_daily.py @ 694

Last change on this file since 694 was 694, checked in by llmlod, 8 years ago

new chaine

File size: 9.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# import
5from pylab import *
6from ReadRawFile import *
7from datetime import date
8import netCDF4
9from scipy import spatial
10from mpl_toolkits.basemap import pyproj
11import itertools as it
12import time
13
14##-------------------------------##
15#     Class for satellite name    #
16##-------------------------------##
17class SatName: 
18    """ ### Defined a number for each satellite """
19    def __init__(self):
20        self.satname = array(['AMSUBN15','AMSUBN16','MHSN18','MHSN19','MHSM01','MHSM02'])
21        self.satnum  = arange(size(self.satname))+1
22
23    def get_satnum(self,name):
24        return concatenate([self.satnum[nn == self.satname] for nn in name])
25   
26    def get_satname(self,num):
27        return concatenate([self.satname[nn == self.satnum] for nn in num])
28
29##-------------------------------##
30#     Correction for one orbit    #
31##-------------------------------##
32def applycorr2orb(fname,lonvec,latvec,ch=['All'],area=[-35.,35.,-180.,180.]):
33    """ ### Apply correction to AMSU or MHS orbit
34    ## Inputs
35    # fname  = file name
36    # tstep  = time resolution for new grid in minutes
37    # lonvec = longitude vecteur of new grid
38    # latvec = latitude vecteur of new grid
39    # ch     = list of extrated channel ('B1','B2','B3','B4','B5' or 'All'), default 'All'
40    # area   = limits [LS,LN,LW,LE] for extracted area, default is world (ie [-35.,35.,-180.,180.])
41    #
42    # Outputs
43    # tbcorrm = brightness temperature of orbit in new grid
44    # trefm   = ordinal time
45    #
46    """
47
48    t=time.time()
49    # ## Read orbit file
50    # print 'Read ', fname
51    lon, lat, dt, tb, fov = load_amsub_mhs(fname,ch,area)
52
53    try:
54        # ##  Class of each orbit points
55        # print 'Classification'
56        clz = find_class(lat,lon)
57        nozero = (clz != 0)
58
59    except ValueError:
60        print 'Orbit is out of the area:', fname
61        return [], [], []
62
63    else:
64        # ## Coef of correction as a function of classification, fov and day of year
65        # print 'Correction'
66        coefz = find_corrcoef(dt[nozero],fov[nozero],clz[nozero],ch=ch)
67        tbcorr = array(tb)[:,nozero] - coefz
68        # ## Average on new grid
69        tbcorrm, tobsm = newgrid(lonvec,latvec,lon[nozero],lat[nozero],dt[nozero],tbcorr)
70   
71    print 'Deal', fname, 'in:', time.time()-t
72
73    return tbcorrm, tobsm, fname.split('/')[3]
74
75##----------------------------------##
76#      Read AMSU-B and MHS files     #
77##----------------------------------##
78def load_amsub_mhs(fname,ch,area):
79    """ ### Read AMSU-B and MHS files
80    ## Inputs
81    # fname = file name
82    # ch    = list of extrated channel ('B1','B2','B3','B4','B5' or 'All'), default 'All'
83    # area  = limits [LS,LN,LW,LE] for extracted area, default is world (ie [-35,35,-180.,180])
84    #
85    ## Outputs
86    # lon  = Longitude
87    # lat  = Latitude
88    # yday = Day of year
89    # tms  = UTC time in milliseconds
90    # tb   = Brightness temperature for each channel
91    # err  = 1 if reading error, 0 else
92    #
93    """
94
95    # Index of channel
96    ch=[cch.lower() for cch in ch]
97    if (ch[0] == 'all'):
98        ich = arange(5)
99    else:
100        ich = array([int(cch[1])-1  for cch in ch])
101
102    # Variables
103    dset_names = ['amb1c_latlon','amb1c_btemps','amb1c_scnlindy','amb1c_scnlintime','amb1c_scnlinyr']
104    try:
105        headers, datasets = ReadRawFile(fname,'/home/mleduc/python/ReadRawFile/data/amsub-mhs_1c_header.txt','/home/mleduc/python/ReadRawFile/data/amsub-mhs_1c_record.txt', False,dset_names)   
106    except:
107        print 'Error with %s'%fname
108        # continue
109        return 
110
111    # Latitude
112    lat = float32(datasets['amb1c_latlon'][:,:,0]/1.E4)
113    # Longitude
114    lon = float32(datasets['amb1c_latlon'][:,:,1]/1.E4)
115    # Year
116    yyyy= datasets['amb1c_scnlinyr']
117    # Day of Year
118    yday= datasets['amb1c_scnlindy']
119    # Time in milliseconds
120    tms = datasets['amb1c_scnlintime']
121    # Tb
122    tb  = float32(datasets['amb1c_btemps'][:,:,ich]/1.E2)
123    # Remplace fill values -9999.99 by NaN
124    tb[(tb == -9999.99)] = NaN
125
126    ### Extract Area
127    # Index in the defined area
128    LS, LN, LW, LE = area
129    zone = (lon>=LW) & (lon<=LE) & (lat>=LS) & (lat<=LN)
130    nscn, nfov, nch = tb.shape
131    # Extraction of Tb for each channel
132    tb = [(tb[:,:,ii])[zone] for ii in xrange(nch)]
133    # day of year and time
134    yyyy = transpose([yyyy]*nfov)[zone]
135    yday = transpose([yday]*nfov)[zone]
136    tms  = transpose([tms]*nfov)[zone]
137    # Find location in fov
138    fov = array(range(nfov)*nscn).reshape(nscn,nfov)[zone]+1
139
140    ### Convert in python date/time
141    dd = num2date(yday)
142    tt = [ms2time(ms) for ms in tms]
143    dt = array([d.replace(year=y,hour=h,minute=m,second=s) for d,y,(h,m,s) in zip(dd,yyyy,tt)])
144
145    return lon[zone], lat[zone], dt, tb, fov
146
147##-----------------------------------------------------##
148#      Convert milliseconds in hour, minute, second     #
149##-----------------------------------------------------##
150def ms2time(ms):
151    """ ### Convert milliseconds in hour, minute, second
152    # Warning 1: lost millisecond because second is integer 2) no day
153    # Warning 2: no day
154    ## Inputs
155    # ms  = millisecond
156    #
157    ## Output
158    # h = hour
159    # m = minute
160    # s = second
161    #
162    """
163    s    = ms/1000
164    m, s = divmod(s,60)
165    h, m = divmod(m,60)
166    #d, h = divmod(h,24)
167    return h, m, s
168
169##---------------------##
170#      Find classes     #
171##---------------------##
172def find_class(lat,lon):
173    """ ### Find class of each given (lat,lon)
174    ## Inputs
175    # lat  = Latitude (degrees)
176    # lon  = Longitude (degrees)
177    #
178    ## Output
179    # clpt = class of each point (same shape as lat and lon)
180    #
181    """
182
183    # Read the classification file
184    fic_class = '/homedata/mleduc/CorrTb/classifERAI_Trop.nc'
185    fileID = netCDF4.Dataset(fic_class)
186    lat_class = fileID.variables['lat'][:]
187    lon_class = fileID.variables['lon'][:]
188    classif   = int16(fileID.variables['classif_tot'][:])
189    fileID.close()
190
191    # Latitude limits of classification (ie tropical band)
192    latstep = abs(diff(lat_class))[0]
193    latmin = lat_class.min()-latstep/2.
194    latmax = lat_class.max()+latstep/2.
195    # Only points in the area of classification
196    inclass = logical_and(lat>=latmin,lat<=latmax)
197
198    # Geographic projection (lon/lat in degrees to x/y in m)
199    projG = pyproj.Proj("+proj=merc +ellps=WGS84 +datum=WGS84")
200    longd_class,latgd_class = meshgrid(lon_class,lat_class)
201    xclass,yclass = projG(longd_class,latgd_class)
202    xx,yy = projG(lon[inclass],lat[inclass]) 
203
204    # Find the nearest neighbour (euclidian distance) with a kd-tree
205    tree = spatial.cKDTree(zip(ravel(xclass),ravel(yclass)))
206    _, ind = tree.query(zip(xx,yy))
207    clpt = zeros(shape(lat),dtype=int16)
208    clpt[inclass] = classif.flatten()[ind]
209
210    return clpt
211
212##-------------------------------------------##
213#      Find the coefficient of correction     #
214##-------------------------------------------##
215def find_corrcoef(dt,fov,cl,ch=['All']):
216    """ ### Find the coefficient of correction
217    ## Inputs
218    # dt  = Python date
219    # fov = Location in the swath
220    # cl  = Class
221    # ch  = list of extrated channel ('B1','B2','B3','B4','B5' or 'All'), default 'All'
222    #
223    ## Outputs
224    # coef = Coefficient of correction
225    #
226    """
227    # Index of channel
228    ch=[cch.lower() for cch in ch]
229    if (ch[0] == 'all'):
230        ich = arange(5)
231    else:
232        ich = array([int(cch[1])-1  for cch in ch])
233    nch = ich.size
234   
235    # Read the classification file
236    fic_corr = '/homedata/mleduc/CorrTb/corrTb_AMSUB_MHS_L1C.nc'
237    fileID = netCDF4.Dataset(fic_corr)
238    day_corr  = fileID.variables['day'][:]
239    coef_corr = fileID.variables['coefcorr'][:,:,:,ich]#[:]
240    fileID.close()
241
242    # Find the day of year
243    yday = array([d.timetuple().tm_yday for d in dt])
244    # Find the day of correction
245    nday = day_corr.size
246    daystep = diff(day_corr)[0]
247    icorr = list(flatten([[ii]*daystep for ii in xrange(nday)])) + [0]*6
248    iday = array(icorr)[yday-1]
249
250    # Find correction
251    noclass = (cl == 0)
252    icl  = array(cl-1,dtype=int)
253    ifov = array(fov-1,dtype=int)
254    coef = []
255    for ii in ich:
256        dd = zeros(cl.shape)+NaN
257        dd[~noclass] = coef_corr[iday[~noclass],icl[~noclass],ifov[~noclass],ii]
258        coef.append(dd)
259
260    return float32(coef)
261
262##---------------------------##
263#      New grid and time      #
264##---------------------------##
265def newgrid(lonvec,latvec,lon,lat,dt,tb):
266    """ ### Find the coefficient of correction
267    ## Inputs
268    #
269    #
270    ## Outputs
271    #
272    #
273    """
274
275    # from date to ordinal
276    dtord = date2num(dt)
277
278    ### Find index of each pixel in new grid 
279    # Geographic projection (lon/lat in degrees to x/y in m)
280    projG = pyproj.Proj("+proj=merc +ellps=WGS84 +datum=WGS84")
281    longd, latgd = meshgrid(lonvec,latvec)
282    xgd, ygd = projG(longd,latgd)
283    xx, yy = projG(lon,lat) 
284    # Find the nearest neighbour (euclidian distance) with a kd-tree
285    tree = spatial.cKDTree(zip(ravel(xgd),ravel(ygd)))
286    _, indll = tree.query(zip(xx,yy))
287
288    # Mean
289    nch = tb.shape[0]
290    tbm = zeros((nch,lonvec.size*latvec.size),dtype=float32)+NaN
291    dtm = zeros((lonvec.size*latvec.size))+NaN
292    for ii in unique(indll):
293        tbm[:,ii] = nanmean(tb[:,(indll==ii)],axis=1)
294        dtm[ii]  = nanmean(dtord[(indll==ii)])
295
296    return tbm, dtm
Note: See TracBrowser for help on using the repository browser.