source: trunk/SRC/ReadWrite/ncdf_getmask.pro @ 391

Last change on this file since 391 was 391, checked in by smasson, 15 years ago

add a call to isafile in ncdf_get*.pro

  • Property svn:keywords set to Id
File size: 6.5 KB
Line 
1;+
2;
3; @file_comments
4; get the land/sea mask array from a NetCDF file
5;
6; @categories
7; Read NetCDF file
8;
9; @param fileid {in}{required}{type=salar string or long}
10; if fileid is a scalar string then it is the name of the file (with
11; the full path) to be opened (in that case, the file will be opened
12; and closed within ncdf_getmask).
13;
14; if fileid is a scalar then it is the id of the file return by a call
15; to ncdf_open outside of ncdf_getmask (in that case, the file will
16; NOT be opened and closed within ncdf_getmask)
17;
18; @keyword ADDSCL_BEFORE {default=0}{type=scalar: 0 or 1}
19; put 1 to apply add_offset and scale factor on data before looking for
20; missing values when using USEASMASK keyword
21;
22; @keyword INVMASK {default=0}{type=scalar: 0 or 1}
23; Inverse the land/sea mask (that should have 0/1 values for land/sea): mask = 1-mask
24;
25; @keyword MASKNAME {type=string}
26; A string giving the name of the variable in the file
27; that contains the land/sea mask
28;
29; @keyword MISSING_VALUE {type=scalar}
30; To define (or redefine if the attribute is already existing) the
31; missing values used with USEASMASK keyword. Note that this value is
32; not used if TESTOP keyword is given and contains 2 words. 
33;
34; @keyword USEASMASK {type=scalar string}
35; A string giving the name of the variable in the file
36; that will be used to build the land/sea mask. In this case the
37; mask is based on the first record (if record dimension
38; exists). The mask is build according to operator defined by TESTOP
39; keyword (default NE) and the testing values defined as
40;   1) the second word of TESTOP if existing
41;   2) MISSING_VALUE keyword
42;   3) attribute missing_value or _fillvalue of the variable USEASMASK
43;   4) !Values.f_nan (can be used only with NE and EQ operators)
44;
45; @keyword TESTOP {default='NE'} {type=scalar string, for example 'GT 0.5'}
46; a string describing the type of test that will be done to define the
47; mask. The test is performed on the variable specified by USEASMASK
48; keyword.
49;
50; TESTOP can contain 1 or 2 words. The first word is the operator
51; definition: "EQ" "NE" "GE" "GT" "LE" "LT" (default is NE). The
52; second word define the testing value. If TESTOP contains only 1
53; word, then the test value is denifed by
54;   1) MISSING_VALUE keyword
55;   2) attribute missing_value or _fillvalue of the variable USEASMASK
56;   3) !Values.f_nan (can be used only with NE and EQ operators)
57;
58; @keyword
59; _EXTRA to be able to call ncdf_getmask with _extra keyword
60;
61; @returns
62; the land/sea mask 2D or 3D array or -1 in case of error or mask absence
63;
64; @examples
65;
66;   IDL> mask = ncdf_getmask('HadISST1_1m_187001_200702_sst_reg1m.nc',useasmask = 'sst', missing_value = -1.00000e+30)
67;
68;   IDL> mask = ncdf_getmask('meshmaskORCA2.nc', maskname = 'tmask')
69;
70;   IDL> mask = ncdf_getmask('t106.nc', useasmask = 'SLM', testop = 'le 0.5')
71;
72; @history
73; August 2007: Sebastien Masson (smasson\@lodyc.jussieu.fr)
74;
75; @version
76; $Id$
77;
78;-
79FUNCTION ncdf_getmask, fileid, ADDSCL_BEFORE = addscl_before $
80                       , MASKNAME = maskname, USEASMASK = useasmask $
81                       , MISSING_VALUE = missing_value, INVMASK = invmask $
82                       , TESTOP = testop, _EXTRA = ex
83;
84  compile_opt idl2, strictarrsubs
85;
86  @cm_general                      ;   needed for iodir
87;
88  IF NOT (keyword_set(maskname) OR keyword_set(useasmask)) AND keyword_set(romsgrid) THEN maskname = 'mask_rho'
89  IF NOT (keyword_set(maskname) OR keyword_set(useasmask)) THEN return, -1
90;----------------------------------------------------------
91; should we open the file?
92  IF size(fileid, /type) EQ 7 THEN $
93     cdfid = ncdf_open(isafile(fileid, title = 'which file must be open by ncdf_getmask?', IODIRECTORY = iodir, _extra = ex)) $
94  ELSE cdfid = fileid
95; what is inside the file
96  inq = ncdf_inquire(cdfid)
97; name of the variables
98  namevar = strarr(inq.nvars)
99  for varid = 0, inq.nvars-1 do begin
100    invar = ncdf_varinq(cdfid, varid)
101    namevar[varid] = strlowcase(invar.name)
102  ENDFOR
103;----------------------------------------------------------
104  CASE 1 OF
105    keyword_set(maskname):mskid = (where(namevar EQ strlowcase(maskname)))[0]
106    keyword_set(useasmask):mskid = (where(namevar EQ strlowcase(useasmask)))[0]
107  ENDCASE
108;
109  if mskid NE -1 THEN BEGIN
110    mskinq = ncdf_varinq(cdfid, mskid)
111; is the mask variable containing the record dimension?
112    withrcd = (where(mskinq.dim EQ inq.recdim))[0]
113    IF withrcd NE -1 THEN BEGIN
114; in order to read only the first record
115; we need to get the size of each dimension
116      count = replicate(1L, mskinq.ndims)
117      FOR d = 0, mskinq.ndims -1 DO BEGIN
118        IF d NE withrcd THEN BEGIN
119          ncdf_diminq, cdfid, mskinq.dim[d], name, size
120          count[d] = size
121        ENDIF
122      ENDFOR
123; read the variable for the first record
124      ncdf_varget, cdfid, mskid, mask, count = count
125    ENDIF ELSE ncdf_varget, cdfid, mskid, mask
126
127; get add_offset, scale factor and missing value attributes
128    ncdf_getatt, cdfid, mskid, add_offset = add, scale_factor = scl, missing_value = miss
129; do we apply add_offset and scale factor ?
130    IF keyword_set(addscl_before) THEN BEGIN
131      IF scl NE 1 THEN mask = mask * scl
132      IF add NE 0 THEN mask = mask + add
133    ENDIF
134
135    IF keyword_set(useasmask)  THEN BEGIN
136
137      IF n_elements(missing_value) NE 0 THEN miss = missing_value
138      IF size(miss, /type) EQ 7 THEN miss = !values.f_nan
139
140      IF NOT keyword_set(testop) THEN testop = 'NE'
141      tmp = strsplit(testop, ' ', /extract)
142      op = strupcase(tmp[0])
143      IF op EQ 'EQ' THEN BEGIN
144        op = 'NE'
145        invmask = 1b - keyword_set(invmask)
146      ENDIF
147      IF n_elements(tmp) EQ 1 THEN testval = miss ELSE testval = float(tmp[1])
148      IF finite(testval) EQ 0 THEN BEGIN
149        IF op NE 'NE' THEN mask = report('NaN test value can be used only with EQ or NE operator') ELSE mask = finite(mask)
150      ENDIF ELSE BEGIN
151        CASE op OF
152          'GE':mask = mask GE testval
153          'GT':mask = mask GT testval
154          'LE':mask = mask LE testval
155          'LT':mask = mask LT testval
156          'NE':BEGIN
157; we have to take care of the float accuracy
158            CASE 1 OF
159              testval GE  1.e6:mask = mask LT (testval - 10)
160              testval LE -1.e6:mask = mask GT (testval + 10)
161              abs(testval) LE 1.e-6:mask = abs(mask) GT 1.e-6
162              ELSE:mask = mask NE testval
163            ENDCASE
164          END
165        ENDCASE
166      ENDELSE
167
168    ENDIF
169
170    IF mask[0] NE -1 THEN BEGIN
171      mask = byte(round(mask))
172      if keyword_set(invmask) then mask = 1b - mask
173    ENDIF
174
175  ENDIF ELSE mask = -1
176
177  IF size(fileid, /type) EQ 7 THEN ncdf_close, cdfid
178
179  return, mask
180END
Note: See TracBrowser for help on using the repository browser.