;; read_ims - reads 24 km or 4 km ascii IMS data files, and saves ;; the data array to a flat binary file. ;; ;; 02/16/2007 Mary Jo Brodzik 303-492-8263 ;; National Snow & Ice Data Center, University of Colorado, Boulder ;; Copyright (C) 2007-8 Regents of the University of Colorado ;; ;; $Revision: 15531 $ ;; function char_to_int_line, buffer cols = strlen(buffer) row = intarr(cols) for i=0, cols - 1 do begin char = strmid(buffer, i, 1) row[i] = fix(char) endfor return, row end function read_ims, filename, VERBOSE=do_verbose do_verbose = keyword_set( do_verbose ) ? do_verbose : 0 rows = 0 cols = 0 buffer = '' line_number = 0 num_dim_units_found = 0 openr, lun, filename, /get_lun while (not eof(lun)) do begin readf, lun, buffer line_number = line_number + 1 if do_verbose then print, "Header Line(", line_number, "):", buffer if stregex(buffer, "Dimensions", /boolean) then begin parts = strsplit(buffer, /regex, /extract) rows = parts[1] cols = parts[2] endif else if stregex(buffer, 'Dim Units', /boolean) then begin num_dim_units_found = num_dim_units_found + 1 endif if 2 eq num_dim_units_found then break endwhile if do_verbose then begin print, "End of header," print, "rows = ", rows print, "cols = ", cols endif if eof(lun) then begin free_lun, lun print, "End of file, no data found." return, -1 endif ;; There are two ways that NOAA stored the data array ;; one is chars of 0-4, nospaces ;; The other is 4-column chars with space separators ;; If the first character on this line is a space, ;; then assume that it's the 4-column chars format. ;; Read the next line in the file, to decide how to proceed ;; and then rewind to the beginning of this line before ;; continuing point_lun, -1 * lun, pos readf, lun, buffer point_lun, lun, pos if do_verbose then print, "First Data Line:", buffer if ( ' ' eq strmid(buffer, 0, 1) ) then begin do_expanded = 1 if do_verbose then print, "Reading data in expanded form." endif else begin do_expanded = 0 if do_verbose then print, "Reading data in compressed form." endelse data = bytarr(cols, rows) if do_expanded then begin ;; Expanded form has a lot of white space, ;; and a data row spans several rows in the file. ;; So read data until a row's worth is read in ;; and then convert it to byte data for output for i=0, rows - 1 do begin if 0 eq i mod 100 then print, "Row ", i length = 0 row_str = '' while cols gt length do begin readf, lun, buffer ;; Split the buffer on white space, and convert ;; color indices to data values, according to ;; color 165 -> data 4 (snow) ;; color 164 -> data 3 (ice) parts = strsplit( buffer, ' +', /extract, /regex ) idx = where( '165' eq parts, count) if 0 lt count then parts[idx] = '4' idx = where( '164' eq parts, count) if 0 lt count then parts[idx] = '3' buffer = strjoin( parts, '' ) row_str = row_str + strcompress( buffer, /rem ) length = strlen( row_str ) endwhile ;; Check for the expected number of columns in this row if cols ne length then begin free_lun, lun print, "Error in expanded data columns found. Exiting." print, "Problematic line has length ", length," and is:" print, row_str return, -1 endif if do_verbose then print, "Data Line(", i, "):", row_str ;; Convert this row to bytes and save row = char_to_int_line( row_str ) data[*, i] = row endfor endif else begin for i=0, rows - 1 do begin if 0 eq i mod 100 then print, "Row ", i readf, lun, buffer if do_verbose then print, "Data Line(", i, "):", buffer row = char_to_int_line(buffer) data[*, i] = row endfor endelse free_lun, lun data = reverse( data, 2 ) outfile = filename + '.bin' openw, lun, outfile, /get writeu, lun, data free_lun, lun print, "Wrote data to ", outfile return, data end