source: trunk/SRC/ReadWrite/ncdf_getaxis.pro @ 399

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

wrong bugfix in previous changeset:398

  • Property svn:keywords set to Id
File size: 13.9 KB
Line 
1;+
2;
3; @file_comments
4; get the x/y dimension Id and x/y axes from a netcdf file
5;
6; @categories
7; Read NetCDF file
8;
9; @param fileid {in}{required}{type=scalar}
10; the id of the netcdf file
11;
12; @param dimidx {out}{type=scalar (long)}
13; id of the x dimension
14;
15; @param dimidy {out}{type=scalar (long)}
16; id of the y dimension
17;
18; @param xaxis {out}{type=1D or 2D array}
19; the x axis
20;
21; @param yaxis {out}{type=1D or 2D array}
22; the y axis
23;
24; @keyword ROMSGRID {out}{type=scalar: 0 or 1}
25; gives back if we are using a ROMS grid (1) or not (0)
26;
27; @keyword START1 {default=0}{type=scalar: 0 or 1}
28; Index the axis from 1 instead of 0 when using /xyindex
29;
30; @keyword XDIMNAME {default='longitude', 'lon', 'x', 'longitude*', 'lon*', 'x*', '*longitude*', '*lon*' or '*x*'}{type=scalar string}
31; A string giving the name of the x dimension or/and a named variable
32; in which x dimension name is returned.
33;
34; @keyword YDIMNAME {default='latitude', 'lat', 'y', 'latitude*', 'lat*', 'y*', 'eta_*', '*latitude*', '*lat*', '*y*'}{type=scalar string}
35; A string giving the name of the y dimension or/and a named variable
36; in which y dimension name is returned.
37;
38; @keyword XAXISNAME {default='x', 'longitude', 'nav_lon', 'lon', 'lon_rho' or 'NbLongitudes'}{type=scalar string}
39; A string giving the name of the variable in the file
40; that contains the x axis or/and a named variable
41; in which this variable name is returned.
42;
43; @keyword YAXISNAME {default='y', 'latitude', 'nav_lat','lat', 'lat_rho' or 'NbLatitudes'}{type=scalar string}
44; A string giving the name of the variable in the file
45; that contains the y axis or/and a named variable
46; in which this variable name is returned.
47;
48; @keyword XYINDEX {default=0}{type=scalar: 0 or 1}
49; To define the x/y axis with index instead of using
50; the values contained in X/YAXISNAME.
51; x/yaxis = keyword_set(start1) + findgen(jpi/jpj)
52;
53; @keyword XMINMESH {default=0L}{type=scalar}
54; Define common (cm_4mesh) variables ixminmesh used to define the localization
55; of the first point of the grid along the x direction in a zoom of the original grid
56;
57; @keyword YMINMESH {default=0L}{type=scalar}
58; Define common (cm_4mesh) variables iyminmesh used to define the localization
59; of the first point of the grid along the y direction in a zoom of the original grid
60;
61; @keyword XMAXMESH {default=jpiglo-1}{type=scalar}
62; Define common (cm_4mesh) variables ixmaxmesh used to define the localization
63; of the last point of the grid along the x direction in a zoom of the original grid
64; Note that if XMAXMESH < 0 then ixmaxmesh is defined as ixmaxmesh = jpiglo -1 + xmaxmesh
65;
66; @keyword YMAXMESH {default=jpjglo-1}{type=scalar}
67; Define common (cm_4mesh) variables iymaxmesh used to define the localization
68; of the last point of the grid along the y direction in a zoom of the original grid
69; Note that if YMAXMESH < 0 then iymaxmesh is defined as iymaxmesh = jpjglo -1 + ymaxmesh
70;
71; @keyword _EXTRA
72; Used to be able to call ncdf_getaxis with _extra
73;
74; @history
75; March 2007: Sebastien Masson (smasson\@locean-ipsl.upmc.fr)
76;
77;
78; @version
79; $Id$
80;-
81PRO ncdf_getaxis, fileid, dimidx, dimidy, xaxis, yaxis $
82                  , XAXISNAME = xaxisname, YAXISNAME = yaxisname $
83                  , XDIMNAME = xdimname, YDIMNAME = ydimname $
84                  , XYINDEX = xyindex, START1 = start1 $
85                  , XMINMESH = xminmesh, XMAXMESH = xmaxmesh $
86                  , YMINMESH = yminmesh, YMAXMESH = ymaxmesh $
87                  , ROMSGRID = romsgrid, _EXTRA = ex
88;
89  compile_opt idl2, strictarrsubs
90;
91@cm_general                   ;   needed for iodir
92@cm_4mesh
93;
94  IF n_elements(xminmesh) NE 0 THEN ixminmesh = 0L > long(xminmesh[0]) ELSE ixminmesh  = 0l
95  IF n_elements(yminmesh) NE 0 THEN iyminmesh = 0L > long(yminmesh[0]) ELSE iyminmesh  = 0l
96  IF n_elements(zminmesh) NE 0 THEN izminmesh = 0L > long(zminmesh[0]) ELSE izminmesh  = 0l
97; should we open the file?
98  IF size(fileid, /type) EQ 7 THEN $
99     cdfid = ncdf_open(isafile(fileid, title = 'which file must be open by ncdf_getaxis?', IODIRECTORY = iodir, _extra = ex)) $
100  ELSE cdfid = fileid
101; what is inside the file
102  inside = ncdf_inquire(cdfid)
103;------------------------------------------------------------
104; name of all dimensions
105  namedim = strarr(inside.ndims)
106  for dimiq = 0, inside.ndims-1 do begin
107    ncdf_diminq, cdfid, dimiq, tmpname, value
108    namedim[dimiq] = strlowcase(tmpname)
109  ENDFOR
110;----------------------------------------------------------
111; name of the variables
112  namevar = strarr(inside.nvars)
113  for varid = 0, inside.nvars-1 do begin
114    invar = ncdf_varinq(cdfid, varid)
115    namevar[varid] = strlowcase(invar.name)
116  ENDFOR
117;----------------------------------------------------------
118; find the xaxis
119; try to get the variable that contains the xaxis
120  if keyword_set(xaxisname) then xaxisname = strlowcase(xaxisname) ELSE xaxisname = 'x'
121  xvarid = (where(namevar EQ xaxisname OR namevar EQ 'longitude' $
122                  OR namevar EQ 'nav_lon' OR namevar EQ 'lon' $
123                  OR namevar EQ 'lon_rho' OR namevar EQ 'nblongitudes'))[0]
124; no xaxis variable found, we will build a fake xaxis based on the size of the x dimension
125; -> we must find the x dimension
126  IF xvarid EQ -1 THEN BEGIN
127    dummy = report(['xaxis variable was not found within the default names:' $
128                    , '''longitude'', ''nav_lon'', ''lon'', ''lon_rho'', ''nblongitudes''' $
129                    , ' we use a fake xaxis based on x dimension size (or use XAXISNAME keyword)'], /simple)
130    xaxisname = 'Not Found'
131; try to get the dimension corresponding to x
132; roms file?
133    dimidx = where(namedim EQ 'xi_rho' OR namedim EQ 'xi_u' OR namedim EQ 'xi_v' OR namedim EQ 'xi_psi')
134    IF dimidx[0] EQ -1 THEN BEGIN
135; we are looking for a x dimension with a name matching one of the following regular expression:
136      if keyword_set(xdimname) then testname = strlowcase(xdimname) $
137      ELSE testname = ['longitude', 'lon', 'x', 'longitude*', 'lon*', 'x*', '*longitude*', '*lon*', '*x*']
138      cnt = -1
139      ii = 0
140      WHILE cnt NE 1 AND ii LT n_elements(testname) DO BEGIN
141        dimidx = where(strmatch(namedim, testname[ii]) EQ 1, cnt)
142        ii = ii+1
143      ENDWHILE
144      CASE cnt OF
145        0:begin
146          dummy = report(['none of the dimensions name matches one of the following regular expression:' $
147                          , '''longitude'', ''lon'', ''x'', ''longitude*'', ''lon*'', ''x*'', ''*longitude*'', ''*lon*'', ''*x*''' $
148                          , ' => we cannot find the x dimension, use XDIMNAME keyword'], /simple)
149          stop
150        END
151        1:dimidx = dimidx[0]
152        ELSE:begin
153          dummy = report(['several (and not one unique) dimensions name matches the following regular expression:' $
154                          , '''longitude'', ''lon'', ''x'', ''longitude*'', ''lon*'', ''x*'', ''*longitude*'', ''*lon*'', ''*x*''' $
155                          , ' => we cannot find the x dimension, use XDIMNAME keyword'], /simple)
156          stop
157        ENDELSE
158      ENDCASE
159      romsgrid = 0b
160    ENDIF ELSE romsgrid = 1b
161  ENDIF ELSE BEGIN
162    romsgrid = strmid(namevar[xvarid], 0, 4) EQ 'lon_'
163    xinq = ncdf_varinq(cdfid, xvarid)
164    xaxisname = xinq.name
165    dimidx = xinq.dim[0]
166    xoffset = lonarr(xinq.ndims)
167    xcount = lonarr(xinq.ndims)
168    FOR i = 0, xinq.ndims -1 DO BEGIN
169      ncdf_diminq, cdfid, xinq.dim[i], blabla, tmpsz
170      xcount[i] = tmpsz
171    ENDFOR
172    jpiglo = xcount[0]
173    IF n_elements(xmaxmesh) NE 0 THEN BEGIN
174      IF xmaxmesh GE 0 THEN ixmaxmesh = long(xmaxmesh[0]) ELSE ixmaxmesh = xcount[0] -1 + long(xmaxmesh[0])
175    ENDIF ELSE ixmaxmesh = xcount[0] - 1L
176    ixmaxmesh  = 0 > ixmaxmesh < (xcount[0] - 1L) ; make sure ixmaxmesh is not too big
177    xoffset[0] = ixminmesh
178    xcount[0] = ixmaxmesh - ixminmesh + 1L
179    jpifromx = xcount[0]
180    jpi = jpifromx
181    IF xinq.ndims GE 2 THEN BEGIN
182      jpjglo = xcount[1]
183      IF n_elements(ymaxmesh) NE 0 THEN BEGIN
184        IF ymaxmesh GE 0 THEN iymaxmesh = long(ymaxmesh[0]) ELSE iymaxmesh = xcount[1] - 1L + long(ymaxmesh[0])
185      ENDIF ELSE iymaxmesh = xcount[1] - 1L
186      iymaxmesh  = 0 > iymaxmesh < (xcount[1] - 1L) ; make sure ixmaxmesh is not too big
187      xoffset[1] = iyminmesh
188      xcount[1] = iymaxmesh - iyminmesh + 1L
189      jpjfromx = xcount[1]
190      jpj = jpjfromx
191    ENDIF
192  ENDELSE
193  IF arg_present(xdimname) THEN ncdf_diminq, cdfid, dimidx,  xdimname, tmp
194;
195  IF arg_present(xaxis) THEN BEGIN
196; should we read or compute the xaxis?
197    IF keyword_set(xyindex) OR xvarid EQ -1 THEN BEGIN
198      xaxis = keyword_set(start1) + findgen(jpifromx)
199      xyindex = 1
200    ENDIF ELSE BEGIN
201; read the xaxis
202      ncdf_varget, cdfid, xvarid, xaxis, offset = xoffset, count = xcount
203      ncdf_getatt, cdfid, xvarid, ADD_OFFSET = add_offset, SCALE_FACTOR = scale_factor
204      IF scale_factor NE 1. THEN xaxis = temporary(xaxis) * scale_factor
205      IF add_offset NE 0. THEN xaxis = temporary(xaxis) + add_offset
206; make sure of the shape of xaxis
207      IF n_elements(jpjfromx) NE 0 THEN xaxis = reform(xaxis, jpifromx, jpjfromx, /over)
208    ENDELSE
209  ENDIF
210
211;----------------------------------------------------------
212; find the yaxis
213; try to get the variable that contains the yaxis
214  if keyword_set(yaxisname) then yaxisname = strlowcase(yaxisname) ELSE yaxisname = 'y'
215  yvarid = (where(namevar EQ yaxisname OR namevar EQ 'latitude' $
216                  OR namevar EQ 'nav_lat' OR namevar EQ 'lat' $
217                  OR namevar EQ 'lat_rho' OR namevar EQ 'nblatitudes'))[0]
218  yvarid = yvarid[0]
219; no yaxis variable found, we will build a fake yaxis based on the size of the y dimension
220; -> we must find the y dimension
221  if yvarid EQ -1 then begin
222    dummy = report(['yaxis variable was not found within the default names:' $
223                    , '''latitude'', ''nav_lat'', ''lat'', ''lat_rho'', ''nblatitudes''' $
224                    , ' we use a fake yaxis based on y dimension size (or use YAXISNAME keyword)'], /simple)
225    yaxisname = 'Not Found'
226; try to get the dimension corresponding to y
227; roms file?
228    dimidy = where(namedim EQ 'eta_rho' OR namedim EQ 'eta_u' OR namedim EQ 'eta_v' OR namedim EQ 'eta_psi')
229    IF dimidy[0] EQ -1 THEN BEGIN
230; we are looking for a y dimension with a name matching one of the following regular expression:
231      if keyword_set(ydimname) then testname = strlowcase(ydimname) $
232      ELSE testname = ['latitude', 'lat', 'y', 'latitude*', 'lat*', 'y*', 'eta_*', '*latitude*', '*lat*', '*y*']
233      cnt = -1
234      ii = 0
235      WHILE cnt NE 1 AND ii LT n_elements(testname) DO BEGIN
236        dimidy = where(strmatch(namedim, testname[ii]) EQ 1, cnt)
237        ii = ii+1
238      ENDWHILE
239      CASE cnt OF
240        0:begin
241          dummy = report(['none of the dimensions name matches one of the following regular expression:' $
242                          , '''latitude'', ''lat'', ''y'', ''latitude*'', ''lat*'', ''y*'', ''eta_*'', ''*latitude*'', ''*lat*'', ''*y*''' $
243                          , ' => we cannot find the y dimension, use YDIMNAME keyword'], /simple)
244          stop
245        END
246        1:dimidy = dimidy[0]
247        ELSE:begin
248          dummy = report(['several (and not one unique) dimensions name matches the following regular expression:' $
249                          , '''latitude'', ''lat'', ''y'', ''latitude*'', ''lat*'', ''y*'', ''eta_*'', ''*latitude*'', ''*lat*'', ''*y*''' $
250                          , ' => we cannot find the y dimension, use YDIMNAME keyword'], /simple)
251          stop
252        ENDELSE
253      ENDCASE
254    ENDIF
255  ENDIF ELSE BEGIN
256    yinq = ncdf_varinq(cdfid, yvarid)
257    yaxisname = yinq.name
258    IF yinq.ndims GE 2 THEN dimidy = yinq.dim[1] ELSE dimidy = yinq.dim[0]
259    yoffset = lonarr(yinq.ndims)
260    ycount = lonarr(yinq.ndims)
261    FOR i = 0, yinq.ndims -1 DO BEGIN
262      ncdf_diminq, cdfid, yinq.dim[i], blabla, tmpsz
263      ycount[i] = tmpsz
264    ENDFOR
265    idy = yinq.ndims GE 2
266    jpjglo = ycount[idy]
267    IF n_elements(ymaxmesh) NE 0 THEN BEGIN
268      IF ymaxmesh GE 0 THEN iymaxmesh = long(ymaxmesh[0]) ELSE iymaxmesh = ycount[idy] - 1L + long(ymaxmesh[0])
269    ENDIF ELSE iymaxmesh = ycount[idy] - 1L
270    iymaxmesh  = iymaxmesh < (ycount[idy] - 1L) ; make sure ixmaxmesh is not too big
271    yoffset[idy] = iyminmesh
272    ycount[idy] = iymaxmesh - iyminmesh + 1L
273    jpjfromy = ycount[idy]
274    jpj = jpjfromy
275    IF yinq.ndims GE 2 THEN BEGIN
276      jpiglo = ycount[0]
277      IF n_elements(xmaxmesh) NE 0 THEN BEGIN
278        IF xmaxmesh GE 0 THEN ixmaxmesh = long(xmaxmesh[0]) ELSE ixmaxmesh = ycount[0] - 1L + long(xmaxmesh[0])
279      ENDIF ELSE ixmaxmesh = ycount[0] - 1L
280      ixmaxmesh  = ixmaxmesh < (ycount[0] - 1L) ; make sure ixmaxmesh is not too big
281      yoffset[0] = ixminmesh
282      ycount[0] = ixmaxmesh - ixminmesh + 1L
283      jpifromy = xcount[0]
284      jpi = jpifromy
285    ENDIF
286  ENDELSE
287  IF arg_present(ydimname) THEN ncdf_diminq, cdfid, dimidy,  ydimname, tmp
288;
289  IF arg_present(yaxis) THEN BEGIN
290    IF n_elements(jpifromy) NE 0 THEN BEGIN
291      IF n_elements(jpifromx) EQ 0 THEN ncdf_diminq, cdfid, dimidx, blabla, jpifromx
292      IF jpifromy NE jpifromx THEN BEGIN
293        dummy = report('x/y axes do not have the same x dimension...')
294        stop
295      ENDIF
296    ENDIF
297    IF n_elements(jpjfromx) NE 0 THEN BEGIN
298      IF n_elements(jpjfromy) EQ 0 THEN ncdf_diminq, cdfid, dimidy, blabla, jpjfromy
299      IF jpjfromy NE jpjfromx THEN BEGIN
300        dummy = report(' x/y axes do not have the same y dimension...')
301        stop
302      ENDIF
303    ENDIF
304; should we read or compute the xaxis?
305    IF keyword_set(xyindex) OR yvarid EQ -1 THEN BEGIN
306      yaxis = keyword_set(start1) + findgen(jpjfromy)
307    ENDIF ELSE BEGIN
308; read the yaxis
309      ncdf_varget, cdfid, yvarid, yaxis, offset = yoffset, count = ycount
310      ncdf_getatt, cdfid, yvarid, ADD_OFFSET = add_offset, SCALE_FACTOR = scale_factor
311      IF scale_factor NE 1. THEN yaxis = temporary(yaxis) * scale_factor
312      IF add_offset NE 0. THEN yaxis = temporary(yaxis) + add_offset
313; make sure of the shape of xaxis
314      IF n_elements(jpifromy) NE 0 THEN yaxis = reform(yaxis, jpifromy, jpjfromy, /over)
315    ENDELSE
316  ENDIF
317
318  IF size(fileid, /type) EQ 7 THEN ncdf_close, cdfid
319
320  return
321END
Note: See TracBrowser for help on using the repository browser.