14 DDREAD 0 LEGEND 4256 LEGENDTEST 11259 NBYTES 11728 NLINES 12224 PANELPLOT 12583 PPI 14019 READB 17581 REPLICAS 19179 SQUARE 20002 THECOLOR 21532 TYPEOF 24122 WEIBULL 24639 WRGB 26075 ;+ Name: ddread Purpose: This routine reads data in formatted (or unformatted) rows and columns. The name stands for Data Dump Read. By default, comments are skipped and the number of columns is sensed. Many options exist, e.g., selecting rows and columns, reading binary data, and selecting non-default data type and delimiters. Examples: junk = ddread(/help) ; get information only array = ddread(file) ; read ASCII data array = ddread(file,/formatted) ; ditto array = ddread(file,object=object) ; read binary data array = ddread(file,columns=[0,3]) ; get only 1st & 4th columns array = ddread(file,rows=lindgen(10)+10); get only 2nd 10 rows array = ddread(file,offset=10,last=19) ; get rows (10,19) array = ddread(file,/countall) ; count comment lines array = ddread(file,/verbose) ; echo comment lines array = ddread(file,type=1) ; return bytes, not floats or longs array = ddread(file,range=['start text','stop text']) ; text delimiters ; Place the detailed output from a Lowtran run in a 2-D array---wow! output = ddread('lowtran.out',range=['(CM-1) (MICRN)','0INTEGRATED ABSORPTION']) % DDREAD: Read 69 data lines selecting 14 of 14 columns; skipped 395 comment lines. Usage: array = ddread([file][,options][,/help]) Optional Inputs: file = file with data; if omitted, then call pickfile. Keywords: /formatted, /unformatted = flags to tell IDL whether data format is binary or ASCII. ddread tries to determine the type of data but it's not foolproof. object = a string containing the IDL declaration for one instance of the object in an unformatted file, e.g., 'fltarr(4)' or '{struct,dwell:0.,pitch:0.,yaw:0.,roll:0.}' rows = an array to select a subset of the rows in a formatted file Does not count comment lines, unless /countallrows is set! columns = likewise for columns type = data type of the output D=float (if '.' appears) or long delimiter = column separater, D=whitespace /help = flag to print header range = start and stop row or strings, e.g. range = ['substring in 1st line','substring in last line'] offset = start row (read to end of file, unless last set) last = stop row (read from start of file, unless offset set) /countallrows = flag to count comment rows as well as data rows (D=0) /verbose = flag to echo comments to screen Outputs: array = array of data from the lines (ASCII) or objects (binary) Common blocks: none Procedure: After deciding on ASCII or binary, read file and return array. Restrictions: - Comments can be either an entire line or else an end of a line, e.g., /* C comment. */ ; IDL comment Arbitrary text as a comment Comment in Fortran The next line establishes # of columns (4) & data type (float): 6. 7 8 9 This line and the next are both considered comments. 6 comment because only one of 4 columns appears 1 2 3 4 but this line has valid data and will be read as data - Even if a range of lines is selected with offset, range or last, all lines are read. This could be avoided. - Other routines needed: pickfile.pro - to choose file if none is given nlines.pro - to count lines in a file nbytes.pro - to count bytes in a variable replicas.pro - to replicate arrays (not scalars as in replicate.pro) typeof.pro - to obtain the type of a variable Modification history: write, 22-26 Feb 92, F.K.Knight (knight@ll.mit.edu) allow reading with arbitrary delimiter using reads, 23 Mar 92, FKK add countallrows keyword and modify loop to read as little data as possible, 20 May 92, FKK correct bug if /formatted set, 6 Jul 92, FKK add verbose keyword to print comments, 6 July 92, FKK correct bug if /rows=...,/countall set, 6 July 92, FKK & EJA add a guard against a blank line being converted to a number, 21 Aug 92, FKK allow parital line just before the EOF. Possibly this isn't the right thing to do, but I decided to allow it. If the final line is incomplete, the values are still read and the remainder of the line is filled with zeroes. 26 Oct 92, FKK allow range keyword to be a string array, 2 Dec 92, FKK make default for countallrows be true if range is present, 2 Dec 92, FKK add new function (typeof); called in a few places, 2 Dec 92, FKK ;- ;+ Name: legend Purpose: This procedure makes a legend for a plot. The legend can contain a mixture of symbols, linestyles, Hershey characters (vectorfont), and filled polygons (usersym). Examples: The call: legend,['Plus sign','Asterisk','Period'],psym=[1,2,3] produces: ----------------- | | | + Plus sign | | * Asterisk | | . Period | | | ----------------- Each symbol is drawn with a plots command, so they look OK. Other examples are given in usage and in optional output keywords. Usage: legend,items,linestyle=linestyle ; vertical legend at upper left legend,items,psym=psym ; ditto except using symbols legend,items,psym=psym,/horizontal ; horizontal format legend,items,psym=psym,box=0 ; sans border legend,items,psym=psym,delimiter='=' ; embed an '=' betw psym & text legend,items,psym=psym,margin=2 ; 2-character margin legend,items,psym=psym,position=pos ; position of legend legend,items,psym=psym,number=2 ; plot two symbols, not one legend,items,/fill,psym=[8,8,8],colors=[10,20,30]; 3 filled squares Inputs: items = text for the items in the legend, a string array. You can omit items if you don't want any text labels. For example, items = ['diamond','asterisk','square']. Optional Inputs: linestyle = array of linestyle numbers If linestyle(i) < 0, then omit ith symbol or line to allow a multi-line entry. psym = array of plot symbol numbers. If psym(i) is negative, then a line connects pts for ith item. If psym(i) = 8, then the procedure usersym is called with vertices define in the keyword usersym. N. B.: Choose either linestyle, psym, neither, or both. If neither is present, only the text is output. If both linestyle and psym parameters are present, they both have to have the same number of elements, and normal plot behaviour occurs. By default, if psym is positive, you get one point so there is no connecting line. vectorfont = vector-drawn characters for the sym/line column, e.g., ['!9B!3','!9C!3','!9D!3'] produces an open square, a checkmark, and a partial derivative, which might have accompanying items ['BOX','CHECK','PARTIAL DERIVATIVE']. If vectorfont(i) = '', then plots is called to make a symbol or a line, but if vectorfont(i) is a non-null string, then xyouts is called. There is no check that !p.font is set properly, e.g., -1 for X and 0 for PostScript. This can produce an error, e.g., use !20 with PostScript and !p.font=0, but allows use of Hershey *AND* PostScript fonts together. Optional Keywords: /help = flag to print header /horizontal = flag to make the legend horizontal /vertical = flag to make the legend vertical (D=vertical) box = flag to include/omit box around the legend (D=include) delimiter = embedded character(s) between symbol and text (D=none) colors = array of colors for plot symbols/lines (D=!color) textcolors = array of colors for text (D=!color) margin = margin around text measured in characters and lines spacing = line spacing (D=bit more than character height) pspacing = psym spacing (D=3 characters) charsize = just like !p.charsize for plot labels position = normalized coordinates of the upper left of the legend number = number of plot symbols to plot or length of line (D=1) usersym = 2-D array of vertices, cf. usersym in IDL manual. (D=square) /fill = flag to fill the usersym Outputs: legend to current plot device Optional Output Keywords: corners = 4-element array, like !p.position, of the normalized coords for the box (even if box=0): [llx,lly,urx,ury]. Useful for multi-column or multi-line legends, for example, to make a 2-column legend, you might do the following: c1_items = ['diamond','asterisk','square'] c1_psym = [4,2,6] c2_items = ['solid','dashed','dotted'] c2_line = [0,2,1] legend,c1_items,psym=c1_psym,corners=c1,box=0 legend,c2_items,line=c2_line,corners=c2,box=0,pos=[c1(2),c1(3)] c = [c1(0)c2(2),c1(3)>c2(3)] plots,[c(0),c(0),c(2),c(2),c(0)],[c(1),c(3),c(3),c(1),c(1)],/norm Useful also to place the legend. Here's an automatic way to place the legend in the lower right corner. The difficulty is that the legend's width is unknown until it is plotted. In this example, the legend is plotted twice: the first time in the upper left, the second time in the lower right. legend,['1','22','333','4444'],linestyle=indgen(4),corners=corners ; BOGUS LEGEND---FIRST TIME TO REPORT CORNERS xydims = [corners(2)-corners(0),corners(3)-corners(1)] ; SAVE WIDTH AND HEIGHT chdim=[!d.x_ch_size/float(!d.x_size),!d.y_ch_size/float(!d.y_size)] ; DIMENSIONS OF ONE CHARACTER IN NORMALIZED COORDS pos = [!x.window(1)-chdim(0)-xydims(0) $ ,!y.window(0)+chdim(1)+xydims(1)] ; CALCULATE POSITION FOR LOWER RIGHT plot,findgen(10) ; SIMPLE PLOT; YOU DO WHATEVER YOU WANT HERE. legend,['1','22','333','4444'],linestyle=indgen(4),pos=pos ; REDO THE LEGEND IN LOWER RIGHT CORNER You can modify the pos calculation to place the legend where you want. For example to place it in the upper right: pos = [!x.window(1)-chdim(0)-xydims(0),!y.window(1)-xydims(1)] Common blocks: none Procedure: If keyword help is set, call doc_library to print header. See notes in the code. Restrictions: Here are some things that aren't implemented. - It would be nice to allow data and device coords as well. - An orientation keyword would allow lines at angles in the legend. - An array of usersyms would be nice---simple change. - An order option to interchange symbols and text might be nice. - Somebody might like double boxes, e.g., with box = 2. - Another feature might be a continuous bar with ticks and text. - There are no guards to avoid writing outside the plot area. - There is no provision for multi-line text, e.g., '1st line!c2nd line' Sensing !c would be easy, but !c isn't implemented for PostScript. A better way might be to simply output the 2nd line as another item but without any accompanying symbol or linestyle. A flag to omit the symbol and linestyle is linestyle(i) = -1. - There is no ability to make a title line containing any of titles for the legend, for the symbols, or for the text. - It might be nice to force the legend to be placed at hardwired locations in the plot, e.g., with keywords like /left/bottom for lower left. Allowing this requires knowing the width of the text before it is printed, which is difficult. Side Effects: Modification history: write, 24-25 Aug 92, F K Knight (knight@ll.mit.edu) allow omission of items or omission of both psym and linestyle, add corners keyword to facilitate multi-column legends, improve place- ment of symbols and text, add guards for unequal size, 26 Aug 92, FKK add linestyle(i)=-1 to suppress a single symbol/line, 27 Aug 92, FKK add keyword vectorfont to allow characters in the sym/line column, 28 Aug 92, FKK ;- ;+ Name: legendtest Purpose: Test the legend procedure. Usage: .run legendtest Inputs: none Optional Inputs: none Keywords: none Outputs: legends of note Common blocks: none Procedure: Side Effects: Sets !20 font to symbol if PostScript and !p.font=0. Restrictions: With the vectorfont test, you'll get different results for PostScript depending on the value of !p.font. Modification history: write, 27 Aug 92, F.K.Knight (knight@ll.mit.edu) ;- ;+ Name: nbytes Purpose: Return the number of bytes in the variable Usage: nb = nbytes(variable) Inputs: variable = any IDL variable Optional Inputs or Keywords: help = flag to print header Outputs: nb = number of bytes in variable Common blocks: none Procedure: Idea from David Stern. Modification history: write, 22 Feb 92, F.K.Knight increase speed by writing to disk only for structures, 10 Sep 92, FKK eliminate Unix-specific file (from ali@rsinc.com), 11 Sep 92, FKK ;- ;+ Name: nlines Purpose: Return the number of lines in a file Usage: nl = nlines(file) Inputs: file = file to scan Optional Inputs or Keywords: help = flag to print header Outputs: nl = number of lines in the file. Common blocks: none Procedure: Assume ASCII data and read through file. Modification history: write, 24 Feb 92, F.K.Knight ;- ;+ Name: PANELPLOT Purpose: Plot many sets of variables on one common set of axes Usage: panelplot,xdata,ydata,/init,nplots=n,... ; make 1st plot panelplot,xdata,ydata,... ; make 2nd plot ... panelplot,xdata,ydata,... ; make nth plot Inputs: (the following inputs apply during initialization) init = flag to initialize for plots nplots = number of plots on the page (the following inputs apply to each individual plot) xdata = abscissa values ydata = ordinate values Optional Inputs: (the following inputs apply during initialization) charsize = value to override the default value: !p.charsize minx = minimum x value to plot maxx = maximum x value to plot xtitle = title of the x axis title = main plot title (the following inputs apply to each individual plot) ytitle = the y axis title rtitle = the plot title on right side of plot ltitle = the plot title on left side of plot yrange = array of y ranges for data Outputs: plot to current device of data Restrictions: To suppress tick labels, labels are set to blanks. However, there may be more ticks than blanks, producing unwanted labels. The plot area hardwired and will be incorrect for large charsizes. Modification history: modify multiplot, 12 Nov 91, FKK eliminate legend, fills with polyh, etc. 5 Jun 92, FKK change keyword mtitle to title, 25 Aug 92, FKK add ystyle and xstyle keywords, 2 Oct 92, FKK ;- ;+ Name: ppi Purpose: Make a ppi (plan position indicator) plot, named for the early CRT displays that presented radar data in polar coordinates. Plot is intensity versus range and azimuth. THere are two input forms: for regularly and irregularly gridded data. Examples: rcs = intarr(360,10) ; DUMMY DATA---SPIRAL RAMP for i=0,9 do $ rcs(*,i) = (indgen(360)+i*10) mod 360 azi = indgen(360) ; AZIMUTH BINS range = indgen(10)+1 ; RANGE BINS ppi,rcs,azi,range ; PPI PLOT: ; 1-deg BINS x 1-UNIT RANGE BINS ppi,rcs,azi,range,color=32 ; USE 32 COLORS, NOT 8 ppi,rcs,azi,range,grid=[12,5] ; ADD GRID AT 12 AZIMUTHS & 5 RANGES tc = bytarr(6) ; ARRAY FOR COLORS col = ['black','cyan','green','yellow','red','white'] for i = 0,5 do tc(i) = thecolor(col(i)) ppi,rcs,azi,range,color=tc ; USE AN ARRAY OF COLOR INDICES Usage: ppi,rcs,azimuth,range[,rangebin=rangebin,azimuthbin=azimuthbin][,option=opt] OR ppi,data[,rangebin=rangebin,azimuthbin=azimuthbin][,option=opt] Inputs: rcs = 2-D array of rcs data with dimensions nazim x nrange azimuth = 1-D vector of azimuth bins, length nazimuth, ,in degrees CW from North (up) range = 1-D vector of range bins, length nrange OR data = 2-D array of intensities at (r,theta) with dimensions 3 x npts where 1st dim contents ------- ----------------------------- 0 range to data point 1 azimuth of data point in degrees 2 intensity of data point and npts = number of points or sectors to plot Optional Keywords: rangebin = size of range bin in same units as range (D=range spacing) azimuthbin = size of azimuth bin in degrees (D=azimuth spacing) help = flag to print header rcsrange = data range spanned by colors (D=[min(data),max(data)]) colors = # of colors in plot (D=8) or array of color indices step = step in color table between colors. The default steps through the entire color table. (D=!d.n_colors/colors) title,xtitle,ytitle = titles like plot position = 4-element array for plot position in window---!d.position (D=largest square with margins) rangerange = plot limits (D=auto) grid = 1 or 2-element array to specify the number of azimuth and range grids, (D=none) Example: grid=[12,5] for azimuth every 30 degrees and range every 25% of range extent Outputs: polar plot to current device Common blocks: none Procedure: If keyword help is set, call doc_library to print header. Only points are plotted if bin parameters are omitted; otherwise, trapezoids are used to approximate sectors. For PostScript, the actual PostScript commands are written to the file; for other devices, polyfill is used. The reason is that polyfill doesn't use the PostScript fill operator. Instead polyfill uses vectors, which makes a gigantic file. I tried a few sets of PostScript commands, but I found that a single arcn did the trick. Previously, I tried the set <...setrgbcolor newpath...arcn...lineto...arc closepath fill> where the ellipsis means the parameters are omitted. Using only arcn with a linewidth equal to the rangebin yields a file about half the length. PostScript code is optimized to produce small PS file. A halftone screen could be used for color device and few colors. Restrictions: Only tested for Openwindows and PostScript, but should work for any device that allows polyfill. Modification history: write, 11-19 Jun 92, F.K.Knight (knight@ll.mit.edu) add optional azimuthal and range grids, 23 Jun 92, FKK add optional array of color indices, 15 Oct 92, FKK TBD, add an optional color bar ;- ;+ Name: readb Purpose: Procedure to copy the bits of an array to another IDL variable. Good for internal conversion, but limited in scope. A more general approach would allow other than array input. Examples: #1 a = replicate(byte('ff'x),4) ; MAKE A SOURCE ARRAY t = intarr(2) ; MAKE A DESTINATION ARRAY readb,a,t ; NEW ROUTINE print,t ; EQUIVALENT TO: t = fix(a,0,2) -1 -1 #2 print, 'test of nested structures' print, '=========================' st1 = {st1, aa:0L, bb:55.} a=bindgen(216) ; JUST ENOUGH BYTES! b={t1:0L, t2:0.0, t3:lonarr(5,5), t4:fltarr(5,5), t5:st1} readb, a, b Usage: readb,source,destination[,offset][,/help] Inputs: source = IDL source array, not a structure Optional Inputs: offset = offset of starting point measured in elements of source Offset is set if this is a recursive call. It might also be set if you want to start reading from the middle of the source array. Note that offset is just like offset in a = fix(source,offset). Keywords: help = flag to print header Outputs: destination = IDL destination variable, any type Common blocks: none Procedure: If keyword help is set, call doc_library to print header. The recursive portion is from Alan Youngblood (support@rsinc.com). For a structure, there is a loop through the tags and readb calls itself. For each tag, you reach a conversion line using one of byte(), fix(), long(), etc., after which offset is incremented by the length of the tag. Modification history: start with Alan's ideas, 8-10 Sep 92, FKKnight (knight@ll.mit.edu) ;- ;+ Name: replicas Purpose: Replicate an array, as replicate.pro does for scalars or structures. Replicas calls replicate if input is a scalar or structure. Usage: array = replicas(/help) copies = replicas(array,ncopies) Inputs: array = array to replicate ncopies = number of replicas Optional Inputs or Keywords: help = flag to print header Outputs: copies = an array of one dimension more than array and filled with copies of array Common blocks: none Procedure: If keyword help is set, call doc_library to print header. This routine could be incorporated into a more general replicate. However, the use of the parameter ncopies is not as general as in replicate. Modification history: write, 22 Feb 92, F.K.Knight guard against calling replicate with an array of structures, 18 Nov 92, FKK ;- ;+ Name: square Purpose: Make a square region for plotting with the current device. Usage: !p.position = square() ; PERMANENTLY SQUARE data = [0,1] plot,data,position=square() ; SQUARE ONLY FOR THIS PLOT plot,data,pos=square(/center) ; DITTO & CENTERED IN WINDOW !p.position = square(/top) ; AT TOP MARGIN OF WINDOW !p.position = square(/bottom) ; AT BOTTOM MARGIN OF WINDOW !p.position = square(/left) ; AT LEFT MARGIN OF WINDOW !p.position = square(/right) ; AT RIGHT MARGIN OF WINDOW !p.position = square(size=.5) ; HALF THE LARGEST SIZE POSSIBLE Optional Inputs: position = 4-element array specifying [xll,yll,xur,yur] device coords Optional Keywords: /help = flag to print header /left = flag to place square at left margin /center = flag to center the square in the plot window /right = flag to place square at right margin /top = like right only for vertical direction /bottom = like left only for vertical direction size = fraction of largest square possible Outputs: position = 4-element array giving [xll,yll,xur,yur] device coords Common blocks: none Procedure: If keyword help is set, call doc_library to print header. Restrictions: Side Effects: If position is omitted, then a plot is necessary and some plotting keywords will be altered, e.g., !x.range and !y.range. This is only a momentary change---until the next plot is done. Modification history: write, 7 Jul 92, F K Knight (knight@ll.mit.edu) add /top, /bottom, /left (D), /right, & /center keywords, 10 Jul 92, FKK ;- ;+ Name: thecolor Purpose: Function to rob a color index from the current color table and set it to the specified color. Then return the index. Options exist for where in the color table the index is chosen. Color names come from the Openwindows colors file, q.v. wrgb.pro. Usage: plot,x,color=thecolor('red') ; plot is red. plot,x,color=thecolor('LightGoldenrod3') ; case insensitive plot,x,color=thecolor('red',index=!d.n_color-1) ; the last index set to red plot,x,color=thecolor('red',/first) ; 1st available at the start of the color table (Default) plot,x,color=thecolor('red',/last) ; ditto except at the end of the color table tmp = thecolor(/reset) ; forget all previous thecolor calls Inputs: name = name of color, a string Optional Inputs: none Keywords: /help = flag to print header index = force the color index to be this value /last = choose index from first available at end of color table /first = choose the first available at the bottom. (D) rgb = output RGB values for the color /noindex = flag to simply return the rgb values, leaving the color table unchanged /reset = flag to kill all current reserved colors but doesn't restore the previous color table. Use loadct,n, tvlct,r,g,b or xloadct. /list = list the current colors and their indices /show = list all available colors /view = show swatches of all available colors; call wrgb widget Outputs: index = function return Optional outputs: none (cf. keyword rgb) Common blocks: thecolor, used to remember available names and info from previous calls, containing: thecolors = names of colors stored in previous calls to thecolor thecolorindices = corresponding color table indices (those replaced) thecolornames = list of available color names, read from file thecolorrgb = corresponding rgb triples previousfirstindex = previous index stored at start of color table previouslastindex = previous index stored at end of color table Procedure: If keyword help is set, call doc_library to print header. Restrictions: Needs a file where color names and RGB values are found. Two files are hardwired; at least one needs to be present. The widget xdisplayfile is called if /show is set. The widget wrgb is called if /view is set. Modification history: write, 29 Nov 91, F.K.Knight (knight@ll.mit.edu) add keyword noindex to simply return the rgb values and not alter the color table, 27 Apr 92, FKK add keyword reset, 30 Jun 92, FKK fix bug when /last occurs after /first, 30 Jun 92, FKK make a generic file the default, 6 Oct 92, FKK ;- ;+ Name: typeof Purpose: Function to return the type of the variable---a shorthand for extracting the type from the array returned by size. Usage: if typeof(variable) eq 7 then message,'Variable is a string.' Inputs: variable = any IDL variable Optional Inputs or Keywords: help = flag to print header Outputs: typeof = type code from the size array Common blocks: none Procedure: Just get the type code from the size array. Modification history: write, 2 Dec 92, F.K.Knight (knight@ll.mit.edu) ;- ;+ Name: weibull Purpose: Function to return the value of the Weibull pdf. Example: beta = 1. ; SHAPE PARAMETER ; =1==> exponential distribution ; >1==> wear-out type shapes whereby f(T) is zero at ; T=gamma, increases as T-->T~, and then decays to 0. ; =2==> Rayleigh distribution gamma = 0. ; LOCATION PARAMETER ; locates the distribution along the abscissa eta = 1. ; SCALE PARAMETER ; reciprocal of useful life T = findgen(100)/10. print,weibull(T,beta,gamma,eta) Usage: pdf = weibull(T[,beta][,gamma][,eta][,/help][,/reliability][,/failurerate]) Inputs: T = abscissa coordinate, scalar or array Optional Inputs: beta = shape parameter, > 0 (D=1==> exponential distribution) eta = scale parameter, > 0 (D=1) gamma = location parameter (D=0) Keywords: help = flag to print header /reliability = return only the exponential portion: R = exp(-((T-gamma)/eta)^beta) R has a value of 1 from 0<=T<=gamma and decreases for T>gamma to zero. /failurerate = return only the failure rate portion: lambda = (beta/eta)*((T-gamma)/eta)^(beta-1) lambda is infinity for 0 wrgb ; starts widget Modification history: convert xrgb to widget-based wrgb, 30Sep91, FKK fix bugs, e.g. cursor,x,y,2 didn't return on cursor motion, 7Oct91, FKK save existing color table at start and reset it at end, 29Jan92, FKK add help button, 29 Jul 92, FKK use a generic file rather then $OPENWINHOME/lib/rgb.txt, 6 Oct 92, FKK ;-