;---------------------------------------------------------------------------- ;+ ; NAME: ; EXTRACT ; PURPOSE: ; Extracts a portion of the data from a given binary array. ; CATEGORY: ; CALLING SEQUENCE: ; a = extract() -> Displays description of extract ; new_attribute_structure = extract(ip) ; INPUTS: ; The function parameter can be a structure obtained from read_hdr() ; routine or a binary data array. ; COMMON BLOCKS: ; Uses the ext_cmn_blok, for the sake of widget interface. ; PROCEDURES CALLED FROM EXTRACT: ; If the input parameter is a binary array, a widget driven procedure ; is called to create a header for the given data array -- MAKE_HDR ; ; The header that is created in this way is loaded on to a structure ; using --READ_HDR ; KEYWORD PARAMETERS: ; MINLON=begin_lon Minimum extract value along the longitude. ; MAXLON=end_lon Maximum extract value along the longitude. ; MINLAT=begin_lat Minimum extract value along the latitude ; MAXLAT=end_lat Maximum extract value along the latitude. ; TIME=new_t Index number of the time band to extract. ; LEVEL=new_z Index number of the level to extract. ; VAR=new_v Index number of the variable to extract. ; ; KEYWORDS: ; /WHOLE Key word to image the whole data range. ; OUTPUTS: ; A structure containing the extracted information ; AUTHOR: ; J. Kirani -June 5, 1995. ; MODIFICATIONS: ; Don Anderson 28 March 2000 Added "silent" flag ; Don Anderson 22 June 2000 Corrected var_strc extraction bug ; Don Anderson 19 July 2000 Added /noscale option ;---------------------------------------------------------------------------- ;;;;;;;;;;;;;;;;; Extract routine;;;;;;;;;;;;;;;;;;;;;; function extract, ip,minlon=begin_lon,maxlon=end_lon,minlat=begin_lat,$ maxlat=end_lat,mintime=new_min_t,maxtime=new_max_t,$ minlevel=new_min_z,maxlevel=new_max_z,minvar=new_min_v,$ maxvar=new_max_v,time=new_t,level=new_z,var=new_v,$ whole=whole_rgn,text=text_ip, silent=silent, noscale=noscale @ext_cmn_blok if keyword_set(text_ip) then text_input=0 else text_input =1 if n_elements(new_min_z) eq 0 and n_elements(new_z) eq 0 $ then z_sub=0 else z_sub=1 if n_elements(new_min_t) eq 0 and n_elements(new_t) eq 0 $ then t_sub=0 else t_sub=1 if n_elements(new_min_v) eq 0 and n_elements(new_v) eq 0 $ then v_sub=0 else v_sub=1 flag='n' file='' if n_params() eq 0 then begin print,'CALLING SEQUENCE :' print,'struct=extract(bin_arr or struct generated by read_hdr)' print,'This function returns the extracted information from the given array or the structure' print,'Keywords:' print,' MINLON = begin_lon Minimum extract value along the longitude' print,' MAXLON = end_lon Maximum extract value along the longitude' print,' MINLAT = begin_lat Minimum extract value along the latitude' print,' MAXLAT = end_lat Maximum extract value along the latitude' print,' MINTIME = new_min_t Time band lower range' print,' MAXTIME = new_max_t Time band upper range' print,' TIME = new_t One time band' print,' MINLEVEL = new_min_z Level lower range' print,' MAXLEVEL = new_max_z Level upper range' print,' LEVEL = new_z One level' print,' MINVAR = new_min_v Variable lower range' print,' MAXVAR = new_max_v Variable upper range' print,' VAR = new_v One variable' print,' /WHOLE Key word to image the whole data range' print,' /TEXT Key word to specify keyboard input' print,' /SILENT Key word to turn off echoed information' goto, stop endif ;;;;;;;;;; Check whether 'ip' is an array or a structure ;;;;;;;;; size_out=size(ip) if size_out(size_out(0)+1) ne 8 then begin size_out=size(ip) print, 'Header file not available, Creating one...' make_hdr ; Widget routine to create header print,'Enter the name of the header file just created ..' read,file if ( keyword_set ( noscale ) ) then ip = read_hdr(file, /noscale) $ else ip = read_hdr(file) endif struct = ip data_arr=struct.a if n_elements(new_t) gt 0 then begin new_min_t = new_t new_max_t = new_t endif if n_elements(new_z) gt 0 then begin new_min_z = new_z new_max_z = new_z endif if n_elements(new_v) gt 0 then begin new_min_v = new_v new_max_v = new_v endif ;;;;;;;;; check if the array has any data ;;;;;;;;;;;;;;;;;;;;;;; size_out=size(data_arr) if size_out(size_out(0)+2) eq 0 then begin print,'Data array is empty' return,0 endif struct.x_lnr.gridpts = size_out(1) struct.y_lnr.gridpts = size_out(2) init ; Initialise all the globals. z_min_index = 0 z_max_index = struct.z_lvl.no_levels - 1 v_min_index = 0 v_max_index = struct.no_vars -1 t_min_index = 0 t_max_index = struct.t_lnr.no_times -1 ;;;;;;;;;; Set the extract range ;;;;;;;;;;;;;;;;;;;;;;; min_lon = (struct.x_lnr.startpt - struct.x_lnr.incr * 0.5) min_lat = (struct.y_lnr.startpt - struct.y_lnr.incr * 0.5) max_lon = (struct.x_lnr.gridpts * struct.x_lnr.incr) + min_lon max_lat = (struct.y_lnr.gridpts * struct.y_lnr.incr) + min_lat if ( not(keyword_set(whole_rgn)) and (n_elements(begin_lon) eq 0) and $ (n_elements(end_lon) eq 0) and (n_elements(begin_lat) eq 0) and $ (n_elements(end_lat) eq 0) ) then begin flag='n' endif else begin flag='y' endelse ; ; If any one of the min max lat/lon are given as parameter then the things ; not specified are considered to have the maximum possible values... ; ; if flag eq 'y' then begin if n_elements(begin_lon) eq 0 then begin_lon=min_lon if n_elements(end_lon) eq 0 then end_lon=max_lon if n_elements(begin_lat) eq 0 then begin_lat=min_lat if n_elements(end_lat) eq 0 then end_lat=max_lat if (min_lon LT 0.0 AND (begin_lon GT 180.0 OR end_lon GT 180.0)) then begin begin_lon = begin_lon - 360.0 end_lon = end_lon - 360.0 endif if (min_lon GT 180.0 AND (begin_lon LT 0.0 OR end_lon LT 0.0)) then begin begin_lon = begin_lon + 360.0 end_lon = end_lon + 360.0 endif endif ;print,"min_lon = ",min_lon ;print,"max_lon = ",max_lon ;print,"begin_lon = ",begin_lon ;print,"end_lon = ",end_lon ; ; ; If the text keyword is set then input the parameters thro' keyboard ; ; if (flag eq 'n') and keyword_set(text_ip) then begin print,'You can extract between',min_lon,' E',max_lon ,' W' print,'And ',min_lat,' S',max_lat,' N' print,'Enter the min_longitude :' read,begin_lon print,'Enter the max_longitude :' read,end_lon print,'Enter the min_latitude :' read,begin_lat print,'Enter the max_latitude :' read,end_lat endif ; ; ; Loads up the possible choices to be displayed ; range=intarr(2) if (size_out(0) eq 3) then begin select_z,struct,range z_min_index=range(0) z_max_index=range(1) endif if (size_out(0) eq 4) then begin select_z,struct,range z_min_index=range(0) z_max_index=range(1) select_t,struct,range t_min_index=range(0) t_max_index=range(1) endif if (size_out(0) eq 5) then begin select_z,struct,range z_min_index=range(0) z_max_index=range(1) select_t,struct,range t_min_index=range(0) t_max_index=range(1) select_v,struct,range v_min_index=range(0) v_max_index=range(1) endif ;;;;;;;;;;; widget interface ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; If the text keyword is not set then display widget interface ; ; selected_mintime = 0 selected_maxtime = t_max_index selected_minlev = 0 selected_maxlev = z_max_index selected_minvar = 0 selected_maxvar = v_max_index if not(keyword_set(text_ip)) then begin if n_elements(new_min_t) eq 0 or $ n_elements(new_min_v) eq 0 or $ n_elements(new_min_z) eq 0 or $ n_elements(new_max_t) eq 0 or $ n_elements(new_max_z) eq 0 or $ n_elements(new_max_v) eq 0 or $ n_elements(begin_lon) eq 0 or $ n_elements(begin_lat) eq 0 or $ n_elements(end_lon) eq 0 or $ n_elements(end_lat) eq 0 then select_widget,struct,flag z_min_index = selected_minlev z_max_index = selected_maxlev t_min_index = selected_mintime t_max_index = selected_maxtime v_min_index = selected_minvar v_max_index = selected_maxvar if flag eq 'n' then begin begin_lon=selected_minlon - struct.x_lnr.incr * 0.5 end_lon=selected_maxlon + struct.x_lnr.incr * 0.5 begin_lat=selected_minlat - struct.y_lnr.incr * 0.5 end_lat=selected_maxlat + struct.y_lnr.incr * 0.5 endif endif ;;;;;;;;;;; Check for extract ranges ;;;;;;;;;;;;;;;;;;;;;;;;;; if ((end_lon le begin_lon) or (end_lon gt max_lon) or $ (end_lat le begin_lat) or (end_lat gt max_lat) or (begin_lon lt min_lon) or $ (begin_lat lt min_lat) ) then begin print,'Incorrect extract range' return,0 endif ;;;;;;;;;;;; Levels, vars and time ;;;;;;;;;;;;;;;;;; ; ; If the selection of time and variable and level are specified as parameters ; then use them in the extraction ; if n_elements(new_min_z) GT 0 then z_min_index=new_min_z-1 if n_elements(new_max_z) GT 0 then z_max_index=new_max_z-1 if n_elements(new_min_t) GT 0 then t_min_index=new_min_t-1 if n_elements(new_max_t) GT 0 then t_max_index=new_max_t-1 if n_elements(new_min_v) GT 0 then v_min_index=new_min_v-1 if n_elements(new_max_v) GT 0 then v_max_index=new_max_v-1 if not keyword_set(silent) then begin print, 'Begin longitude',begin_lon print, 'End longitude',end_lon print, 'Begin latitude',begin_lat print, 'End latitude', end_lat print, 'Min Level selected',z_min_index print, 'Max Level selected',z_max_index print, 'Min Time selected',t_min_index print, 'Max Time selected',t_max_index print, 'Min Var selected',v_min_index print, 'Max Var selected',v_max_index endif ;;;;;;; Finding the array index from the longitude and latitude ;;;;;;; begin_x = fix((begin_lon - min_lon)/struct.x_lnr.incr) end_x = struct.x_lnr.gridpts - fix((max_lon - end_lon)/struct.x_lnr.incr)-1 begin_y = fix((begin_lat - min_lat)/struct.y_lnr.incr) end_y = struct.y_lnr.gridpts - fix((max_lat - end_lat)/struct.y_lnr.incr)-1 if not keyword_set(silent) then begin print,'Beginning of x-value',begin_x print,'end of x-value',end_x print,'Beginning of y-value',begin_y print,'end of y-value',end_y endif ;;;;;;;; extraction taking care of the order ;;;;;;;;;;;;;;;;;;;;;;; if (struct.order_info eq 1) then begin new_arr=data_arr(begin_x:end_x,$ (struct.y_lnr.gridpts - end_y-1):(struct.y_lnr.gridpts - begin_y-1),*,*,* ) endif else begin new_arr=data_arr(begin_x:end_x, begin_y:end_y,*,*,*) endelse ;;;;;;;;;;; Change the attributes according to extraction range ;;;;;;;;;;; new_arr1=new_arr(*,*,z_min_index:z_max_index,t_min_index:t_max_index,$ v_min_index:v_max_index) size_out=size(new_arr1) ; By default, output data are floats outarr = fltarr ( size_out(1), size_out(2), $ (z_max_index-z_min_index+1), (t_max_index-t_min_index+1), $ v_max_index-v_min_index+1 ) if (keyword_set (noscale)) then begin case struct.dat_type of 'INTEGER' : outarr = intarr ( size_out(1), size_out(2), $ (z_max_index-z_min_index+1), (t_max_index-t_min_index+1), $ v_max_index-v_min_index+1 ) 'LONG' : outarr = lonarr ( size_out(1), size_out(2), $ (z_max_index-z_min_index+1), (t_max_index-t_min_index+1), $ v_max_index-v_min_index+1 ) 'FLOAT' : outarr = fltarr ( size_out(1), size_out(2), $ (z_max_index-z_min_index+1), (t_max_index-t_min_index+1), $ v_max_index-v_min_index+1 ) 'BYTE' : outarr = bytarr ( size_out(1), size_out(2), $ (z_max_index-z_min_index+1), (t_max_index-t_min_index+1), $ v_max_index-v_min_index+1 ) endcase endif new_st = {x_lnr:{lin},y_lnr:{lin},$ t_lnr:{time},z_lvl:{levl},$ var_strc:replicate({v_st},20),dat_set:'',dat_type:'',$ msk_val:0.0,no_vars:0,scl_ftr:1.0,$ ttl_str:'',units:'',unk:0.0,h_flag:0,order_info:0,$ x_ext:'',y_ext:'',z_ext:'',t_ext:'',v_ext:'',$ a:outarr } ;;;;;;;;;;; Store the new range of lat/lon values ;;;;;;;;;;;;;;;;;;;;;;;;;;;; new_st.y_lnr.startpt = begin_lat + struct.y_lnr.incr * 0.5 new_st.y_lnr.gridpts = size_out(2) ;new_st.y_lnr.gridpts = (end_lat - begin_lat) / struct.y_lnr.incr new_st.y_lnr.incr=struct.y_lnr.incr new_st.y_lnr.maptype='LINEAR' new_st.y_ext=struct.y_ext new_st.x_lnr.startpt = begin_lon + struct.x_lnr.incr * 0.5 new_st.x_lnr.gridpts = size_out(1) ;new_st.x_lnr.gridpts = (end_lon - begin_lon) / struct.x_lnr.incr new_st.x_lnr.incr=struct.x_lnr.incr new_st.x_lnr.maptype='LINEAR' new_st.x_ext=struct.x_ext ;;;;;;;;;;; Change the z-info only if a new level is chosen ;;;;;;;;;;;;;;;; if z_display_arr(z_min_index) ne '' then begin new_st.z_lvl.no_levels = z_max_index - z_min_index +1 new_st.z_lvl.maptype = 'LEVELS' for i=z_min_index,z_max_index,1 do begin new_st.z_lvl.lev(i) = float(z_display_arr(i)) endfor endif else begin new_st.z_lvl = struct.z_lvl endelse ;;;;;;;;;; Change the time if new time is chosen ;;;;;;;;;;;;;;;;;;;;;;; new_st.t_lnr.maptype = 'LINEAR' if t_display_arr(t_min_index) ne '' then begin new_st.t_lnr.no_times =t_max_index - t_min_index +1 space = ' ' i = StrParse(t_display_arr(t_min_index),space,words) space = ':' i = StrParse(words(0),space,hr) new_st.t_lnr.hour = fix(hr(0)) new_st.t_lnr.minutes = fix(hr(1)) new_st.t_lnr.day = fix(words(1)) new_st.t_lnr.mon = words(2) new_st.t_lnr.year = fix(words(3)) new_st.t_lnr.incr_by = struct.t_lnr.incr_by new_st.t_lnr.incr_unit = struct.t_lnr.incr_unit endif else begin new_st.t_lnr = struct.t_lnr endelse for i=v_min_index, v_max_index, 1 do begin ;BUG: new_st.var_strc(i-v_min_index)=struct.var_strc(i-v_min_index) new_st.var_strc(i-v_min_index)=struct.var_strc(i) endfor new_st.no_vars=v_max_index - v_min_index+1 new_st.dat_set=struct.dat_set new_st.dat_type=struct.dat_type new_st.msk_val=struct.msk_val new_st.ttl_str=struct.ttl_str new_st.unk=struct.unk new_st.scl_ftr = struct.scl_ftr new_st.units = struct.var_strc(0).var_units new_st.h_flag=struct.h_flag new_st.order_info=struct.order_info new_st.a=new_arr1 ;;;;;;;;;; Set the sub titles ;;;;;;;;;;;;;;; if z_display_arr(0) ne '' then new_st.z_ext=z_display_arr(z_min_index) $ else new_st.z_ext=struct.z_ext if t_display_arr(0) ne '' then new_st.t_ext=t_display_arr(t_min_index) $ else new_st.t_ext = struct.t_ext if v_display_arr(0) ne '' then new_st.v_ext=v_display_arr(v_min_index) $ else new_st.v_ext=struct.v_ext if not keyword_set(silent) then print, 'Extraction completed' return, new_st stop : end