;+ ; ; @file_comments ; reading timeseries writing on many files ; ; @categories ; Reading ; ; @param var {in} {type=string} ; the name of the variable to be read ; ; @param date1 {in} {type=scalar} ; give the first date of the time series. ; Date format is ymmdd, yymmdd, yyymmdd, yyyymmdd, yyyyymmdd, yyyyyymmdd. ; ; @param date2 {in} {type=scalar} ; give the last date of the time series. ; Date format is ymmdd, yymmdd, yyymmdd, yyyymmdd, yyyyymmdd, yyyyyymmdd. ; ; @param expin {in} {type=string} {default=varexp} ; the name of the experiment. ; ; @param freqin {in} {type=string} {default='5d'} ; the averaging frequency. ; ; @keyword CENTURY {type=integer} ; give the true century of the calendar. ; for example if filename is AA5_5d_920101_921231* and the calendar variable ; in the file is 19920101 to 19921231 then CENTURY=19 ; ; @keyword NOSTRUCT {default=1} ; Set this keyword to return an array instead of a structure. ; ; @keyword GRIDTYPE ; name of the grid to be read 'grid_T' ++'gridT' ; ; @keyword _EXTRA ; Used to pass read_ncdf keywords ; ; @returns ; a structure with the following Structure Tags: ; arr:the array output ; grid: the array grid ; units: the array units ; experiment: the name of the experiment ; name: the name of the variable ; ; @uses ; common ; ; @restrictions ; Update the time and jpt common variables. ; Time is the calendar in IDL julian days. ; 1) The file must contain an unlimited dimension, and the ; variable to be read must contain this unlimited dimension. ; 2) The file must contain a one dimension variable which ; dimension is the unlimited dimension. This variable is the ; calendar. ; 3) This variable calendar must have an attribut called "units" ; which must have a format similar to ; "seconds since 0001-01-01 00:00:00" ; "hours since 0001-01-01 00:00:00" ; "days since 1979-01-01 00:00:00" ; "months since 1979-01-01 00:00:00" ; "years since 1979-01-01 00:00:00" ; 4) The calendar must be the Gregorian calendar ; 5) The name of the file must beginning by ; exp_freq_datefirst_datelast_* ; 6) The maximum gap between 2 consecutive files must be one day. ; ; @examples ; IDL> res = rseries_ncdf('sozotaux',920501,930410,'AA5','5d') ; ; for ORCA2 outputs ; IDL> iodir='/usr/work/sur/fvi/OPA/ORCA2/' ; IDL> res= rseries_ncdf('votemper',010101,061231,'ESS','5d') ; IDL> help,res,/structure ; ;** Structure <310ebc0>, 5 tags, length=1800, data length=1800, refs=1: ; ARR FLOAT Array[1, 1, 1, 438] ; GRID STRING 'T' ; UNITS STRING 'C' ; EXPERIMENT STRING 'ESS_5d_060101_061231_grid_T.nc' ; NAME STRING 'votemper' ; ; @history ; Sebastien Masson (smasson\@lodyc.jussieu.fr) Apr 23 2001 ; ; @todo ; adaptation to Drakkar terminologie ; ORCA2 terminology of output files ; experience_5d_yymmdd_yymmdd_grid.nc ; with experience in 'ESS' ; with grid in 'grid_T' ; ; ORCA025 terminology of output files ; /u/rech/cli/rcli002/ORCA025/ORCA025-experience_drakkar-S/year_drakkar/ORCA025-experience_drakkar-yyear_drakkarnmoisdjour_grid.nc ; with experience_drakkar in 'G70', ; with grid in 'gridT' ; ; @version ; $Id$ ; ;- FUNCTION rseries_ncdf, var, date1, date2, expin, freqin, CENTURY = century, NOSTRUCT = nostruct, GRIDTYPE = gridtype, _EXTRA = ex @common ; name of the file: exp_freq_datefirst_datelast_* date1 = (long(date1))[0] date2 = (long(date2))[0] if date2 LT date1 then return, report('date2 must be larger than date1') if n_elements(expin) EQ 0 then exp = varexp ELSE BEGIN IF (strpos(expin, '_'))[0] NE -1 AND n_elements(freqin) EQ 0 THEN BEGIN exp = strmid(expin, 0, strpos(expin, '_')) freqin = strmid(expin, strpos(expin, '_')+1) ENDIF ELSE exp = expin varexp = exp ENDELSE if n_elements(freqin) EQ 0 then freq = '5d' ELSE freq = freqin ;------------------------------------------------ ; determination of the filename beginning with exp_freq_* ;------------------------------------------------ IF keyword_set(gridtype) EQ 0 THEN gridtype = '' ; determination OF datefirst and datelast ; list of the files beginning by iodir+exp+sep+freq sep = '_' possiblenames = iodir+exp+sep+freq+'*'+gridtype+'.nc' possiblenames = findfile(possiblenames) if possiblenames[0] EQ '' then return, report('nofilename :'+iodir+exp+sep+freq+'*'+gridtype+'.nc'+' found') npos = n_elements(possiblenames) ; list of the datefirst and datelast of the files beginning by ; iodir+exp+sep+freq datefirst = lonarr(npos) datelast = lonarr(npos) sepshift = n_elements(str_sep(exp, sep))-1 for i = 0, npos-1 do BEGIN separate = str_sep(possiblenames[i], sep) datefirst[i] = separate[2+sepshift] datelast[i] = separate[3+sepshift] ENDFOR ; selection of the files for which datefirst le date1 and datelast ge ; date1 CASE strmid(freqin, 0, 1, /rever) OF 'm' : div = 100 'y' : div = 10000 ELSE : div = 1 ENDCASE goodfile = where(datefirst le date1/div and datelast GE date1/div) if goodfile[0] EQ -1 then return, report('filename :'+iodir+exp+sep+freq+'*'+gridtype+'.nc'+' not found with the dates containing '+strtrim(date1, 1)) datefirst = datefirst[goodfile] datelast = datelast[goodfile] ; how many different pairs of dates are present ? ; find the unique pairs of dates pairofdate = dcomplex(datefirst, datelast) pairofdate = pairofdate[uniq(pairofdate, sort(pairofdate))] fileok = '' datefirstok = 0L datelastok = 0L ; loop on the files for which date1 is between datefirst and datelast for p = 0, n_elements(pairofdate)-1 do begin ; name of the file: exp_freq_datefirst_datelast_* datefirst = long(pairofdate[p]) datelast = long(imaginary(pairofdate[p])) ; determination OF the possible filenames ; test if the year format is i1, i2, i3, i4, i5 or i6 namebegin = iodir+exp+sep+freq+sep+strtrim(datefirst, 1)+sep+strtrim(datelast, 1)+'*'+gridtype+'.nc' namebegin = findfile(namebegin) possiblenames = '' if namebegin[0] NE '' then possiblenames = [possiblenames, namebegin] if datefirst LT 1e9 then begin for i = 1, 5-(datefirst GE 1e5)-(datefirst GE 1e6) $ -(datefirst GE 1e7)-(datefirst GE 1e8) do begin zero = string(replicate(byte('0'), i)) namebegin = iodir+exp+sep+freq+sep $ + zero+strtrim(datefirst, 1) +sep+ zero+strtrim(datelast, 1) +'*'+gridtype+'.nc' namebegin = findfile(namebegin) if namebegin[0] NE '' then possiblenames = [possiblenames, namebegin] endfor ENDIF if n_elements(possiblenames) eq 1 then return, report('filename :'+iodir+exp+sep+freq+sep+'*'+strtrim(datefirst, 1)+sep+'*'+strtrim(datelast, 1)+'*'+gridtype+'.nc'+' not found') possiblenames = possiblenames[1:n_elements(possiblenames)-1] ; determination OF the filenames ncdf_control, 0, /noverbose i = 0 repeat BEGIN cdfid = ncdf_open(possiblenames[i]) ; print,possiblenames[i],var test = ncdf_varid(Cdfid, var) ncdf_close, cdfid i = i+1 endrep until test NE -1 OR i EQ n_elements(possiblenames) ncdf_control, 0, /verbose if test NE -1 then begin fileok = [fileok, possiblenames[i-1]] datefirstok = [datefirstok, datefirst] datelastok = [datelastok, datelast] endif ENDFOR numoffileok = n_elements(fileok)-1 if numoffileok EQ 0 then return, report('the variable '+var+' was not fond in the file: '+possiblenames) fileok = fileok[1:numoffileok] datefirstok = datefirstok[1: numoffileok] datelastok = datelastok[1: numoffileok] if numoffileok NE 1 then BEGIN ; more than one file containts the variable var and has the date1 ; between datefirst and datelast... ; Is there any file FOR which date2 LE datelast? goodfile = where(date2 LE datelastok) if goodfile[0] NE -1 then begin fileok = fileok[goodfile] datefirstok = datefirstok[goodfile] datelastok = datelastok[goodfile] ; we choose the file which has the smallest datelast bestfile = sort(datelastok) filename = fileok[bestfile[0]] datefirst = datefirstok[bestfile[0]] datelast = datelastok[bestfile[0]] ENDIF ELSE BEGIN ; we choose the file which has the bigest datelast bestfile = sort(datelastok) filename = fileok[bestfile[numoffileok-1]] datefirst = datefirstok[bestfile[numoffileok-1]] datelast = datelastok[bestfile[numoffileok-1]] ENDELSE ENDIF ELSE BEGIN filename = fileok[0] datefirst = datefirstok[0] datelast = datelastok[0] ENDELSE ; now we have find the good file with the good dates and the godd ; variable inside. ; we get the number of dimension of the variable cdfid = ncdf_open(filename) varcontient = ncdf_varinq(cdfid, var) ncdf_close, cdfid ; ;------------------------------------------------ ; reading of the variables ;------------------------------------------------ ; if NOT keyword_set(century) then century = 0l IF chkstru(ex, 'filename') THEN ex.filename = filename CASE strmid(freqin, 0, 1, /rever) OF 'm':datelast = 100*datelast + daysinmonth(datelast MOD 100, datelast / 100) 'y':div = 10000*datelast+360+(5+leapyr(datelast+century))*(key_caltype EQ 'greg') ELSE : div = 1 ENDCASE if date2 GT datelast THEN BEGIN ; if we need to read more than one file, ; first we read the first file ;++ print,var,date1+century*1000000L, datelast[0]+century*1000000L ;++READ, B, PROMPT='Enter Name: ' res1 = read_ncdf(var, date1+century*1000000L, datelast[0]+century*1000000L $ , filename = filename, /nostruct, _extra = ex) time1 = time ; store the first part of the calendar jpt1 = jpt ; store the number time steps already read ; and after we call again rseries_ncdf ; newdatefirst is defined as datelast+1day newdatefirst = jul2date(date2jul(datelast)+1) res2 = rseries_ncdf(var, newdatefirst, date2, exp, freq, /NOSTRUCT, _extra = ex) ; ; CASE 1 OF res1[0] EQ -1 AND res2[0] EQ -1: return, -1 res1[0] EQ -1:res = temporary(res2) res2[0] EQ -1:BEGIN time = time1 jpt = jpt1 res = temporary(res1) END ELSE : BEGIN ; we glue the result of the first read and the result of the new call ; to rseries_ncdf time = [time1, time] jpt = jpt1+jpt case varcontient.ndims OF 1:res = [temporary(res1), temporary(res2)] 2:res = [ [temporary(res1)], [temporary(res2)] ] 3:res = [ [ [temporary(res1)] ], [ [temporary(res2)] ] ] 4:BEGIN res = [(temporary(res1))[*], (temporary(res2))[*]] grille, mask, glam, gphi, gdep, nx, ny, nz res = reform(res, nx, ny, nz, jpt, /over) END ENDCASE ENDELSE ENDCASE endif ELSE BEGIN res = read_ncdf(var, date1+century*1000000L, date2+century*1000000L $ , filename = filename, /nostruct, _extra = ex) ENDELSE ;------------------------------------------------ if keyword_set(nostruct) then return, res $ ELSE return, {arr:res, grid:vargrid, units:varunit, experiment:varexp, name:varname} end