;+ ; ; @file_comments ; Like WHERE but works on structure tag names ; Obtain subscripts of elements in structure array for which ; a particular Tag has values in a range or matching specified values. ; Like the WHERE function but for use with structures ; ; @categories ; Structure ; ; @param STRUCT {in}{required} ; structure array to search. ; ; @keyword TAG_NAME ; Scalar string specifying Tag Name ; ; @keyword TAG_NUMBER ; Otherwise give the Tag Number, ; ; @keyword RANGE ; [min,max] range to search for in Struct ; ; @keyword VALUES ; One or array of numbers to match for in Struct, ; ; @keyword ISELECT ; Specifies indices to select only part of structure array, ; (use it to recycle subscripts from previous searches). ; ; @keyword NOPRINT ; Suppress informational messages about nothing found. ; ; @returns ; Nfound {out} ; # of occurrences found. ; ; @restrictions ; User *must* specify (1) TAG_NAME or TAG_NUMBER to search, and (2) ; the VALUES or RANGE to search on; ; ; @examples ; Suppose STR is a structure with tags CAT_NO:indgen(10), and ; NAME:strarr(10). Find the indices where STR.CAT_NO is ; between 3 and 5. ; ; IDL> print, WHERE_TAG( str, TAG_NAME = 'CAT_NO', VALUE = [3,4,5] ) ;or ; IDL> print, WHERE_TAG( str, TAG_NUM = 0, RANGE = [3,5]) ; ; @history ; written 1990 Frank Varosi STX @ NASA/GSFC ; Stop printing "Tag not found" with /NOPRINT, CD Pike 8-Jun-93 ; ; @version ; $Id$ ; ;- function where_tag, Struct, Nfound, TAG_NAME=Tag_Name, $ TAG_NUMBER=Tag_Num, $ ISELECT=ipart, NOPRINT=noprint, $ RANGE=range, VALUES=values ;First check required parameters... ; compile_opt idl2, strictarrsubs ; Ntag = N_tags( Struct ) if (Ntag LE 1) then begin message,"expecting a Structure Array, try again...",/CONTIN return,[-1] endif if (N_elements( Tag_Num ) NE 1) AND $ (N_elements( Tag_Name ) NE 1) then begin message,"specify TAG_NAME= or TAG_NUMBER= to search",/CONTIN return,[-1] endif Tags = Tag_names( Struct ) if N_elements( Tag_Name ) EQ 1 then begin Tag_Name = strupcase( Tag_Name ) Tag_Num = where( Tags EQ Tag_Name ) Tag_Num = Tag_Num[0] if (Tag_Num LT 0) then begin if NOT keyword_set( noprint ) then $ message,"Tag <"+Tag_Name+"> not found",/CONTIN return,[-2] endif endif if (Tag_Num LT 0) OR (Tag_Num GE Ntag) then begin message,"Tag# " + strtrim(Tag_Num,2) + " exceeds Max Tag# " $ + strtrim(Ntag-1,2) + " in structure",/CONTIN return,[-1] endif if N_elements( ipart ) GT 0 then begin ;check if any searching ;on a subset of input. w = where( ipart GE 0, nf ) if (nf LE 0) then return,[-1] if (nf LT N_elements( ipart )) then ipart = ipart[w] endif ;Now find out where for RANGE : if N_elements( range ) EQ 2 then begin if N_elements( ipart ) GT 0 then begin w = where( (Struct[ipart].(Tag_Num) GE range[0]) AND $ (Struct[ipart].(Tag_Num) LE range[1]), Nfound ) if (Nfound GT 0) then windex = ipart[w] else windex = w endif $ else windex = where( (Struct.(Tag_Num) GE range[0]) AND $ (Struct.(Tag_Num) LE range[1]), Nfound ) if (Nfound LE 0) AND (NOT keyword_set( noprint ) ) then begin strnums = strtrim( range, 2 ) string = strnums[0] + "," + strnums[1] message," NO values of <" + Tags[Tag_num] + $ "> found in the Range [" + string + "]",/CONTIN endif ;where Values: endif else if N_elements( values ) GE 1 then begin Nval = N_elements( values ) vals = [values] Nfound = 0 if N_elements( ipart ) GT 0 then begin for v=0,Nval-1 do begin w = where( Struct[ipart].(Tag_Num) EQ vals[v], Nf ) if (Nf GT 0) then begin if (Nfound GT 0) then ww = [ww,w] else ww = w endif Nfound = Nfound + Nf endfor if (Nfound GT 0) then windex = ipart[ww[sort( ww )]] $ else windex = w endif else begin for v=0,Nval-1 do begin w = where( Struct.(Tag_Num) EQ vals[v], Nf ) if (Nf GT 0) then begin if (Nfound GT 0) then ww = [ww,w] else ww = w endif Nfound = Nfound + Nf endfor if (Nfound GT 0) then windex = ww[sort( ww )] $ else windex = w endelse if (Nfound LE 0) AND (NOT keyword_set( noprint ) ) then begin strnums = strtrim( vals, 2 ) string = strnums[0] for i=1,Nval-1 do string = string + "," + strnums[i] message," NO values of <" + Tags[Tag_num] + $ "> found Equaling [" + string + "]",/CONTIN endif endif else begin message,"must specify a RANGE=[#,#] or VALUES=#('s)",/CONTIN windex=[-1] endelse return, windex end