source: trunk/src/useCorrTb_daily.py @ 700

Last change on this file since 700 was 700, checked in by pinsard, 8 years ago

log in modules

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