source: trunk/SRC/Grid/micromeshmask.pro @ 455

Last change on this file since 455 was 451, checked in by smasson, 13 years ago

update meshmask related file for full compatibility with partial steps

  • Property svn:keywords set to Id
File size: 11.0 KB
Line 
1;+
2;
3; @file_comments
4; Reduce the size of the NetCDF meshmask created by OPA by
5; using bit (and not byte) format for the masks and the float format
6; for the other fields.
7;
8; @categories
9; For OPA
10;
11; @param inid {in}{required}
12;
13; @param outid {in}{required}
14;
15; @param inname {in}{required}
16;
17; @param outname {in}{optional}
18;
19; @history
20;      July 2004 Sebastien Masson (smasson\@lodyc.jussieu.fr)
21;
22; @version
23; $Id$
24;
25;-
26PRO ncdf_transfer, inid, outid, inname, outname
27;
28  compile_opt idl2, strictarrsubs
29;
30  IF n_elements(outname) EQ 0 THEN outname = inname
31  ncdf_varget, inid, inname, zzz
32  ncdf_varput, outid, outname, float(reform(zzz, /over))
33  RETURN
34END
35;
36;+
37;
38; @param ncfilein {in}{required}
39; 1) the name of the meshmask file to be reduced. In that case,
40; there is only one meshmask file
41;
42; OR
43;
44; 2) the xxx part in the names: xxx.mesh_hgr.nc xxx.mesh_zgr.nc
45; xxx.mask.nc. In that case, the meshmask is split into 3 files.
46;
47; @param ncfileout {in}{optional} {default='micromeshmask.nc'}
48; the name of the uniq reduced meshmask file.
49;
50; @keyword IODIR
51; to define the files path.
52;
53; @examples
54;
55;   IDL> meshdir='/d1fes2-raid2/smasson/DATA/ORCA05/'
56;   IDL> micromeshmask, 'meshmask_ORCA_R05.nc',iodir=meshdir
57;
58;-
59PRO micromeshmask, ncfilein, ncfileout, IODIR=iodir
60;
61  compile_opt idl2, strictarrsubs
62;
63  filein = isafile(FILE = ncfilein, IODIR = iodir, /NEW)
64  test = (findfile(filein))[0]
65  IF test EQ '' THEN BEGIN
66    filein_hgr = (findfile(filein+'.mesh_hgr.nc'))[0]
67    filein_zgr = (findfile(filein+'.mesh_zgr.nc'))[0]
68    filein_msk = (findfile(filein+'.mask.nc'))[0]
69    IF filein_hgr EQ '' OR filein_zgr EQ '' OR filein_msk EQ ''  THEN BEGIN
70      ras = report(['meshmask file(s) not found...', $
71      filein+' does not exist', $
72      filein+'.mesh_hgr.nc does not exist', $
73      filein+'.mesh_zgr.nc does not exist', $
74      filein+'.mask.nc does not exist'])
75      return
76    ENDIF
77  ENDIF ELSE filein = test
78;------------------------------------------------------
79;------------------------------------------------------
80; get the horizontal dimensions
81  IF n_elements(filein_hgr) NE 0  THEN cdfid = ncdf_open(filein_hgr) $
82  ELSE cdfid = ncdf_open(filein)
83  ncdf_diminq, cdfid, 'x', name, jpi
84  ncdf_diminq, cdfid, 'y', name, jpj
85; for the mask, we use "its byte" representation -> its y dimension
86; will be extended to be a multiple of 8, then it will be divided by
87; 8. -> if (jpj mod 8) eq 0 the jpj_m=jpi/8 else jpj_m=jpi/8 + 1
88  jpj_m = (jpj+7)/8
89; get the vertical dimensions
90  IF n_elements(filein_zgr) NE 0  THEN BEGIN
91    ncdf_close, cdfid
92    cdfid = ncdf_open(filein_zgr)
93  ENDIF
94  listdims = strlowcase(ncdf_listdims(cdfid))
95  IF (where(listdims EQ 'z'))[0] NE -1 THEN ncdf_diminq, cdfid, 'z', name, jpk ELSE BEGIN
96    dimid = (where(strmid(listdims, 0, 5) EQ 'depth'))[0]
97    IF dimid NE -1 THEN ncdf_diminq, cdfid, dimid, name, jpk ELSE BEGIN
98      dummy = report('We could not find the vertical dimension..., its name must be z or start with depth')
99      return
100    ENDELSE
101  ENDELSE
102; get the variables list related to the partial steps
103  zgr_varlist = ncdf_listvars(cdfid)
104  zgr_varlist = strtrim(strlowcase(zgr_varlist), 2)
105; is e3t a real 3D array?
106  IF (where(zgr_varlist EQ 'e3t'))[0] NE -1 THEN BEGIN
107    varinq = ncdf_varinq(cdfid, 'e3t')
108    if varinq.ndims GE 3 THEN BEGIN
109      ncdf_diminq, cdfid, varinq.dim[0], name, iii
110      ncdf_diminq, cdfid, varinq.dim[1], name, jjj
111      ncdf_diminq, cdfid, varinq.dim[2], name, kkk
112      IF iii EQ jpi AND jjj EQ jpj AND kkk EQ jpk THEN key_e3_3d = 1
113    ENDIF   
114  ENDIF
115; is gdept a real 3D array?
116  IF (where(zgr_varlist EQ 'gdept'))[0] NE -1 THEN BEGIN
117    varinq = ncdf_varinq(cdfid, 'gdept')
118    if varinq.ndims GE 3 THEN BEGIN
119      ncdf_diminq, cdfid, varinq.dim[0], name, iii
120      ncdf_diminq, cdfid, varinq.dim[1], name, jjj
121      ncdf_diminq, cdfid, varinq.dim[2], name, kkk
122      IF iii EQ jpi AND jjj EQ jpj AND kkk EQ jpk THEN key_gdep_3d = 1
123    ENDIF   
124  ENDIF
125;------------------------------------------------------
126;------------------------------------------------------
127;
128;------------------------------------------------------
129; define the output file
130;------------------------------------------------------
131  IF n_elements(ncfileout) EQ 0  THEN ncfileout = 'micromeshmask.nc'
132  cdfidout = ncdf_create(isafile(FILE = ncfileout, IODIR = iodir, /NEW), /clobber)
133  ncdf_control, cdfidout, /nofill
134; dimension
135  dimidx = ncdf_dimdef(cdfidout, 'x', jpi)
136  dimidy = ncdf_dimdef(cdfidout, 'y', jpj)
137  dimidy_m = ncdf_dimdef(cdfidout, 'y_m', jpj_m)
138  dimidz = ncdf_dimdef(cdfidout, 'z', jpk)
139; global attributs
140  ncdf_attput, cdfidout, 'IDL_Program_Name', 'micromeshmask.pro', /GLOBAL
141  ncdf_attput, cdfidout, 'Creation_Date', systime(), /GLOBAL
142; declaration des variables
143  varid = lonarr(20)
144; horizontal variables
145  hgrlist = ['glamt', 'glamu', 'glamv', 'glamf' $
146             , 'gphit', 'gphiu', 'gphiv', 'gphif' $
147             , 'e1t', 'e1u', 'e1v', 'e1f' $
148             , 'e2t', 'e2u', 'e2v', 'e2f']
149  FOR h = 0, n_elements(hgrlist)-1 DO $
150    varid[h] = ncdf_vardef(cdfidout, hgrlist[h], [dimidx, dimidy], /float)
151; vertical variables
152  zgrlist = ['e3t', 'e3w', 'gdept', 'gdepw']
153  FOR z = 0, n_elements(zgrlist)-1 DO $
154    varid[16+z] = ncdf_vardef(cdfidout, zgrlist[z], [dimidz], /float)
155; variables related to the partial steps
156  with_partial = keyword_set(key_e3_3d) OR (where(zgr_varlist EQ 'hdept'))[0] NE -1 $
157                 OR (where(zgr_varlist EQ 'e3tp'))[0] NE -1 $
158                 OR (where(zgr_varlist EQ 'e3t_ps'))[0] NE -1
159  IF with_partial THEN BEGIN
160    varid = [varid, ncdf_vardef(cdfidout, 'hdept', [dimidx, dimidy], /float)]
161    varid = [varid, ncdf_vardef(cdfidout, 'hdepw', [dimidx, dimidy], /float)]
162    varid = [varid, ncdf_vardef(cdfidout, 'e3t_ps', [dimidx, dimidy], /float)]
163    varid = [varid, ncdf_vardef(cdfidout, 'e3w_ps', [dimidx, dimidy], /float)]
164  ENDIF
165;
166  IF (where(zgr_varlist EQ 'mbathy'))[0] NE -1 THEN $
167    varid = [varid, ncdf_vardef(cdfidout, 'mbathy', [dimidx, dimidy], /short)]
168; mask variable
169  msklist = ['tmask', 'umask', 'vmask', 'fmask']
170  FOR m = 0, n_elements(msklist)-1 DO BEGIN
171    varid = [varid, ncdf_vardef(cdfidout, msklist[m] $
172                                , [dimidx, dimidy_m, dimidz], /byte)]
173;     ncdf_attput, cdfidout, varid[n_elements(varid)-1] $
174;       , 'Comment', 'the mask is stored as bit. You must use ' $
175;       +'the binary representation of the byte to get back the data.'
176  ENDFOR
177;------------------------------------------------------
178;------------------------------------------------------
179  ncdf_control, cdfidout, /endef
180;------------------------------------------------------
181;
182; get the horizontal variables
183;
184  IF n_elements(filein_hgr) NE 0  THEN BEGIN
185    ncdf_close, cdfid
186    cdfid = ncdf_open(filein_hgr)
187  ENDIF
188;
189  FOR h = 0, n_elements(hgrlist)-1 DO $
190    ncdf_transfer, cdfid, cdfidout, hgrlist[h]
191;
192; get the vertical variables
193;
194  IF n_elements(filein_zgr) NE 0  THEN BEGIN
195    ncdf_close, cdfid
196    cdfid = ncdf_open(filein_zgr)
197  ENDIF
198;
199  inzgrlist =  zgrlist
200  IF (where(zgr_varlist EQ 'gdept_0'))[0] NE -1 THEN inzgrlist =  inzgrlist+'_0'
201  FOR z = 0, n_elements(zgrlist)-1 DO $
202    ncdf_transfer, cdfid, cdfidout, inzgrlist[z], zgrlist[z]
203; partial step variables
204  IF (where(zgr_varlist EQ 'hdept' ))[0] NE -1 THEN ncdf_transfer, cdfid, cdfidout, 'hdept'
205  IF (where(zgr_varlist EQ 'hdepw' ))[0] NE -1 THEN ncdf_transfer, cdfid, cdfidout, 'hdepw'
206  IF (where(zgr_varlist EQ 'e3tp'  ))[0] NE -1 THEN ncdf_transfer, cdfid, cdfidout, 'e3tp', 'e3t_ps'
207  IF (where(zgr_varlist EQ 'e3wp'  ))[0] NE -1 THEN ncdf_transfer, cdfid, cdfidout, 'e3wp', 'e3w_ps'
208  IF (where(zgr_varlist EQ 'e3t_ps'))[0] NE -1 THEN ncdf_transfer, cdfid, cdfidout, 'e3t_ps'
209  IF (where(zgr_varlist EQ 'e3w_ps'))[0] NE -1 THEN ncdf_transfer, cdfid, cdfidout, 'e3w_ps'
210  IF (where(zgr_varlist EQ 'mbathy'))[0] NE -1 THEN ncdf_transfer, cdfid, cdfidout, 'mbathy'
211;
212  IF keyword_set(key_e3_3d)  THEN BEGIN
213; get the bottom
214    CASE (ncdf_varinq(cdfid, 'mbathy')).ndims OF
215      2:ncdf_varget, cdfid, 'mbathy', bat, count = [jpi, jpj]
216      3:ncdf_varget, cdfid, 'mbathy', bat, count = [jpi, jpj, 1]
217      4:ncdf_varget, cdfid, 'mbathy', bat, count = [jpi, jpj, 1, 1]
218    ENDCASE
219    bottom = 0L > ( long(bat) - 1L )
220    bottom = lindgen(jpi, jpj) + jpi*jpj*temporary(bottom)
221;
222    CASE (ncdf_varinq(cdfid, 'e3t')).ndims OF
223      3:ncdf_varget, cdfid, 'e3t', res, count = [jpi, jpj, jpk]
224      4:ncdf_varget, cdfid, 'e3t', res, count = [jpi, jpj, jpk, 1]
225    ENDCASE
226    ncdf_varput, cdfidout, 'e3t_ps', (temporary(res))[bottom] * (bat NE 0L)
227;
228    CASE (ncdf_varinq(cdfid, 'e3w')).ndims OF
229      3:ncdf_varget, cdfid, 'e3w', res, count = [jpi, jpj, jpk]
230      4:ncdf_varget, cdfid, 'e3w', res, count = [jpi, jpj, jpk, 1]
231    ENDCASE
232    ncdf_varput, cdfidout, 'e3w_ps', (temporary(res))[bottom] * (bat NE 0L)
233  ENDIF
234;
235  IF keyword_set(key_gdep_3d)  THEN BEGIN
236; get the bottom
237    CASE (ncdf_varinq(cdfid, 'mbathy')).ndims OF
238      2:ncdf_varget, cdfid, 'mbathy', bat, count = [jpi, jpj]
239      3:ncdf_varget, cdfid, 'mbathy', bat, count = [jpi, jpj, 1]
240      4:ncdf_varget, cdfid, 'mbathy', bat, count = [jpi, jpj, 1, 1]
241    ENDCASE
242    bottom = 0L > ( long(bat) - 1L )
243    bottom = lindgen(jpi, jpj) + jpi*jpj*temporary(bottom)
244;
245    CASE (ncdf_varinq(cdfid, 'gdept')).ndims OF
246      3:ncdf_varget, cdfid, 'gdept', res, count = [jpi, jpj, jpk]
247      4:ncdf_varget, cdfid, 'gdept', res, count = [jpi, jpj, jpk, 1]
248    ENDCASE
249    ncdf_varput, cdfidout, 'hdept', (temporary(res))[bottom] * (bat NE 0L)
250;
251    bottom = jpi*jpj + temporary(bottom)
252    CASE (ncdf_varinq(cdfid, 'gdepw')).ndims OF
253      3:ncdf_varget, cdfid, 'gdepw', res, count = [jpi, jpj, jpk]
254      4:ncdf_varget, cdfid, 'gdepw', res, count = [jpi, jpj, jpk, 1]
255    ENDCASE
256    ncdf_varput, cdfidout, 'hdepw', (temporary(res))[bottom] * (bat NE 0L)
257  ENDIF
258;
259; mask
260;
261  IF n_elements(filein_msk) NE 0  THEN BEGIN
262    ncdf_close, cdfid
263    cdfid = ncdf_open(filein_msk)
264  ENDIF
265; loop on the vertical levels to limit the memory use
266  FOR k = 0, jpk-1 DO BEGIN
267    FOR m = 0, 3 DO BEGIN
268      CASE (ncdf_varinq(cdfid, msklist[m])).ndims OF
269        3:ncdf_varget, cdfid, msklist[m], zzz, offset = [0, 0, k] $
270        , count = [jpi, jpj, 1]
271        4:ncdf_varget, cdfid, msklist[m], zzz, offset = [0, 0, k, 0] $
272        , count = [jpi, jpj, 1, 1]
273      ENDCASE
274      zzz = byte(temporary(zzz))
275; zzz must contain only 0 or 1
276      zzz = temporary(zzz) MOD 2
277; we transpose zzz because we need to work with the y dimension as the
278; first dimension
279      zzz = transpose(temporary(zzz))
280; extend jpj to be a multiple of 8
281      jpjadd = jpj_m*8-jpj
282      IF jpjadd NE 0 THEN zzz = [temporary(zzz), bytarr(jpjadd, jpi)]
283; reform zzz, to look like output of binary.pro
284      zzz = reform(zzz, 8, 1, jpj_m, jpi, /over)
285; convert into "its byte form"
286      zzz = inverse_binary(temporary(zzz))
287      ncdf_varput, cdfidout, msklist[m], transpose(temporary(zzz)) $
288        , offset = [0, 0, k], count = [jpi, jpj_m, 1]
289    ENDFOR
290  ENDFOR
291;------------------------------------------------------
292;------------------------------------------------------
293  ncdf_close, cdfid
294  ncdf_close, cdfidout
295
296  RETURN
297END
Note: See TracBrowser for help on using the repository browser.