Changeset 271 for trunk/SRC/ToBeReviewed/LECTURE
- Timestamp:
- 08/30/07 14:44:23 (17 years ago)
- Location:
- trunk/SRC/ToBeReviewed/LECTURE
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SRC/ToBeReviewed/LECTURE/read_ncdf.pro
r240 r271 31 31 ; Useless, defined for compatibility 32 32 ; 33 ; @keyword ADDSCL_BEFORE {default=0}{type=scalar: 0 or 1} 34 ; put 1 to apply add_offset ad scale factor on data before looking for 35 ; missing values 36 ; 33 37 ; @keyword BOXZOOM 34 38 ; Contain the boxzoom on which we have to do the reading … … 41 45 ; 42 46 ; @keyword INIT {default=0}{type=scalar: 0 or 1} 43 ; To call automatically initncdf , filenameand thus47 ; To call automatically initncdf with filename as input argument and thus 44 48 ; redefine all the grid parameters 45 49 ; … … 62 66 ; but only the array referring to the field. 63 67 ; 64 ; @keyword TIMEVAR {type=string}65 ; It define the name of the variable that66 ; contains the time axis. This keyword can be useful if there67 ; is no unlimited dimension or if the time axis selected by default68 ; (the first 1D array with unlimited dimension) is not the good one.69 ;70 68 ; @keyword ZETAFILENAME {default=FILENAME}{type=string} 71 69 ; For ROMS outputs. The filename of the file where zeta variable should be read … … 75 73 ; 76 74 ; @keyword _EXTRA 77 ; Used to pass keywords 75 ; Used to pass keywords to <pro>isafile</pro>, <pro>initncdf</pro>, 76 ; <pro>ncdf_gettime</pro> and <pro>domdef</pro> 78 77 ; 79 78 ; @returns … … 95 94 ; 96 95 FUNCTION read_ncdf, name, beginning, ending, compatibility, BOXZOOM = boxzoom, FILENAME = filename $ 97 , PARENTIN = parentin, TIMESTEP = timestep, TIMEVAR = timevar$96 , PARENTIN = parentin, TIMESTEP = timestep, ADDSCL_BEFORE = addscl_before $ 98 97 , TOUT = tout, NOSTRUCT = nostruct, CONT_NOFILL = CONT_NOFILL, INIT = init $ 99 98 , GRID = grid, CALLITSELF = callitself $ … … 115 114 ; print,filename 116 115 ; is parent a valid widget ? 117 if keyword_set(parentin) thenBEGIN116 IF keyword_set(parentin) THEN BEGIN 118 117 parent = long(parentin) 119 118 parent = parent*widget_info(parent, /managed) … … 123 122 ; Opening of the name file 124 123 ;------------------------------------------------------------ 125 if size(filename, /type) NE 7 then$124 IF size(filename, /type) NE 7 THEN $ 126 125 return, report('read_ncdf cancelled') 127 126 IF !version.OS_FAMILY EQ 'unix' THEN spawn, '\file '+filename+' > /dev/null' 128 127 cdfid = ncdf_open(filename) 129 contient= ncdf_inquire(cdfid)128 inq = ncdf_inquire(cdfid) 130 129 ;------------------------------------------------------------ 131 130 ; we check if the variable name exists in the file. 132 131 ;------------------------------------------------------------ 133 if ncdf_varid(cdfid, name) EQ -1 thenBEGIN132 IF ncdf_varid(cdfid, name) EQ -1 THEN BEGIN 134 133 ncdf_close, cdfid 135 134 return, report('variable '+name+' !C not found in the file '+filename) 136 135 ENDIF 137 var contient= ncdf_varinq(cdfid, name)138 IF var contient.ndims LT 2 THEN return, report('read_ncdf cannot read scalar or 1D data')136 varinq = ncdf_varinq(cdfid, name) 137 IF varinq.ndims LT 2 THEN return, report('read_ncdf cannot read scalar or 1D data') 139 138 ; look for the dimension names 140 dimnames = strarr(var contient.ndims)141 FOR i = 0, var contient.ndims-1 DO BEGIN142 ncdf_diminq, cdfid, var contient.dim[i], tmp, dimsize139 dimnames = strarr(varinq.ndims) 140 FOR i = 0, varinq.ndims-1 DO BEGIN 141 ncdf_diminq, cdfid, varinq.dim[i], tmp, dimsize 143 142 dimnames[i] = tmp 144 143 ENDFOR … … 146 145 ; shall we redefine the grid parameters 147 146 ;------------------------------------------------------------ 148 ifkeyword_set(init) THEN initncdf, filename, _extra = ex147 IF keyword_set(init) THEN initncdf, filename, _extra = ex 149 148 ;------------------------------------------------------------ 150 149 ; check the time axis and the debut and ending dates 151 150 ;------------------------------------------------------------ 152 if n_elements(beginning) EQ 0 then begin151 IF n_elements(beginning) EQ 0 THEN BEGIN 153 152 beginning = 0 154 153 timestep = 1 155 endif 156 if keyword_set(timestep) then begin 157 firsttps = beginning[0] 158 if n_elements(ending) NE 0 then lasttps = ending[0] ELSE lasttps = firsttps 159 jpt = lasttps-firsttps+1 160 IF NOT keyword_set(callitself) then time = julday(1, 1, 1) + lindgen(jpt) 161 ENDIF ELSE BEGIN 162 if keyword_set(parent) then BEGIN 154 ENDIF 155 ; define time and jpt 156 CASE 1 OF 157 keyword_set(timestep):BEGIN 158 firsttps = beginning[0] 159 IF n_elements(ending) NE 0 THEN lasttps = ending[0] ELSE lasttps = firsttps 160 jpt = lasttps-firsttps+1 161 IF NOT keyword_set(callitself) then time = julday(1, 1, 1) + lindgen(jpt) 162 END 163 keyword_set(parent):BEGIN 163 164 widget_control, parent, get_uvalue = top_uvalue 164 165 filelist = extractatt(top_uvalue, 'filelist') … … 168 169 date1 = date2jul(beginning[0]) 169 170 if n_elements(ending) NE 0 then date2 = date2jul(ending[0]) ELSE date2 = date1 170 firsttps = where(time EQ date1) & firsttps = firsttps[0] 171 lasttps = where(time EQ date2) & lasttps = lasttps[0] 172 ENDIF ELSE BEGIN 173 IF keyword_set(timevar) THEN BEGIN 174 timeid = ncdf_varid(cdfid, timevar) 175 IF timeid EQ -1 THEN BEGIN 176 ncdf_close, cdfid 177 return, report('the file '+filename+' as no variable ' + timevar $ 178 + '. !C Use the TIMESTEP keyword') 179 endif 180 timecontient = ncdf_varinq(cdfid, timeid) 181 contient.recdim = timecontient.dim[0] 182 ENDIF ELSE BEGIN 183 ; we find the infinite dimension 184 timedim = contient.recdim 185 if timedim EQ -1 then BEGIN 186 ncdf_close, cdfid 187 return, report('the file '+filename+' as no infinite dimension. !C Use TIMESTEP or TIMEVAR keyword') 188 endif 189 ; we find the FIRST time axis 190 timeid = 0 191 repeat BEGIN ; As long as we have not find a variable having only one dimension: the infinite one 192 timecontient = ncdf_varinq(cdfid, timeid) ; that the variable contain. 193 timeid = timeid+1 194 endrep until (n_elements(timecontient.dim) EQ 1 $ 195 AND timecontient.dim[0] EQ contient.recdim) $ 196 OR timeid EQ contient.nvars+1 197 ; 198 if timeid EQ contient.nvars+1 then BEGIN 199 ncdf_close, cdfid 200 return, report('the file '+filename+' as no time axis variable. !C Use the TIMESTEP keyword') 201 endif 202 timeid = timeid-1 203 ENDELSE 204 ; we must found the time origin of the julian calendar used in the 205 ; time axis. 206 ; does the attribut units an dcalendar exist for the variable time axis? 207 if timecontient.natts EQ 0 then BEGIN 171 firsttps = (where(abs(time - date1) LT 0.9d/86400.d))[0] ; beware of rounding errors... 172 lasttps = (where(abs(time - date2) LT 0.9d/86400.d))[0] 173 jpt = lasttps-firsttps+1 174 END 175 ELSE:BEGIN 176 time = ncdf_gettime(filename, cdfid, caller = 'read_ncdf', err = err, _extra = ex) 177 IF n_elements(err) NE 0 THEN BEGIN 178 dummy = report(err) 208 179 ncdf_close, cdfid 209 return, report('the variable '+timecontient.name+' has no attribut.!C Use the TIMESTEP keyword or add the attribut ''units'' to the variable') 210 endif 211 attnames = strarr(timecontient.natts) 212 for attiq = 0, timecontient.natts-1 do attnames[attiq] = ncdf_attname(cdfid, timeid, attiq) 213 if (where(attnames EQ 'units'))[0] EQ -1 then BEGIN 214 ncdf_close, cdfid 215 return, report('Attribut ''units'' not found for the variable '+timecontient.name+' !C Use the TIMESTEP keyword') 180 return, -1 216 181 ENDIF 217 ; 218 ; now we try to find the attribut called calendar... 219 ; the attribute "calendar" exists? 220 ; If no, we suppose that the calendar is gregorian calendar 221 ; 222 if (where(attnames EQ 'calendar'))[0] NE -1 then BEGIN 223 ncdf_attget, cdfid, timeid, 'calendar', value 224 value = string(value) 225 CASE value OF 226 'noleap':key_caltype = 'noleap' 227 '360d':key_caltype = '360d' 228 'greg':IF n_elements(key_caltype) EQ 0 THEN key_caltype = 'greg' 229 ELSE:BEGIN 230 ; notused = report('Unknown calendar: '+value+', we use greg calendar.') 231 key_caltype = 'greg' 232 END 233 ENDCASE 234 ENDIF ELSE BEGIN 235 ; notused = report('Unknown calendar, we use '+key_caltype+' calendar.') 236 IF n_elements(key_caltype) EQ 0 THEN key_caltype = 'greg' 237 ENDELSE 238 ; 239 ; now we take acre of units attribut 240 ncdf_attget, cdfid, timeid, 'units', value 241 ; 242 ; time_counter:units = "seconds since 0001-01-01 00:00:00" ; 243 ; time_counter:units = "hours since 0001-01-01 00:00:00" ; 244 ; time_counter:units = "days since 1979-01-01 00:00:00" ; 245 ; time_counter:units = "months since 1979-01-01 00:00:00" ; 246 ; time_counter:units = "years since 1979-01-01 00:00:00" ; 247 ; 248 ; we decript the "units" attribut to find the time origin 249 value = strtrim(strcompress(string(value)), 2) 250 mots = str_sep(value, ' ') 251 unite = mots[0] 252 unite = strlowcase(unite) 253 IF strpos(unite, 's', strlen(unite)-1) NE -1 THEN unite = strmid(unite, 0, strlen(unite)-1) 254 IF strpos(unite, 'julian_') NE -1 THEN unite = strmid(unite, 7) 255 IF unite NE 'second' AND unite NE 'hour' AND unite NE 'day' $ 256 AND unite NE 'month' AND unite NE 'year' THEN BEGIN 257 ncdf_close, cdfid 258 return, report('time units does not start with seconds/hours/days/months/years') 259 ENDIF 260 IF stregex(value, '[^ ]* since ([0-9]){1,4}-([0-9]){1,2}-([0-9]){1,2}.*', /boolean) EQ 0 THEN BEGIN 261 ncdf_close, cdfid 262 return, report('attribut units of time has not the good format: [^ ]* since ([0-9]){1,4}-([0-9]){1,2}-([0-9]){1,2}.*') 263 ENDIF 264 depart = str_sep(mots[2], '-') 265 ncdf_varget, cdfid, timeid, time 266 time = double(time) 267 case unite of 268 'second':time = julday(depart[1], depart[2], depart[0])+time/86400.d 269 'hour':time = julday(depart[1], depart[2], depart[0])+time/24.d 270 'day':time = julday(depart[1], depart[2], depart[0])+time 271 'month':BEGIN 272 if total(fix(time) NE time) NE 0 then $ ; we switch to days with 30d/m 273 time = julday(depart[1], depart[2], depart[0])+round(time*30) $ 274 ELSE for t = 0, n_elements(time)-1 DO $ 275 time[t] = julday(depart[1]+time[t], depart[2], depart[0]) 276 END 277 'year':BEGIN 278 if total(fix(time) NE time) NE 0 then $ ; we switch to days with 365d/y 279 time = julday(depart[1], depart[2], depart[0])+round(time*365) $ 280 ELSE for t = 0, n_elements(time)-1 do $ 281 time[t] = julday(depart[1], depart[2], depart[0]+time[t]) 282 END 283 ELSE:BEGIN 284 ncdf_close, cdfid 285 return, report('The "units" attribute of the time axis must be something like: !C "seconds since 0001-01-01 ..." !C "days since 1979-01-01 ..." !C "months since 1979-01-01 ..." !C "years since 1979-01-01 ..."') 286 end 287 ENDCASE 182 ; date1 288 183 date1 = date2jul(beginning[0]) 184 ; date2 289 185 if n_elements(ending) NE 0 then date2 = date2jul(ending[0]) ELSE date2 = date1 290 time = double(time) 291 firsttps = where(time GE date1) & firsttps = firsttps[0]186 ; firsttps 187 firsttps = where(time GE (date1 - 0.9d/86400.d)) & firsttps = firsttps[0] 292 188 if firsttps EQ -1 THEN BEGIN 293 189 ncdf_close, cdfid 294 190 return, report('date 1: '+strtrim(jul2date(date1), 1)+' is not found in the time axis.') 295 191 ENDIF 296 lasttps = where(time LE date2) 297 if lasttps[0] EQ -1 THEN BEGIN 192 ; lasttps 193 lasttps = where(time LE (date2 + 0.9d/86400.d)) & lasttps = lasttps[n_elements(lasttps)-1] 194 if lasttps EQ -1 THEN BEGIN 298 195 ncdf_close, cdfid 299 196 return, report('the time axis has no date before date 2: '+strtrim(jul2date(date2), 1)) 300 197 endif 301 lasttps = lasttps[n_elements(lasttps)-1]302 198 if lasttps LT firsttps then BEGIN 303 199 ncdf_close, cdfid 304 200 return, report('the time axis has no dates between date1 and date 2: '+strtrim(jul2date(date1), 1)+' '+strtrim(jul2date(date2), 1)) 305 201 endif 306 ENDELSE307 time = time[firsttps:lasttps]308 jpt = lasttps-firsttps+1309 END ELSE202 time = time[firsttps:lasttps] 203 jpt = lasttps-firsttps+1 204 END 205 ENDCASE 310 206 ;------------------------------------------------------------ 311 207 ; Name of the grid on which the field refer to. … … 316 212 ; are we in one of the case corresponding to ROMS conventions? 317 213 CASE 1 OF 318 dimnames[2 <(var contient.ndims-1)] EQ 's_w':vargrid = 'W'214 dimnames[2 <(varinq.ndims-1)] EQ 's_w':vargrid = 'W' 319 215 dimnames[0] EQ 'xi_rho' AND dimnames[1] EQ 'eta_rho':vargrid = 'T' 320 216 dimnames[0] EQ 'xi_u' AND dimnames[1] EQ 'eta_u' :vargrid = 'U' … … 342 238 ENDELSE 343 239 ;--------------------------------------------------------------- 344 ; call the init function ?345 ;---------------------------------------------------------------346 347 ;---------------------------------------------------------------348 240 ; redefinition of the domain 349 241 ;--------------------------------------------------------------- 350 if keyword_set(tout) then begin242 IF keyword_set(tout) THEN BEGIN 351 243 nx = jpi 352 244 ny = jpj … … 413 305 ;--------------------------------------------------------------------- 414 306 ;--------------------------------------------------------------------- 415 ; We define global variable joined with the variable.307 ; We define common (cm_4data) variables associated with the variable. 416 308 ;--------------------------------------------------------------------- 417 309 ; varname 418 310 IF NOT keyword_set(callitself) THEN varname = name 419 ; varunit 420 if varcontient.natts NE 0 then begin 421 attnames = strarr(varcontient.natts) 422 for attiq = 0, varcontient.natts-1 do attnames[attiq] = ncdf_attname(cdfid, name, attiq) 423 lowattnames = strlowcase(attnames) 424 ; 425 found = (where(lowattnames EQ 'units'))[0] 426 IF found NE -1 then ncdf_attget, cdfid, name, attnames[found], value ELSE value = '' 427 IF NOT keyword_set(callitself) THEN varunit = strtrim(string(value), 2) 428 ; 429 found = (where(lowattnames EQ 'add_offset'))[0] 430 if found NE -1 then ncdf_attget, cdfid, name, attnames[found], add_offset ELSE add_offset = 0. 431 ; 432 found = (where(lowattnames EQ 'scale_factor'))[0] 433 if found NE -1 then ncdf_attget, cdfid, name, attnames[found], scale_factor ELSE scale_factor = 1. 434 ; 435 missing_value = 'no' 436 found = (where(lowattnames EQ '_fillvalue'))[0] 437 if found NE -1 then ncdf_attget, cdfid, name, attnames[found], missing_value 438 found = (where(lowattnames EQ 'missing_value'))[0] 439 if found NE -1 then ncdf_attget, cdfid, name, attnames[found], missing_value 440 ; 441 ENDIF ELSE BEGIN 442 IF NOT keyword_set(callitself) THEN varunit = '' 443 add_offset = 0. 444 scale_factor = 1. 445 missing_value = 'no' 446 ENDELSE 311 ; varunit and others... 312 ncdf_getatt, cdfid, name, add_offset = add_offset, scale_factor = scale_factor, missing_value = missing_value, units = units 313 IF NOT keyword_set(callitself) THEN varunit = units 447 314 ; vardate 448 315 ; We make a legible date in function of the specified language. … … 455 322 ; We apply the value valmask on land points. 456 323 if NOT keyword_set(cont_nofill) then begin 457 valmask = 1 e20324 valmask = 1.e20 458 325 case 1 of 459 varcontient.ndims eq 2:BEGIN ;xy array 460 mask = mask[*, *, 0] 326 varinq.ndims eq 2:BEGIN ;xy array 327 earth = where(mask[*, *, 0] EQ 0) 328 END 329 varinq.ndims eq 3 AND (where(varinq.dim EQ inq.recdim))[0] EQ -1:BEGIN ;xyz array 461 330 earth = where(mask EQ 0) 462 331 END 463 varcontient.ndims eq 3 AND (where(varcontient.dim EQ contient.recdim))[0] EQ -1:BEGIN ;xyz array 464 earth = where(mask EQ 0) 465 END 466 varcontient.ndims eq 3 AND (where(varcontient.dim EQ contient.recdim))[0] NE -1:BEGIN ;xyt array 467 mask = mask[*, *, 0] 468 earth = where(mask EQ 0) 332 varinq.ndims eq 3 AND (where(varinq.dim EQ inq.recdim))[0] NE -1:BEGIN ;xyt array 333 earth = where(mask[*, *, 0] EQ 0) 469 334 if earth[0] NE -1 then BEGIN 470 335 earth = earth#replicate(1, jpt)+replicate(nx*ny, n_elements(earth))#lindgen(jpt) 471 336 END 472 337 END 473 var contient.ndims eq 4:BEGIN ;xyzt array338 varinq.ndims eq 4:BEGIN ;xyzt array 474 339 earth = where(mask EQ 0) 475 340 if earth[0] NE -1 then BEGIN … … 477 342 END 478 343 END 479 endcase344 ENDCASE 480 345 ENDIF ELSE earth = -1 481 346 ; we look for missing_value 347 ; we apply add_offset, scale_factor and missing_value 348 IF keyword_set(addscl_before) THEN BEGIN 349 if scale_factor NE 1 then res = temporary(res)*scale_factor 350 if add_offset NE 0 then res = temporary(res)+add_offset 351 ENDIF 482 352 IF size(missing_value, /type) NE 7 then BEGIN 483 IF size(missing_value, /type) EQ 1 THEN BEGIN 484 missing_value = strlowcase(string(missing_value)) 485 IF strmid(missing_value, 0, 1, /reverse_offset) EQ 'f' THEN $ 486 missing_value = strmid(missing_value, 0, strlen(missing_value)-1) 487 IF isnumber(string(missing_value), tmp) EQ 1 THEN missing_value = tmp ELSE BEGIN 488 ras = report('Warning: missing value is not a number: ' + missing_value) 489 missing_value = - 1 490 ENDELSE 491 ENDIF 492 ; if missing_value NE valmask then begin 493 if abs(missing_value) LT 1e6 then missing = where(res EQ missing_value) $ 494 ELSE missing = where(abs(res) gt abs(missing_value)/10.) 495 ; ENDIF ELSE missing = -1 353 IF finite(missing_value) EQ 1 THEN BEGIN 354 CASE 1 OF 355 missing_value GT 1.e6:missing = where(res GT missing_value-10.) 356 missing_value LT -1.e6:missing = where(res LT missing_value+10.) 357 abs(missing_value) LT 1.e-6:missing = where(res LT 1.e-6) 358 ELSE:missing = where(res EQ missing_value) 359 ENDCASE 360 ENDIF ELSE missing = where(finite(res) EQ 0) 496 361 ENDIF ELSE missing = -1 497 ; we apply add_offset, scale_factor and missing_value 498 if scale_factor NE 1 then res = temporary(res)*scale_factor 499 if add_offset NE 0 then res = temporary(res)+add_offset 362 IF NOT keyword_set(addscl_before) THEN BEGIN 363 if scale_factor NE 1 then res = temporary(res)*scale_factor 364 if add_offset NE 0 then res = temporary(res)+add_offset 365 ENDIF 500 366 if missing[0] NE -1 then res[temporary(missing)] = !values.f_nan 501 367 if earth[0] NE -1 then res[temporary(earth)] = 1.e20 … … 508 374 ncdf_attget, cdfid, 'hc', hc, /global 509 375 ; look for all variables names 510 allvarnames = strarr( contient.nvars)511 FOR i = 0, contient.nvars-1 DO BEGIN376 allvarnames = strarr(inq.nvars) 377 FOR i = 0, inq.nvars-1 DO BEGIN 512 378 tmp = ncdf_varinq( cdfid, i) 513 379 allvarnames[i] = tmp.name -
trunk/SRC/ToBeReviewed/LECTURE/read_ncdf_varget.pro
r231 r271 97 97 ;...................................................................... 98 98 ;...................................................................... 99 var contient.ndims eq 2:BEGIN ;xy array99 varinq.ndims eq 2:BEGIN ;xy array 100 100 ;...................................................................... 101 101 ;...................................................................... … … 185 185 ;...................................................................... 186 186 ;...................................................................... 187 var contient.ndims eq 3 AND (where(varcontient.dim EQ contient.recdim))[0] EQ -1:BEGIN ;xyz array187 varinq.ndims eq 3 AND (where(varinq.dim EQ inq.recdim))[0] EQ -1:BEGIN ;xyz array 188 188 ;...................................................................... 189 189 ;...................................................................... … … 276 276 ;...................................................................... 277 277 ;...................................................................... 278 var contient.ndims eq 3 AND (where(varcontient.dim EQ contient.recdim))[0] NE -1:BEGIN ;xyt array278 varinq.ndims eq 3 AND (where(varinq.dim EQ inq.recdim))[0] NE -1:BEGIN ;xyt array 279 279 ;...................................................................... 280 280 ;...................................................................... … … 376 376 ;...................................................................... 377 377 ;...................................................................... 378 var contient.ndims eq 4:BEGIN ;xyzt array378 varinq.ndims eq 4:BEGIN ;xyzt array 379 379 ;...................................................................... 380 380 ;...................................................................... … … 481 481 ; we apply reverse 482 482 IF keyword_set(key_yreverse) AND ny NE 1 THEN BEGIN 483 IF var contient.ndims - ((where(varcontient.dim EQ contient.recdim))[0] NE -1) EQ 2 THEN $483 IF varinq.ndims - ((where(varinq.dim EQ inq.recdim))[0] NE -1) EQ 2 THEN $ 484 484 res = reverse(reform(res, nx, ny, jpt, /overwrite), 2) $ 485 485 ELSE res = reverse(reform(res, nx, ny, nz, jpt, /overwrite), 2) 486 486 ENDIF 487 487 if keyword_set(key_zreverse) AND nz NE 1 $ 488 AND var contient.ndims - ((where(varcontient.dim EQ contient.recdim))[0] NE -1) EQ 3 THEN $488 AND varinq.ndims - ((where(varinq.dim EQ inq.recdim))[0] NE -1) EQ 3 THEN $ 489 489 res = reverse(reform(res, nx, ny, nz, jpt, /overwrite), 3) 490 490 ;
Note: See TracChangeset
for help on using the changeset viewer.