
; This pro uses IDL widgets to display .FTS images and allow user to
; interactively plot profiles.

; October 1997
; Ed Esfandiari - first version.
;
; 11/20/97 aee  - added "Save Profile", and "Ring" options.
; 11/21/97 aee  - added "Draw Box & Sum Intensities" and "Apply C3 Vignetting"
;                 options plus switch between original and calibrated images.
; 12/08/97 aee  - added slider widgets for controling y-range of the plot.
; 02/06/98 aee  - added zoom (instead of slider) and "mark plot peaks" options.
; 03/05/98 aee  - added "Box Width" and "ByteSCale" options.
; 07/27/98 aee  - added option to print a snapshot of the currently displayed 
;                 image as a part of printing the profile plot. 
; 12/17/98 aee  - added Shane Stezelberger's FWHM feature to the code.
;



Function get_profile,image,xp1,yp1,xp2,yp2,xx,yy,xstart=x0,ystart=y0,nomark=nomark
;
; PURPOSE:
;	Extract a profile from an image. Based on IDL's profile.pro
;
; OUTPUTS:
;	PROFILE returns a floating-point vector containing the values of
;	the image along the profile line marked by the user.
;
; OPTIONAL OUTPUTS:
;	XX:	After picking the end points, XX contains the X coordinates
;		of the points along the selected profile.
;
;	YY:	After picking the end points, YY contains the Y coordinates
;		of the points along the selected profile.
;
; @(#)image_profiles.pro	1.4 11/24/97 :LASCO IDL LIBRARY
;
on_error,2                      ;Return to caller if an error occurs
s=size(image)
sx = s(1) & sy=s(2)
if n_elements(x0) le 0 then x0 = 0
if n_elements(y0) le 0 then y0 = 0
xx= xp1 
yy= yp1
xx1= xp2
yy1= yp2
 
	y = yy - y0
	x = xx - x0
	if !order ne 0 then y = sy - 1 - y ;Invert?
	if (x lt 0) or (x ge sx) or (y lt 0) or (y ge sy) then begin
        	message, 'Point outside image', /CONTINUE
               res=widget_message('Point outside image')
               return,-999 
	endif

	y1 = yy1 - y0
	x1 = xx1 - x0
	if !order ne 0 then y1 = sy - 1 - y1 ;Invert?
	if (x1 lt 0) or (x1 ge sx) or (y1 lt 0) or (y1 ge sy) then begin
		message, 'Point outside image.', /CONTINUE
               res=widget_message('Point outside image')
               return,-999
	endif
;	print,'To (',x1,',',y1,')'
	if not keyword_set(nomark) then $
		plots,[xx,xx1],[yy,yy1],/dev,/noclip ;Draw the line
;
dx = float(x1-x)		;delta x
dy = float(y1-y)
n = abs(dx) > abs(dy)
if (n eq 0) then begin 
  message, 'Zero length line.', /CONTINUE
  res=widget_message('Zero length line')
  return,-999
end
;
r = fltarr(n+1)
;
if abs(dx) gt abs(dy) then begin
	if x1 ge x then s=1 else s=-1
	sy = (y1-y)/abs(dx)
   endif else begin
	if y1 ge y then sy=1 else sy=-1
	s = (x1-x)/abs(dy)
   endelse
;
xx = indgen(n+1l)*s+x		;X values, make into longwords.
yy = indgen(n+1l)*sy+y		;Y values
line_prof= image(long(yy)*sx + xx)
;srt= sort(xx)
;xx= xx(srt)
;yy= yy(srt)
;line_prof= line_prof(srt)
return,line_prof
end




pro get_ring,image,rad,xcenter,ycenter,value,xrad,yrad,angle
  newrad=rad
  pi=2*asin(1.)
  angle=indgen(360)
  rangle=(-angle*pi)/180.
  xrad=xcenter+newrad*sin(rangle)
  yrad=ycenter+newrad*cos(rangle)
  value=image(xrad,yrad)
  for i=1,359 do npf= get_profile(image,xrad(i-1),yrad(i-1), $
                                  xrad(i),yrad(i),nxx,nyy)
;  npf= get_profile(image,xrad(359),yrad(359),xrad(0),yrad(0),nxx,nyy)
  return
end




pro get_pts,x,y,x1,y1,p,x2,y2,ops_x2,ops_y2

; Feb 27 98 - Ed Esfandiari
; Given line (x,y) to (x1,y1) and distance, p, between (x1,y1) and (x2,y2) which
; is also perpendicular to line (x,y),(x1,y1) and goes through (x1,y1), find
; the coordinates of (x2,y2) and also coordinate on the opposite side (the same
; distance, P, way).
;

  x2= x1 - p*sin(atan((y1-y)/(x1-x)))
  y2= y1 + p*cos(atan((y1-y)/(x1-x)))

  ops_x2= x1 + p*sin(atan((y1-y)/(x1-x)))
  ops_y2= y1 - p*cos(atan((y1-y)/(x1-x)))

;  print,'x2,y2= ',x2,y2
;  print,'ops= ',ops_x2,ops_y2

  return
end


;+ get_pt function from width library.
; NAME:
;
;       GET_PT
;       
; PURPOSE:
; 
;        Digitize a point on a previously plotted curve, and return
;        the corresponding array element.
;
; CALLING SEQUENCE:
; 
;        Result = GET_PT(XAXIS,YAXIS,XPOINT,YPOINT)
;        
; INPUTS:
; 
;        XAXIS - the x axis vector which was used to make the plot.
;        
;        YAXIS - the y axis vector which was used to make the plot.
;		
; KEYWORD PARAMETERS:
; 
;        NOHIGHLIGHT - set to inhibit putting a red mark on the curve
;                      at the digitized point.
;			
;        MESSAGE - a string to print as the message to the user.
;                  Default = 'Digitize a point: '
;			
;        NOINIT - set to inhibit placing the cursor in the center of
;                 the plot window.
;		    
; OUTPUTS:
; 
;        Result - The array subscript of the digitized point.
;
; OPTIONAL OUTPUT PARAMETERS:
; 
;        XPOINT, YPOINT - the digitized points.
;
; SIDE EFFECTS:
; 
;        A mark is drawn on the plot at the digitized point.
;
; PROCEDURE:
;
;        The user is asked to digitize a point on the curve using the
;        mouse.  The VALUE_TO_INDEX function is used to find the
;        closest array element.
;		
; MODIFICATION HISTORY:
; 
;        D. L. Windt, Bell Laboratories, November 1989
;        Feb. 1991, Removed call to TEK_COLOR
;        Mar. 1997, replaced index search code with call to
;        VALUE_TO_INDEX function.
;
;        windt@bell-labs.com
;-
function get_pt,xaxis,yaxis,xpoint,ypoint,nohighlight=nohighlight, $
            message=message,noinit=noinit
on_error,2

if keyword_set(message) then print,message else print,'Digitize a point: '

if keyword_set(noinit) eq 0 then tvcrs,.5,.5,/norm ; move cursor to window.
cursor,xpt,ypt,/data            ; digitize the point.
index=value_to_index(xaxis,xpt) ; find the index
xpoint=xaxis(index)             ; get the x and y values of the point.
ypoint=yaxis(index)

if keyword_set(nohighlight) eq 0 then $
  plots,[xpoint,xpoint],[ypoint,ypoint],psym=2,symsize=.5,color=2

return,index
end


function use_box_avg,img,bsize,xx,yy,pf

  ;x_vect= indgen(n_elements(xx)) 
  ;wset,prof_win
  ;plot,x_vect,pf
  ;wait,5

  tot_pt= n_elements(xx)
  get_pts,xx(tot_pt-1),yy(tot_pt-1),xx(0),yy(0),bsize/2,nx2,ny2,onx2,ony2
  ppf= get_profile(img,nx2,ny2,onx2,ony2,nxx,nyy)
  ;help,ppf
  pf(0)= total(ppf)/n_elements(ppf)
  for ct=1,tot_pt-1 do begin
    get_pts,xx(0),yy(0),xx(ct),yy(ct),bsize/2,nx2,ny2,onx2,ony2
    ppf= get_profile(img,nx2,ny2,onx2,ony2,nxx,nyy)
    pf(ct)= total(ppf)/n_elements(ppf)
  end

  ;oplot,x_vect,pf
  ;wait,10
  ;stop 

  return,pf
end




FUNCTION c3_vig,img,header
; This function calibrates a C3 image to mean solar brightness units.
; The calibrated image is returned.  The units are mean solar 
; brightness.
;
; RESTRICTIONS:
;	Only handles clear polarizer except for H-alpha
;
; PROCEDURE:
;	The routine reads in the vignetting and a mask array from the
;	NRL_LIB/lasco/data/calib directory.  To obtain the calibration
;	factors, it calls the C3_CALFACTOR procedure.
;
hdr = header
IF (DATATYPE(hdr) NE 'STC')  THEN hdr=LASCO_FITSHDR2STRUCT(hdr)
IF (hdr.detector NE 'C3')  THEN BEGIN
   txt= widget_message('Sorry, Wrong telescope: '+hdr.detector,title='Warning')
   RETURN,0
END

   sd = getenv ('NRL_LIB')+'/lasco/data/calib/'
   vig_fn= get_cal_name(sd+'C3_cl*vig*.dat',strmid(hdr.fileorig,0,6))
   if(vig_fn ne '') then begin 
     vig = fltarr(1024,1024)
     mask = vig
     OPENR,lucal,vig_fn,/GET_LUN
     READU,lucal,vig
     CLOSE,lucal
     FREE_LUN,lucal
   endif else begin
     txt= widget_message('Sorry, No '+sd+'C3_cl*vig*.dat file',title='Warning')
     return,0
   endelse 
   msk_fn= get_cal_name(sd+'C3_cl*msk*.dat',strmid(hdr.fileorig,0,6))
   if(msk_fn ne '') then begin
     OPENR,lucal,msk_fn,/GET_LUN
     READU,lucal,mask
     CLOSE,lucal
     FREE_LUN,lucal
   endif else begin
     txt= widget_message('Sorry, No '+sd+'C3_cl*msk*.dat file',title='Warning')
     return,0
   endelse
   vig_full = vig*mask
;
;  c3_cal_factor returns a factor in units of MSB/(DN/pixel-sec)
;  divide the factor by the image exposure time here, and not later
;
valid= GET_EXP_FACTOR(hdr,expfac,bias)
hdr.EXPTIME= hdr.EXPTIME*expfac
;calfac = c3_calfactor(header)
calfac = c3_calfactor(hdr) ;use "hdr" so that "original "header" is not changed.
factor = calfac/hdr.EXPTIME
IF (hdr.r1col EQ 20) AND (hdr.r1row EQ 1) AND $
   (hdr.r2col EQ 1043) AND (hdr.r2row EQ 1024)  $
THEN vig = vig_full*factor ELSE BEGIN
   x1=hdr.r1col-20
   x2=hdr.r2col-20
   y1=hdr.r1row-1
   y2=hdr.r2row-1
   vig = vig_full(x1:x2,y1:y2)*factor
ENDELSE
summing = (hdr.sumcol>1)*(hdr.sumrow>1)
IF (summing NE 1)  THEN FOR i=1,summing,4 DO vig=IMG_SUM_2X2(vig)
summing = (hdr.lebxsum)*(hdr.lebysum)
IF (summing NE 1)  THEN FOR i=1,summing,4 DO vig=IMG_SUM_2X2(vig)
RETURN,(img-bias)*vig
END



pro get_opposite_pt,xc,yc,xr,yr,xp,yp,xn,yn

; Given a point (xp,yp) and radial line between (xc,yc) and (xr,yr), calculates 
; and returns the coordinates of the opposite point (xn,yn) so that line (xp,yp)
; and (xn,yn) is perpendicular to the radial line and both ends are at equal
; distance from the radial line.

  cr= sqrt((xr-xc)^2 + (yr-yc)^2)
  cp= sqrt((xp-xc)^2 + (yp-yc)^2)

; Calculate angle between each of two lines and the positive x-axis, counter 
; clockwise, and then subtract them to get the angle between the two lines: 

  t1= atan(yr-yc,xr-xc)
  t2= atan(yp-yc,xp-xc)
  ang= abs(t2 - t1)
  cn= cp*cos(ang)

  xn= (cn*xr-cn*xc+cr*xc)/cr   ; x coord of itersection with the radial line
  yn= (cn*yr-cn*yc+cr*yc)/cr   ; y coord of itersection with the radial line

; now get the coordinates at the opposite side:

  xn= xn-(xp-xn)
  yn= yn-(yp-yn)

  return
end



function snorth_ang,ang,dx,dy
  ; change the input angle to redflect the angle from the solar north counter
  ; clockwise:

  if(dx gt 0.0 and dy gt 0.0) then ang= ang+270.0 ; 1st quadrant
  if(dx lt 0.0 and dy gt 0.0) then ang= ang+90.0  ; 2nd
  if(dx lt 0.0 and dy lt 0.0) then ang= ang+90.0  ; 3rd
  if(dx gt 0.0 and dy lt 0.0) then ang= ang+270.0 ; 4th
  return,ang
end


PRO ZOOM_PLOT
  common shared,selected_img,fname,save,save_req,img,prof_win,img_win,prof_opt,$
              prof_types,erase_plot,xcent,ycent,plot_types,cent_id,ymin,ymax, $
              axis_types,scale_types,plt_opt,axs_opt,scl_opt,sc_xcent,sc_ycent,$
              motion_id,arcs,solr,xylab,p2p_pts,xp1,yp1,udef,beg_pt,end_pt,$
              cxc,cyc,cxr,cyr,radial_select,xout,pf,xx,yy,dd,asc_unit,asc_name,$
              x_arr,y_arr,plot_cnt,plot_info,imsize,last_press,img_name,mt,$
              rad,radx,rady,draw_box,sum_box,header,orig_img,cal_img,dimg_id
  common mshared,fwhm_keyword,date,time,filename,R1_ang,angle,camera,$
              boundary,x_subarray,xpeak,ypeak,halfmax,halfmax_array,edge
  common yvals,yr1,yr2,x_vect,zx1,zx2,zy1,zy2,zpt,zoom,ptmsg,org_pf,org_xar,$
               bsize,bmin,bmax,bscl,bw 

  beg= 0 & fin= 0

  if(zx1 ge 60 and zx1 le 430) then $
    beg= fix(n_elements(pf)*(zx1-60.0)/370.0)
  if(zx2  ge 60 and zx2 le 430) then $
    fin= fix(n_elements(pf)*(zx2-60.0)/370.0)
  if(beg lt 0) then beg= 0
  if(fin ge n_elements(pf)) then fin= n_elements(pf)-1

  if(beg lt fin) then begin
    plot_cnt= 1 ; remove old plot, if any.
    x_vect= x_vect(beg:fin)
    pf= pf(beg:fin)  
    x_arr= x_vect
    y_arr= pf
    plot_info(plot_cnt).plt= "oplot,x_vect,pf" ;need oplot (have plot_info(0))
    plot_info(plot_cnt).beg= 0 
    plot_info(plot_cnt).fin= n_elements(pf)-1
    plot_info(plot_cnt).msg=''
    plot_info(plot_cnt).save_txt=''

    wset,prof_win
    !x.style= 1
    !y.style= 1
    if(plt_opt eq 'Linear Plot' )then $
      plot,x_vect(plot_info(1).beg:plot_info(1).fin),pf(plot_info(1).beg:plot_info(1).fin) $
    else $ ; log plot
      plot_io,x_vect(plot_info(1).beg:plot_info(1).fin),pf(plot_info(1).beg:plot_info(1).fin)
    wset,img_win
  end

  return
END



PRO IMG_SELECT_EVENT, event
common shared,selected_img,fname,save,save_req,img,prof_win,img_win,prof_opt,$
              prof_types,erase_plot,xcent,ycent,plot_types,cent_id,ymin,ymax, $
              axis_types,scale_types,plt_opt,axs_opt,scl_opt,sc_xcent,sc_ycent,$
              motion_id,arcs,solr,xylab,p2p_pts,xp1,yp1,udef,beg_pt,end_pt,$
              cxc,cyc,cxr,cyr,radial_select,xout,pf,xx,yy,dd,asc_unit,asc_name,$
              x_arr,y_arr,plot_cnt,plot_info,imsize,last_press,img_name,mt,$
              rad,radx,rady,draw_box,sum_box,header,orig_img,cal_img,dimg_id
  common mshared,fwhm_keyword,date,time,filename,R1_ang,angle,camera,$
              boundary,x_subarray,xpeak,ypeak,halfmax,halfmax_array,edge
  common yvals,yr1,yr2,x_vect,zx1,zx2,zy1,zy2,zpt,zoom,ptmsg,org_pf,org_xar,$
               bsize,bmin,bmax,bscl,bw 

  common widget_common,save_id, save_wid
 
WIDGET_CONTROL, event.id, GET_UVALUE=uval
WIDGET_CONTROL, event.top, GET_UVALUE=struct   ; get structure from UVALUE


help_info=[$
   ' This utility lets user to interactively select a line, curve, or ring',$
   'from the image and plot its profile. The profile can be plotted using',$
   'either the "Index", "Distance" (actual distance in terms of number of',$
   'pixels or solar radii between the two ends), "X-component", or "Y-',$
   'component" in units of "Solar Radii" or "Pixels" versus the intensity.',$
   'The displayed plot can be manipulated using the "ZOOM" and "ORIG-PLOT"',$
   'icons. Intensity peaks at various regions of the plot can be marked using',$
   'the "Mark Plot Peaks" icon.',$
   'In addition, the user can run a crude "full width half maximum" analysis',$
   'on a profile feature. The feature''s width data is plotted on screen and',$
   'optionally saved to an ASCII file. To use it, create a profile with a',$
   'strong feature. Select "FWHM" under the profile window, and click on the',$
   'peak of this feature. The procedure will plot the half-maximum line for',$
   'you -- click on it twice, once on either side of the selected feature.',$
   'Then select "SAVE FWHM" to save it.']
   help_info=[help_info,$
   '',$
   ' This program also provides the option of drawing a box and summing the',$
   'intensities within the box using the "DrawBox/SumIntens" button.',$
   '',$
   ' Another feature that can be used for Point to Point, Cross Section, Radial',$
   '(sun-center), and Radial (user-defined) options is to specify a width so',$
   'that instead of a flat line (width=1, default), a box of that width is',$
   'used to plot a profile. In this case the pixels within that width are',$
   'averaged and plotted. Use the "Box Width" icon to change the width.',$
   '',$
   ' In addition, it allows for in-memory vignetting calibration of the input',$
   'image (currently, only C3 telescope) using the "Apply C3 Vignetting" icon.',$
   ' User can flip back and forth between the original and the calibrated',$
   'image, if any, using "Use Calibrated Image" and "Use Original Image"',$
   'icons. Both images may be used to create profiles or sum intensites.',$
   '',$
   ' XLOADCT can be used to select color tables and adjust contrast and gamma.',$
   'User can also select his/her own byte scale minimum and maximum limits',$
   'using the "ByteScale" icon. To redisplay the image using the new limits,',$
   'simply click on the "Refresh Image" icon. The default limit is image''s',$
   'minimum and maximum values.',$
   '',$
   ' To select a point on the image, click using any of the mouse buttons.',$
   'Set the "overplot Profiles", for plotting on top of the previous plots.',$
   'Following options are provided for selecting a line, curve, or ring:',$
   '',$
   'Point to Point: Select two points on the image. A line is drawn between',$
   '                them and its profile is plotted. The radial distance (in',$
   '                solar radii) and radial angle with respect to the solar',$
   '                north for both ends of the line are also displayed on the',$
   '                plot.',$
   '',$
   'Trace:          To trace an event, click along the boundry at desired',$
   '                intervals. At least two clicks/points are required (for a',$
   '                straight line). Indicate the end of your points selection',$
   '                by pressing the "Mark End of Trace" button. A surface/contour',$
   '                plot of the selected shape is then displayed followed by',$
   '                an optional 2D profile plot. For the profile plot, the',$
   '                radial distance (in solar radii) and radial angle with',$
   '                respect to the solar north for both ends of the traced',$
   '                shape are also displayed.',$
   '',$   
   'Ring:           Select a point to mark the radius of the ring centered at',$
   '                the sun-center. The ring is then drawn on the image and',$
   '                its profile is plotted. Ring''s radius in terms of solar',$
   '                radii is also displayed on the plot.',$
   '',$
   'Cross Section:  Select a point to mark the radial line from that point to',$
   '                the sun-center. Then select a point at either side of the',$
   '                radial line. A line is drawn from this point perpendicular',$
   '                to the radial line ending at the same distance on the',$
   '                other side and its profile is plotted. As long as this',$
   '                option is on and/or "Refresh Image" is not used, one can',$
   '                use the current radial line to repeatedly select other',$
   '                lines and plot/overplot their profiles. The radial angle',$
   '                of the radial line with respect to the solar north and also',$
   '                the radial distance (in solar radii) of each profile''s',$
   '                intersection point with the radial line are also displayed',$
   '                on the plot.',$ 
   '',$
   'Radial (sun-center): select a point on the image. A radial line from it',$
   '                to the sun-center is drawn and its profile is plotted.',$
   '                As long as this option is on, one can repeatedly select',$
   '                other points to draw more radial lines to the sun-center',$
   '                and plot/overplot their profiles. The radial distance (in',$
   '                solar radii) and radial angle with respect to the solar',$
   '                north for both ends of the line are also displayed on the',$
   '                plot.',$
   '',$
   'Radial (user-defined): First select a point to be used as the center.',$
   '                Then select another point. A radial line from this point',$
   '                to the center is drawn and then plotted. As long as this',$
   '                option is on, one can repeatedly select other points to',$
   '                draw more radial lines to the same center and plot/overplot',$
   '                their profiles. The radial distance (in solar radii) and',$
   '                radial angle with respect to the solar north for both ends',$
   '                of the line are also displayed on the plot.',$
;   '',$
   '']
   help_info=[help_info,$
   '  When switching between profile options, first make sure to toggle off the',$
   '"Overplot profiles" option, if on, to get rid of the plots from previous',$
   'options.',$
   '',$ 
   '  To print the plot(s) shown in the plot window, choose a printer and',$
   'click on the "Print Profile" button. Default printer is hp4-247. You',$
   'will be asked if a current snapshot of the displayed image should also',$
   'be printed.',$
   '',$
   '  To save profile values that are plotted, in an ascii text file, choose',$
   'a filename and click on the "Save Profile" button. If file already',$
   'exists, data is appended to it; Otherwise, it is created. Default file',$
   'name is XXXXXXXX.txt where Xs are the first eight characters of the image',$
   'name.',$
   '',$
   ' For comments and suggestions, please contact Ed Esfandiari at NRL:',$
   'esfandiari@susim.nrl.navy.mil or (202) 404-8941.']

; initialize the full-width keyword flag

fwhm_keyword=0

select_info=[$
   ' No selection.']

;print,'uval= ',uval
 case (uval) of
  'Done': begin ; exit the program but delete the plot file first, if any.
                  if(last_press eq 'prn') then wait,3
                  openw,unit,'img_profile.ps',/get_lun,/delete
                  close,unit
                  free_lun,unit
             WIDGET_CONTROL, /DESTROY, struct.base
          end
  'Help': begin
             last_press= 'help'
;             save_req= 0 ;if this event selected, ignore the savescreen req.
             xdisplayfile,TITLE='Help',$
             GROUP=event.top, HEIGHT=15, WIDTH=75, $
             TEXT= help_info
          end 
  'xld':   begin
             last_press= 'xld'
             xloadct
           end
  'scle':  begin
             last_press='scle'
             WIDGET_CONTROL, event.id ,GET_VALUE=bmx
             bmin= float(strtrim(strmid(bmx(0),0,strpos(bmx(0),',')),2))
             bmax= float(strtrim(strmid(bmx(0),strpos(bmx(0),',')+1, 20),2))
           end
  'oplot': begin
             last_press='oplot'
             if(erase_plot eq 'false') then $
                erase_plot='true' $ 
             else $
                erase_plot='false'
           end
  'ymin':  begin
;             help,/st,event
             ymin= event.value
           end
  'ymax':  begin
;             help,/st,event
             ymax= event.value
           end
  'xzm':   begin
        IF (plot_cnt eq 0 ) THEN BEGIN
          WIDGET_CONTROL,ptmsg,SET_VALUE='No plot to zoom on!'
        ENDIF ELSE BEGIN
          zoom= 'xzoom'
          msg='Select a new X-AXIS range by clicking on two points on the plot.'
          WIDGET_CONTROL,ptmsg,SET_VALUE= msg
        ENDELSE
  end
  'orp':   begin
        IF (plot_cnt eq 0 ) THEN BEGIN
          WIDGET_CONTROL,ptmsg,SET_VALUE='No previous plot!'
        ENDIF ELSE BEGIN
             x_vect= org_xar
             pf= org_pf
             zx1= 60   ; so that ind= 0 is calculated
             zx2= 430  ; so that ind= n_elements(pf)-1 is calculated
             zoom_plot
;             wset,prof_win
;             if(plt_opt eq 'Linear Plot' )then $ 
;               plot,x_vect,pf $
;             else $ ; log plot
;               plot_io,x_vect,pf
;             wset,img_win
        ENDELSE
  end
  'new_y': begin
;             help,/st,event
             if(plot_cnt gt 1) then begin ;oplot option is set, remove old plots
               plot_info(1).plt= "oplot,x_vect,pf"
               x_arr= x_vect & y_arr= pf
               plot_info(1).beg=0
               plot_info(1).fin= n_elements(pf)-1
               plot_info(1).msg=''
               plot_info(1).save_txt=''
               plot_cnt= 1
             end
             wset,prof_win
             !ymin=ymin
             !ymax=ymax
             j= plot_cnt
             if(plt_opt eq 'Linear Plot' )then $ 
               plot,x_arr(plot_info(j).beg:plot_info(j).fin),pf $
             else $ ; log plot
               plot_io,x_arr(plot_info(j).beg:plot_info(j).fin),pf
             wset,img_win
           end
  'ref':   begin
             wset,img_win
;             tvscl,img
             tv,bytscl(img,bmin,bmax)
             radial_select= 1 ; force using new radial axis for cross-section.
             widget_control,end_pt,set_value= ' ' 
             widget_control,end_pt,set_value= ' ' 
           end
  'cimg':  begin
             last_press='cimg'
             calsize= size(cal_img)
             if(calsize(0) eq 0) then begin
               msg='Calibrated Image Not Available. Apply Vignetting First.'
               txt= widget_message(msg,title='Warning')
               return
             end
             img= cal_img
;             tvscl,img
             bmin= abs(min(img)) & bmax= abs(max(img))
             tv,bytscl(img,bmin,bmax)
             widget_control,dimg_id,set_value= '> Calibrated Image'
             bmx= string(abs(min(img)),'(i5)')+","+string(max(img),'(i7)')
             widget_control,bscl,set_value= bmx
           end
  'oimg':  begin
             last_press='oimg'
             img= orig_img
;             tvscl,img
             bmin= abs(min(img)) & bmax= abs(max(img))
             tv,bytscl(img,bmin,bmax)
             widget_control,dimg_id,set_value= '>  Original Image'
             bmx= string(abs(min(img)),'(i5)')+","+string(max(img),'(i7)')
             widget_control,bscl,set_value= bmx
           end
  'dimg':  begin
             last_press='dimg'
           end
  'c3vig': begin
              last_press='c3_vig'
              if(fix(strmid(header.filename,1,1)) gt 2) then begin
                msg='This image is already calibrated. Calibrate again?'
                res=widget_message(msg,/question,title="Warning")
                if(res ne "Yes") then return 
              end
              widget_control,/hour
              cal_img= c3_vig(orig_img,header)
              print,'c3_vig done.'
            end
  'mkpk' :   begin
        IF (plot_cnt eq 0 ) THEN BEGIN
          WIDGET_CONTROL,ptmsg,SET_VALUE='Must have a plot to mark the peak!'
          return
        ENDIF
               wset,prof_win
               msg='select a region by clicking on two points on the plot.'
               WIDGET_CONTROL,ptmsg,SET_VALUE= msg
               if(zoom eq 'false') then begin
                 peak= get_peak(org_xar,org_pf,/NOHIGHLIGHT,/PRINT)
                 xyouts,org_xar(peak),org_pf(peak),strtrim(string(org_pf(peak)),2)
               endif else begin
                 peak= get_peak(x_vect,pf,/NOHIGHLIGHT,/PRINT)
                 xyouts,x_vect(peak),pf(peak),strtrim(string(pf(peak)),2)
               end
               WIDGET_CONTROL,ptmsg,SET_VALUE= ' '
             end
  'mkend':   begin
             last_press= 'mkend'
             if(prof_opt eq 'Trace') then begin
               p2p_pts= 0
;               srt= sort(xx)
;               xx= xx(srt)
;               yy= yy(srt)
;               pf= pf(srt)
               xx1= float(xx)
               yy1= float(yy)
               xa= imsize(1)
               ya= imsize(2)
;               lab= 'Surface Plot (Pixels)'
;               if(scl_opt eq "Solar Radii" or scl_opt eq "Intensity) then begin
                 xx1= xx1*(arcs/solr)
                 yy1= yy1*(arcs/solr)
                 xa= xa*(arcs/solr)
                 ya= ya*(arcs/solr)
                 lab= 'Surface Plot (Solar Radii)'
;               end
               imarr= fltarr(xa,ya)
               imarr(xx1,yy1)= pf 
               wset,prof_win
               !x.title='' & !y.title=''
               !z.title='Intensity'
               surface,imarr,/save,charsize=2,/dev
               xyouts,200,7,lab,/dev
               contour,imarr,/noerase,/t3d,zvalue=1.0,charsize=2,/dev 
               res=widget_message('Plot a Profile'+'"?', $
                                  /question,title="Question")
               if(res eq "Yes") then begin
                 if(erase_plot eq 'false') then begin 
                   txt= '"Overplot" is on. Press "OK", toggle off "Overplot",'
                   txt= txt+' and press "Mark End of Trace".'
                   res=widget_message(txt,title='Information')
                   return
                 end
                 goto, show_plot
               end
             end
           end
  'popt':  begin
             last_press= 'popt'
             widget_control,beg_pt,set_value= ''
             widget_control,end_pt,set_value= ''
             prof_opt= prof_types(event.index) 
             case (prof_opt) of
               'Cross Section': begin
                  radial_select= 1
                  xcent= sc_xcent
                  ycent= sc_ycent
                  xycent= strtrim(string(xcent),2)+','+strtrim(string(ycent),2)
                  widget_control,cent_id,set_value= xycent
                  widget_control,end_pt,set_value= '('+xycent+')'
                  widget_control,beg_pt,set_value= ''
                end
               'Radial (sun center)': begin
                  prof_opt= 'Radial'
                  xcent= sc_xcent 
                  ycent= sc_ycent
                  xycent= strtrim(string(xcent),2)+','+strtrim(string(ycent),2)
                  widget_control,cent_id,set_value= xycent
                  widget_control,end_pt,set_value= '('+xycent+')'
                  widget_control,beg_pt,set_value= ''
                end
               'Radial (user defined)': begin
                  udef= 1 
                  res=widget_message('Click on the image to mark a new center.',/information)
                end
               'Ring': begin
                 bsize= 1
                 widget_control,bw,set_value= bsize 
                 xycent= strtrim(string(xcent),2)+','+strtrim(string(ycent),2)
                 widget_control,cent_id,set_value= xycent 
                 res=widget_message('Click on the image to mark the radius.',$
                                    /information)
               end
               'Trace': begin
                  bsize= 1
                  widget_control,bw,set_value= bsize 
                  widget_control,cent_id,set_value= 'Not Applicable'
                  res=widget_message('Click on the image at least twice to trace an event. When done, click on "Mark End of Trace" icon to make a plot.',/information) 
               end
               else : widget_control,cent_id,set_value= 'Not Applicable'
             endcase
           end
  'cxy':   begin
             last_press='cxy'
           end
  'mtd':   begin
             last_press='mtd'
           end
  'bpt':   begin
             last_press='bpt'
           end
  'ept':   begin
             last_press='ept'
           end
  'ptype': begin
             last_press='ptype'
             new_plt= plot_types(event.index)
             if(plt_opt ne new_plt and erase_plot eq 'false') then $
               res=widget_message('You may want to toggle off the "Overplot Profile" option.') 
             plt_opt= new_plt 
           end
  'Xaxis': begin
             last_press='xaxis'
;             new_axs= axis_types(event.index)

             pu= axis_types(event.index)
             new_axs= strtrim(strmid(pu,0,strpos(pu,'(')),2)
             scl_opt= strmid(pu,strpos(pu,'(')+1,strpos(pu,')'))
             scl_opt= strmid(scl_opt,0,strlen(scl_opt)-1)  
             
             if(axs_opt ne new_axs and erase_plot eq 'false') then $
               res=widget_message('You may want to toggle off the "Overplot Profile" option.')
             axs_opt= new_axs 
           end

   'max': begin

; perform "full width half maximum" analysis
; check for plot existence
 	IF (plot_cnt eq 0 ) THEN BEGIN
          WIDGET_CONTROL,ptmsg,SET_VALUE='Must have a plot to measure feature widths!'
          return
        ENDIF

; The CME profiles can be messy, and peak values can be spoofed by cosmic ray
; strikes and the like.  Here, the user must manually select the "peak value"
; of the desired feature:

	msg='Click on the peak value of the feature'
	WIDGET_CONTROL,ptmsg,SET_VALUE= msg
	wset,prof_win

; Read the peak position

	cursor,xpeak,ypeak,/data
	print,'Peak intensity is '+strtrim(ypeak,2)+' at '+strtrim(xpeak,2)+' solar radii'
	print

; Add an asterisk at the peak of the existing plot
 
	plots,[xpeak,xpeak],[ypeak,ypeak],psym=7,symsize=0.95

; Calculate the half-maximum value and plot it
	
	halfmax = (ypeak/2.)
	halfmax_array=FltArr(N_Elements(x_vect))
	halfmax_array=halfmax_array+halfmax
	oplot, x_vect,halfmax_array,LineStyle=2

; This dotted line at the half-maximum point may intersect more than
; one feature, so the user must manually select the desired feature.
; Clicking to the left and right of the desired feature will narrow
; the neighborhood.  The order of selection does not matter.

	msg = 'Click on the boundaries of this feature'
	WIDGET_CONTROL,ptmsg,SET_VALUE = msg

; Set up REPEAT...UNTIL loop to catch bad feature-boundary values

	REPEAT begin

	wait,0.3   ; Prevent the cursor-read values from piling up 

	cursor,xlimit1,ylimit1,/data  ; read the first boundary value
	plots,[xlimit1,xlimit1],[ylimit1,ylimit1],psym=7,symsize=0.95
;	print, xlimit1
	
	wait,0.2
	cursor,xlimit2,ylimit2,/data  ; read the second boundary value
	plots,[xlimit2,xlimit2],[ylimit2,ylimit2],psym=7,symsize=0.95
;	print,xlimit2

; Invert the boundary values, if necessary

	if (xlimit2 lt xlimit1) then begin
		temp=xlimit1
		xlimit1=xlimit2
		xlimit2=temp
	endif
; Check boundary values for proper positions

	if (xlimit1 gt xpeak AND xlimit2 gt xpeak) then begin
		print,'Try again: click the FWHM button'
		return
	endif

	if (xlimit1 lt xpeak AND xlimit2 lt xpeak) then begin
		print,'Try again: click the FWHM button'
		return
	endif
		
; Extract the feature's profile from the existing arrays

	first_index=value_to_index(x_vect,xlimit1)
	second_index=value_to_index(x_vect,xlimit2)
	x_subarray=x_vect(first_index:second_index)
	pf_subarray=pf(first_index:second_index)

; Search the feature data for half-maximum crossing points.  The
; following algorithm steps through the profile data, checking for 
; points where the profile crosses the half-maximum value.  At
; these values, the next-lowest profile value is recorded in the
; array "edge."
; At locations where the pf array falls below the half-maximum value
; at only one point, only one crossing point will be recorded.

	c=0
	marker=1
	edge=0

;print,n_elements(edge)
;help,n_elements(edge)
;check=fix(n_elements(edge))
;help,check
;help,edge
	while (c lt n_elements(pf_subarray)) do begin
	    if (marker mod 2) then begin
		if (pf_subarray(c) gt halfmax) then begin

; Check for possible duplicate values at "valley" points
                   while (edge(fix(n_elements(edge)-1)) ne (c-1)) do begin
			edge=[edge,c-1]
			marker=marker+1
		   endwhile
		endif	    
	    endif else begin 	
		if (pf_subarray(c) lt halfmax) then begin
			edge=[edge,c]
			marker=marker+1
		endif
	    endelse

            c=c+1
	endwhile

; Check for valid boundary values.  If there are NO crossing points in the 
; resulting array, the user must re-select two new boundary points.  However,
; this code WILL allow both boundary points to lie on the same side of the
; peak value (with as little as one crossing point).

		if (n_elements(edge) le 1) then begin
			msg = 'OOPS! Click just outside the event boundaries again.'
			WIDGET_CONTROL,ptmsg,SET_VALUE = msg
		endif

	ENDREP UNTIL (n_elements(edge) gt 1)

; strip out the first integer "0" from the EDGE array

	  edge=edge(1:n_elements(edge)-1)

; Plot the boundaries on the existing profile (with approximately dotted vertical lines)
	c=0
	while (c lt n_elements(edge)) do begin
		boundary=FltArr(N_Elements(x_vect))
		boundary=boundary+x_subarray(edge(c))
		oplot,boundary,pf,LineStyle=2
		c=c+1
	endwhile
	msg = ''
	WIDGET_CONTROL,ptmsg,SET_VALUE = msg
	return
end

  'sav':   begin

; Save the profile width measurements to a ASCII file

	IF (n_elements(edge) le 1) THEN BEGIN
          WIDGET_CONTROL,ptmsg,SET_VALUE='Please measure a feature width first!'
          return

        ENDIF
; Extract date-and-time information from the 'mt' structure
	position=strpos(mt,',')
	filename=strmid(mt,position+2,12)
	date=strmid(mt,position+16,10)
	time=strmid(mt,position+27,8)
	camera = 'c'+strmid(filename,0,1)
				
; Assemble a title for the save file
 		title=camera+'_'+strmid(date,0,4)                    
		title=title+strmid(date,5,2)               
		title=title+strmid(date,8,2)
; Add the position angle of the profile.  A radial profile is assumed, so
; R1_ang = R2_ang.		
		angle=strtrim(string(fix(R1_ang)),2)
		title=title+'_PA'+angle+'.txt'
; Build a text widget to select/modify the save file name
	save_wid=widget_base(/col)
	save_lab=widget_label(save_wid,value='Save/Append the current profile width data?')
	save_id=WIDGET_TEXT(save_wid,VALUE=title,UVALUE='save_id',/EDITABLE)
	save_yes=widget_button(save_wid,value="Yes",uvalue='save_yes')
	save_no=widget_button(save_wid,value="Cancel",uvalue='save_no')
	widget_control,save_wid,/realize
	xmanager,'save_file',save_wid,event_handler='IMG_SELECT_EVENT'
XMANAGER, 'IMG_SELECT', base, EVENT_HANDLER='IMG_SELECT_EVENT'
	widget_control,save_wid,/destroy
    end
   'save_yes':  begin
; Retrieve the save filename from the appropriate text widget
	widget_control,save_id,get_value=title
	title=title(0)
; Check for existing filenames
  	ff= findfile(title)
	res=0
; If filename is unique, give it a header
	if (strlen(ff(0)) eq 0) then begin
		openw,save_lun,title,/get_lun,/append
		printf,	save_lun, date
		header = "CAM FILENAME    TIME    ANGLE   PEAK_RADIUS   EDGE_RADII"
		printf, save_lun, header 
		close, save_lun & FREE_LUN, save_lun 
	endif
; If filename already exists, prompt the user to append data to it
        if (strlen(ff(0)) gt 0) then begin ; file already exists
           	res=widget_message('Append to the existing file: "'+title+'"?',/question, $
                                     title="Existing File") 
                if(res eq "No") then begin
			msg = "Profile width data not saved"
		   	WIDGET_CONTROL,ptmsg,SET_VALUE = msg
			widget_control,save_wid,/destroy
			return
		endif
	endif

; Open the outputfile
		openw, save_lun,title,/get_lun,/append
	
; Data for the save file will be added to a long text string, called "string."
; The first column will define the camera (C2 or C3).

		string=camera+" "+filename+" "+time+" "		
		string=string+" "+angle+" "+strtrim(xpeak,2)+" "
; Add all edge/boundary positions to the text string
		
		c=0
		while (c lt n_elements(edge)) do begin
			string=string+strtrim(x_subarray(edge(c)),2)+" "
			c=c+1
		endwhile
		printf,save_lun,string
		close, save_lun & FREE_LUN, save_lun
         
	widget_control,save_wid,/destroy
   end

   'save_no':  begin

; Kill the text widget and return to the main program
	widget_control,save_wid,/destroy
	return
   end

  'iwin':  begin
;             print,'Image: event type, x, y= ',event.type,event.x,event.y
             if(event.type eq 2) then begin ; cursor motion
               txt= 'x: '+strtrim(string(event.x),2)+'  '+ $
                    'y: '+strtrim(string(event.y),2) 
               widget_control,motion_id,set_value= txt 
             end
             wset,img_win
             if(event.type eq 0 and strmid(draw_box,0,4) eq 'true') then begin
;             NOTE: draw_box section MUST be the first section of this code.
              if(draw_box eq 'true') then begin ; first coordinates
               widget_control,sum_box,set_value=' '
               xp1= event.x & yp1= event.y
               xyouts,event.x,event.y,'.',/dev
               widget_control,beg_pt,set_value='('+strtrim(string(xp1),2)+$
                                             ' , '+strtrim(string(yp1),2)+')'
               widget_control,end_pt,set_value=' '
               draw_box= 'true_true'
              endif else begin ; 2nd coordinates
               xp2= event.x & yp2= event.y
;               xyouts,event.x,event.y,'.',/dev
               widget_control,end_pt,set_value='('+strtrim(string(xp2),2)+$
                                             ' , '+strtrim(string(yp2),2)+')'
               ptf= get_profile(img,xp1,yp1,xp2,yp1,xxx,yyy)
               ptf= get_profile(img,xp2,yp1,xp2,yp2,xxx,yyy)
               ptf= get_profile(img,xp2,yp2,xp1,yp2,xxx,yyy)
               ptf= get_profile(img,xp1,yp2,xp1,yp1,xxx,yyy)
               ptf= 0.0D
               if(yp2 lt yp1) then begin
                 yt1= yp1 & xt1= xp1
                 yp1= yp2 & xp1= xp2
                 yp2= yt1 & xp2= xt1 
               end
               for i= yp1,yp2 do $ 
                 ptf= ptf+total(get_profile(img,xp1,i,xp2,i,xxx,yyy,nomark='y'))
               draw_box= 'false'
               widget_control,sum_box,set_value= string(ptf) 
              endelse
              return
             end
             if(event.type eq 0 and prof_opt eq "Point to Point") then begin
              p2p_pts= p2p_pts+1
              if(p2p_pts eq 1) then begin
                xp1= event.x 
                yp1= event.y
                xyouts,event.x,event.y,'.',/dev
                widget_control,beg_pt,set_value='('+strtrim(string(event.x),2)+$
                   ' , '+strtrim(string(event.y),2)+')'
                widget_control,end_pt,set_value=''
;                print,'from:', event.x,event.y
                return
              end
              if(p2p_pts eq 2) then begin
                xyouts,event.x,event.y,'.',/dev
                widget_control,end_pt,set_value='('+strtrim(string(event.x),2)+$
                   ' , '+strtrim(string(event.y),2)+')'
;                print,'to:  ', event.x,event.y
                p2p_pts= 0
                pf= get_profile(img,xp1,yp1,event.x,event.y,xx,yy)
                if(pf(0) eq -999) then return ; invalid point 
              end 
              if(bsize gt 1) then pf= use_box_avg(img,bsize,xx,yy,pf)
             end
             if(event.type eq 0 and prof_opt eq "Trace") then begin
              p2p_pts= p2p_pts+1
              if(p2p_pts eq 1) then begin
                xp1= event.x 
                yp1= event.y
                xyouts,event.x,event.y,'.',/dev
                widget_control,beg_pt,set_value='('+strtrim(string(event.x),2)+$
                   ' , '+strtrim(string(event.y),2)+')'
                widget_control,end_pt,set_value=''
;                print,'from:', event.x,event.y
                return
              end
              if(p2p_pts gt 1) then begin
                xyouts,event.x,event.y,'.',/dev
                widget_control,end_pt,set_value='('+strtrim(string(event.x),2)+$
                   ' , '+strtrim(string(event.y),2)+')'
                npf= get_profile(img,xp1,yp1,event.x,event.y,nxx,nyy)
                if(npf(0) ne -999) then begin
                  if(p2p_pts eq 2) then begin
                    pf= npf & xx= nxx & yy= nyy
                  endif else begin ; greater than 2
                    pf= [pf,npf] & xx= [xx,nxx] & yy= [yy,nyy] 
                  endelse
                  xp1= event.x & yp1= event.y
                endif else p2p_pts= p2p_pts -1 ; invalid point, ignore it.
                return
              end 
             end
             if(event.type eq 0 and prof_opt eq "Ring") then begin
               p2p_pts= 0
               widget_control,beg_pt,set_value='('+strtrim(string(event.x),2)+$
                    ' , '+strtrim(string(event.y),2)+')'
               
               rad= sqrt((event.x-xcent)^2+(event.y-ycent)^2)
               radx= event.x & rady= event.y
               okarr= [imsize(1)-xcent-1,imsize(2)-ycent-1,xcent,ycent]
               if(rad gt min(okarr)) then begin
                 res=widget_message('Radius too big.',title='Warning')
                 return 
               end 
               get_ring,img,rad,xcent,ycent,pf,xx,yy,pts
             end
             if(event.type eq 0 and prof_opt eq "Radial") then begin 
               p2p_pts= 0
               widget_control,beg_pt,set_value='('+strtrim(string(event.x),2)+$
                    ' , '+strtrim(string(event.y),2)+')'
               pf= get_profile(img,xcent,ycent,event.x,event.y,xx,yy)
               if(pf(0) eq -999) then return ; invalid point 
               if(bsize gt 1) then pf= use_box_avg(img,bsize,xx,yy,pf)
             end
             if(event.type eq 0 and prof_opt eq "Radial (user defined)") then begin
               p2p_pts= 0
               if(udef eq 1) then begin ; get the center
                 udef= 0
                 xcent= event.x
                 ycent= event.y
                 xyouts,xcent,ycent,'.',/dev
                 xycent= strtrim(string(xcent),2)+' , '+strtrim(string(ycent),2)
                 widget_control,cent_id,set_value= xycent
                 widget_control,end_pt,set_value= '('+xycent+')'
                 widget_control,beg_pt,set_value= ''
                 return
               end
               widget_control,beg_pt,set_value='('+strtrim(string(event.x),2)+$
                    ' , '+strtrim(string(event.y),2)+')'
               pf= get_profile(img,xcent,ycent,event.x,event.y,xx,yy)
               if(pf(0) eq -999) then return ; invalid point 
               if(bsize gt 1) then pf= use_box_avg(img,bsize,xx,yy,pf)
             end
             if(event.type eq 0 and prof_opt eq "Cross Section") then begin
               if(radial_select eq 1) then begin
                radial_select= 0
                p2p_pts= 0
                widget_control,beg_pt,set_value='('+strtrim(string(event.x),2)+$
                     ' , '+strtrim(string(event.y),2)+')'
                cxc= float(xcent) & cyc= float(ycent)
                cxr= float(event.x) & cyr= float(event.y)
                pf= get_profile(img,xcent,ycent,event.x,event.y,xx,yy)
                return
               end
               widget_control,beg_pt,set_value='('+strtrim(string(event.x),2)+$
                    ' , '+strtrim(string(event.y),2)+')'
               widget_control,end_pt,set_value=''
               get_opposite_pt,cxc,cyc,cxr,cyr,float(event.x),float(event.y),xn,yn 
               pf= get_profile(img,event.x,event.y,xn,yn,xx,yy)
               widget_control,end_pt,set_value='('+strtrim(string(xn),2)+$
                    ' , '+strtrim(string(yn),2)+')'
               if(pf(0) eq -999) then return ; invalid point 
               if(bsize gt 1) then pf= use_box_avg(img,bsize,xx,yy,pf)
             end

             if(event.type eq 0 and prof_opt ne "None") then begin
show_plot:
               !p.psym=0
;show_plot:
               x_scale= " (Pixels)" ; scale of plot is in Pixels at this point.
               case (axs_opt) of
                 "Index": begin
                                x_title= "Index"
                                x_vect= indgen(n_elements(xx)) 
                                x_scale= " (Intensity)"
                              end
                 "X Component" : begin 
                                     if(prof_opt eq 'Cross Section') then begin
                                      txt='Can''t use "X Component" with '
                                      txt=txt+'"Cross Section". Use "Distance"'
                                      txt=txt+' or "Index".'
                                      ans= widget_message(txt)
                                      return
                                     end
                                     x_title= "X Component"
                                     x_vect= xx ; pixels. relative to pixel=0,0
                                     if(scl_opt eq "Solar Radii") then begin 
                                       dd= float(xx)-sc_xcent ;rel. to suncenter
                                       x_vect= dd*(arcs/solr) 
                                       x_scale= " (Solar Radii)"
                                     end
                                    end
                 "Y Component" : begin 
                                     if(prof_opt eq 'Cross Section') then begin
                                      txt='Can''t use "Y Component" with '
                                      txt=txt+'"Cross Section". Use "Distance"'
                                      txt=txt+' or "Index".'
                                      ans= widget_message(txt)
                                      return
                                     end
                                     x_title= "Y Component"
                                     x_vect= yy ; pixels. relative to pixel=0,0
                                     if(scl_opt eq "Solar Radii") then begin
                                       dd= float(yy)-sc_ycent ;rel. to suncenter
                                       x_vect= dd*(arcs/solr)
                                       x_scale= " (Solar Radii)"
                                     end
                                    end
                 "Distance"   : begin
                                     x_title= "Distance"
                                     xx= float(xx)
                                     yy= float(yy)
                                     mx= where(xx eq min(xx))
                                     mx= mx(0)
;                                     dd= sqrt((xx-xx(0))^2+(yy-yy(0))^2)
                                     dd= sqrt((xx-xx(mx))^2+(yy-yy(mx))^2)
                                     if(prof_opt eq 'Cross Section') then begin
                                       x_title= 'Cross-Section '+x_title 
                                       len= n_elements(dd)-1
                                       dd= dd - dd(fix(len/2.0))
                                     end
                                     x_vect= dd ; pixels
                                     if(scl_opt eq "Solar Radii") then begin
                                       x_scale= " (Solar Radii)"
                                       x_vect= dd*(arcs/solr)
                                     end
                                    end
               endcase
;              Now plot/oplot the profile:
               wset,prof_win 
;               widget_control,yr1,set_value= 0 
;               widget_control,yr2,set_value= 0 
               !ymin=0 & !ymax=0
org_pf= pf
org_xar= x_vect
zoom= 'false'
               if(erase_plot eq 'true' or plot_cnt eq 0) then begin
                 !x.style=1
                 !y.style=1
!xmin=0 & !xmax=0
!ymin=0 & !ymax=0
                 !y.title= "Intensity"
                 !x.title= x_title+x_scale
                 mt=prof_opt+' profile, '+ $
                    strmid(img_name,9,strlen(img_name)-15)+')'
                 !mtitle= mt
                 if(plt_opt eq 'Linear Plot' )then begin 
                   plot,x_vect,[min(pf),max(pf)],/nodat,title=mt 
                   plot_info(0).plt= "plot,x_vect,[min(pf),max(pf)],/nodat,title=mt"
                 endif else begin  ; log plot
                   min_pf= min(pf)
                   nz= where(pf gt 0.0D,cnt)
                   if(cnt gt 0) then min_pf= min(pf(nz)) 
                   plot_io,x_vect,[min_pf,max(pf)],/nodat,title=mt
                   plot_info(0).plt= "plot_io,x_vect,[min_pf,max(pf)],/nodat,title=mt"
                 endelse
                 plot_info(0).beg=-1 & plot_info(0).fin=-1 
                 plot_info(0).msg=''
                 plot_info(0).save_txt=''
;                 plots,x_vect,pf
;                 plot_info(1).plt= "plots,x_vect,pf"
                 oplot,x_vect,pf
                 plot_info(1).plt= "oplot,x_vect,pf"
                 x_arr= x_vect & y_arr= pf
                 plot_info(1).beg=0
                 plot_info(1).fin= n_elements(pf)-1
                 plot_info(1).msg=''
                 plot_info(1).save_txt=''
                 plot_cnt= 1
               endif else begin  ; keep old plot(s), use oplot
                 oplot,x_vect,pf
                 x_arr= [x_arr,x_vect] & y_arr= [y_arr,pf]
                 plot_cnt= plot_cnt+1
                 plot_info(plot_cnt).plt= "oplot,x_vect,pf"
                 plot_info(plot_cnt).beg= plot_info(plot_cnt-1).fin+1
                 plot_info(plot_cnt).fin= plot_info(plot_cnt-1).fin+n_elements(pf)
                 if(prof_opt ne 'Cross Section') then begin 
                   xyouts,90,215,xylab,/dev,col=0 ;remove old label
                   plot_info(plot_cnt-1).msg=''
                 end
               endelse
               if(prof_opt eq 'Cross Section') then begin
                 npt= n_elements(x_vect)
                 mid_x= (xx(0)+xx(npt-1))/2.0
                 mid_y= (yy(0)+yy(npt-1))/2.0
                 mid_R= sqrt((mid_x-sc_xcent)^2+(mid_y-sc_ycent)^2)*(arcs/solr)
                 dy=mid_y-sc_ycent & dx= mid_x-sc_xcent
                 R_ang= atan(dy/dx)*(180.0/3.14159)
                 ; adujst R_ang counter clockwise from solar north: 
                 R_ang= snorth_ang(R_ang,dx,dy)
                 if(plot_cnt eq 1) then begin 
                   xyouts,315,217,'Radial angle= '+string(R_ang,'(f5.1)'),/dev
                   str="xyouts,315,217,'Radial angle= "+string(R_ang,'(f5.1)')+$
                       "',/dev"
                   plot_info(0).msg= str
                   plot_info(0).save_txt='Radial angle= '+string(R_ang,'(f5.1)')
                 end
                 mx_ind= where(pf eq max(pf))
                 xout= x_vect(mx_ind(0))
                 lab= string(mid_R,'(f5.2)')+'R' 
                 min_pf= 0.0
                 xyouts,xout,pf(mx_ind),lab
                 str="xyouts,"+string(xout)+","+string(max(pf))+",'"+lab+"'"
                 plot_info(plot_cnt).msg= str
                 plot_info(plot_cnt).save_txt="Profile's mid point: "+lab
               endif else begin
                if(prof_opt eq 'Ring') then begin
                 npt= n_elements(x_vect)
                 mid_x= radx
                 mid_y= rady
                 mid_R= rad*(arcs/solr)
                 dy=mid_y-sc_ycent & dx= mid_x-sc_xcent
                 R_ang= atan(dy/dx)*(180.0/3.14159)
                 ; adujst R_ang counter clockwise from solar north: 
                 R_ang= snorth_ang(R_ang,dx,dy)
                 mx_ind= where(pf eq max(pf))
                 xout= x_vect(mx_ind(0))
                 min_pf= 0.0
                 xylab= "Ring's Radius: "+string(mid_R,'(f5.2)')+'R'
                 xyouts,90,215,xylab,/dev
                 str="xyouts,90,215,'"+xylab+"',/dev"
                 str='xyouts,90,215,"'+xylab+'",/dev'
                 plot_info(plot_cnt).msg= str
                 plot_info(plot_cnt).save_txt=xylab
                endif else begin
                 lpt= n_elements(x_vect)-1
                 dy=yy(0)-sc_ycent & dx= xx(0)-sc_xcent
                 if(dy eq 0 and dy eq 0) then begin 
                   R1= 0     ; radial line
                   R1_ang= 0
                 endif else begin 
                   R1= sqrt((xx(0)-sc_xcent)^2+(yy(0)-sc_ycent)^2)*(arcs/solr)
                   R1_ang=atan(dy/dx)*(180.0/3.14159)
                 end
                 ; adujst t1 angles counter clockwise from solar north: 
                 R1_ang= snorth_ang(R1_ang,dx,dy)
                 R2= sqrt((xx(lpt)-sc_xcent)^2+(yy(lpt)-sc_ycent)^2)*(arcs/solr)
                 dy=yy(lpt)-sc_ycent & dx= xx(lpt)-sc_xcent
                 R2_ang=atan(dy/dx)*(180.0/3.14159)
                 R2_ang= snorth_ang(R2_ang,dx,dy) 
                 if(R1 lt 0.00001) then R1_ang= R2_ang ; if radial one of these
                 if(R2 lt 0.00001) then R2_ang= R1_ang ; two is true.
                 xylab='('+string(R1,'(f5.2)')+','+string(R1_ang,'(f5.1)')+ $
                   ') , (' +string(R2,'(f5.2)')+','+string(R2_ang,'(f5.1)')+')'
                 xyouts,90,215,xylab,/dev
                 str="xyouts,90,215,'"+xylab+"',/dev"
                 plot_info(plot_cnt).msg= str
                 ttxt= "Profile's end points: "
                 plot_info(plot_cnt).save_txt= ttxt+xylab
                endelse
               endelse
;               event.type= 0
             end
           end
  'pwin':  begin
;             print,'Plot: event type, x, y= ',event.type,event.x,event.y
;             if(event.type eq 2) then print,'x, y motion= ',event.type,event.x,event.y
        if(event.type eq 1 and zoom eq 'xzoom') then begin
          if(event.type eq 1) then print,'x, y = ',event.x,event.y
          if(event.x lt 60 or event.x gt 430) then begin
            WIDGET_CONTROL,ptmsg,SET_VALUE= 'Point out of bounds, try again.'
            return
          end
          wset,prof_win
          if(zpt eq 1) then begin
            zpt= 2
            zx1= event.x
            xyouts,event.x,event.y,'X',/dev
            msg='First point is selected. Now select the second point.'
            WIDGET_CONTROL,ptmsg,SET_VALUE= msg
          endif else begin ; zpt = 2
            zpt=1
            zx2= event.x
            xyouts,event.x,event.y,'X',/dev
            WIDGET_CONTROL,ptmsg,SET_VALUE='Plotting the selected region....'
            if(zx2 lt zx1) then begin
              tmp= zx1 & zx1=zx2 & zx2= tmp
            end
            zoom= 'done'
            zoom_plot
            WIDGET_CONTROL,ptmsg,SET_VALUE= ' ' 
          endelse
          wset,img_win
        end

  end
  'boxw':  begin
             last_press='boxw'
             WIDGET_CONTROL, event.id ,GET_VALUE=bsize
             bsize= fix(bsize(0))
           end
  'pnm':   begin
             last_press='pnm'
             WIDGET_CONTROL, event.id ,GET_VALUE=fname
           end
  'prn': begin
              save_req= event.select
              if(event.select eq 1) then begin
                if(plot_cnt eq 0) then begin
                  res=widget_message('No profile to print.',title="Warning")
                  return
                end
                res=widget_message('Print to "'+fname+'"?',/question, $
                                   title="Printer")
                if(res eq "Yes") then begin
                  last_press= 'prn'
                  msge='Print a snapshot of the displayed image, too?'
                  res1=widget_message(msge,/question)
                  if(res1 eq "Yes") then begin
                    wset,img_win
                    pimg= tvrd()
                    sz=size(pimg)
;                    wset,prof_win
                    ; create a invisible window and add image plus plot info:
                    window,2,xsize=sz(1),ysize=sz(2),/pixmap 
                    msg=''
                    for i=0,plot_cnt do begin
                      if(strpos(plot_info(i).msg,'/dev') gt 0) then $
                        msg= plot_info(i).msg  ; keep the last xyouts with /dev
                    end
                    if(msg ne '')then begin
                      msg= strmid(msg,strpos(msg,',')+1,200)
                      msg= strmid(msg,strpos(msg,',')+1,200)
                      msg= strmid(msg,strpos(msg,',')+1,200)
                      ; now "xyouts,xpos,ypos," is removed.
                    end
                    tvscl,pimg  ; place the image in the invisible window.
	
                    ; add the plot info on the image:
                    xyouts,5,sz(2)-10,mt,/dev
                    xyouts,5,5,strmid(msg,1,strpos(msg,',/dev')-2),/dev 

                    pimg= tvrd() ; now capture the new image+info in pimg. 

                    wset,img_win
                  endif        


                  print,'printing to '+fname
                  set_plot,'ps'
                  device,file='img_profile.ps'
                  device,/landscape

                  if(res1 eq "Yes") then tvscl,pimg  ; include image for print

                  x_vect=x_arr(plot_info(1).beg:plot_info(1).fin)
                  pf=y_arr(plot_info(1).beg:plot_info(1).fin)
                  res=execute(plot_info(0).plt)
                  if(plot_info(0).msg ne '') then res=execute(plot_info(0).msg)

                  for i=1,plot_cnt do begin
                    x_vect=x_arr(plot_info(i).beg:plot_info(i).fin)
                    pf=y_arr(plot_info(i).beg:plot_info(i).fin)


                    res=execute(plot_info(i).plt)
                    if(plot_info(i).msg ne '')then res=execute(plot_info(i).msg)
    	     	        c=0

			while (fwhm_keyword eq 1) do begin
	                  while (c lt n_elements(edge)) do begin

		            boundary=FltArr(N_Elements(x_vect))
		            boundary=boundary+x_subarray(edge(c))
				
			    output = 'oplot,boundary,pf,LineStyle=1'
			    res=execute(output)
	
		            c=c+1
	                  endwhile
		
			output = 'plots,[xpeak,xpeak],[ypeak,ypeak],psym=2,symsize=0.95'
			res=execute(output)
	
				halfmax_array=FltArr(N_Elements(x_vect))
				halfmax_array=halfmax_array+halfmax
			
			output = 'oplot, x_vect,halfmax_array,LineStyle=2'
			res=execute(output)
			endwhile
                  end

                  device,/close_file
                  set_plot,'x'

                 spawn,'lp -o nobanner -d '+fname+' img_profile.ps',/sh
                end
              end
           end
  'nasc':  begin
             last_press='nasc'
             WIDGET_CONTROL, event.id ,GET_VALUE=asc_name
             asc_name= asc_name(0)
           end
  'sumi': begin
             last_press='sumi'
          end
  'dbox': begin
             last_press='dbox'
            res=widget_message('Select lower left and upper right corners.',$
                               title='Information')
            draw_box= 'true'
          end
  'asc': begin
              if(event.select eq 1) then begin
                last_press= 'asc'
                if(plot_cnt eq 0) then begin
                  res=widget_message('No profile to Save.',title='Warning')
                  return
                end
                ff= findfile(asc_name)
                if(strlen(ff(0)) gt 0) then begin ; file already exists
                  res=widget_message('Append to "'+asc_name+'"?',/question, $
                                     title="Existing File") 
                  apnd= 1
                endif else begin 
                  res=widget_message('Save data in "'+asc_name+'"?',/question, $
                                     title="New File")
                  apnd= 0 
                endelse
                if(res eq "Yes") then begin
                  openw,asc_unit,asc_name,/get_lun,/append 
                  if(apnd) then printf,asc_unit,'' ; blank line between appends 
                  printf,asc_unit,mt  ; mtile of the plot(s)
                  if(plot_info(0).save_txt ne '') then $
                    printf,asc_unit,'  '+plot_info(0).save_txt
                  for i=1,plot_cnt do begin ;i=0 is was used with plot,/nodat
                    x_vect=x_arr(plot_info(i).beg:plot_info(i).fin)
                    pf=y_arr(plot_info(i).beg:plot_info(i).fin)
                    if(plot_info(i).save_txt ne '') then $
                      printf,asc_unit,'  '+plot_info(i).save_txt
                    printf,asc_unit,'  x_axis ('+!x.title+')='
                    printf,asc_unit,x_vect
                    printf,asc_unit,'  y_axis ('+!y.title+')='
                    printf,asc_unit,pf
                    printf,asc_unit,'' ; blank line between oplots
                  end
                  free_lun,asc_unit
                end
              end
           end
 endcase

end


pro image_profiles,image,img_hdr
  common shared,selected_img,fname,save,save_req,img,prof_win,img_win,prof_opt,$
              prof_types,erase_plot,xcent,ycent,plot_types,cent_id,ymin,ymax, $
              axis_types,scale_types,plt_opt,axs_opt,scl_opt,sc_xcent,sc_ycent,$
              motion_id,arcs,solr,xylab,p2p_pts,xp1,yp1,udef,beg_pt,end_pt,$
              cxc,cyc,cxr,cyr,radial_select,xout,pf,xx,yy,dd,asc_unit,asc_name,$
              x_arr,y_arr,plot_cnt,plot_info,imsize,last_press,img_name,mt,$
              rad,radx,rady,draw_box,sum_box,header,orig_img,cal_img,dimg_id
  common mshared,fwhm_keyword,date,time,filename,R1_ang,angle,camera,$
              boundary,x_subarray,xpeak,ypeak,halfmax,halfmax_array,edge
  common yvals,yr1,yr2,x_vect,zx1,zx2,zy1,zy2,zpt,zoom,ptmsg,org_pf,org_xar,$
               bsize,bmin,bmax,bscl,bw 

  if(n_params() eq 0) then begin
    print,''
    print,'Invalid Call.' 
    print,''
    print,'Calling Sequence: image_profiles,image,img_hdr'
    print,'                  or'
    print,"                  image_profiles,'...path.../xxxxxxxx.fts'"
    print,''
    return
  endif 

  if(n_params() eq 1) then begin
    if(strpos(strlowcase(image),'.fts') lt 0) then begin
     print,''
     print,'Invalid .FTS name. Call without parameter for valid input options.'
     print,''
     return
    end
    img= lasco_readfits(image,hdr,/fits) 
  end
  if(n_params() eq 2) then begin
    img= image
    hdr= img_hdr
  end
  s= size(img)
  imsize= s
  if(s(0) ne 2) then begin
    print,''
    print,'Input is not an image. Call without parameters for valid input options.'
    return
  end
  img_size= '  Image Size: ('+strtrim(string(s(1)),2)+','+strtrim(string(s(2)),2)+')'
  IF (DATATYPE(hdr) NE 'STC')  THEN hdr=LASCO_FITSHDR2STRUCT(hdr)
  sun_cent= get_sun_center(hdr,/nocheck)
  sc_xcent= sun_cent.xcen 
  xcent= sc_xcent 
  sc_ycent= sun_cent.ycen
  ycent= sc_ycent
  arcs= GET_SEC_PIXEL(hdr)
  solr= GET_SOLAR_RADIUS(hdr)
  img_name= '  Image: '+strupcase(hdr.filename)+' ('+hdr.date_obs+' '+ $
            hdr.time_obs+'),'

  header= hdr
  orig_img= img
  cal_img= 0

  erase_plot= 'true'
  prof_opt= 'Point to Point'
  plt_opt= 'Linear Plot'
  axs_opt= "Index"
  scl_opt= 'Intensity'
  p2p_pts= 0
  radial_select= 0
  plot_cnt= 0
  last_press= ''
  draw_box= 'false'

  zoom= 'false'
  zpt= 1
  zx1= 0 & zx2= 0
  zy1= 0 & zy2= 0
  !xmin=zx1 & !xmax=zx2
  !ymin=zy1 & !ymax=zy2

  plot_info= {plt:'',beg:0l,fin:0l,xout:0.0D,yout:0.0D,msg:'',save_txt:''}
  plot_info= replicate(plot_info,51)
  save_req= 0

  font='-adobe-times-bold-r-normal--14-140-75-75-p-77-iso8859-1'

;  base=widget_base(title='IMAGE_PROFILES.'+img_name+img_size,xsize=1018, $
;                   ysize=710,xoffset=2,/frame)
  base=widget_base(title='IMAGE_PROFILES.'+img_name+img_size,xoffset=2,/frame)

  b1= widget_base(base,/ROW)
  b4= widget_base(b1,/COLUMN)
  b2= widget_base(b1,/COLUMN)
  bb3= widget_base(b2,/ROW)
  bb6= widget_base(b4,/ROW)
  txt= widget_label(bb6,value='    ') ; OK here
  b6= widget_base(bb6,/ROW,/frame)
;  txt= widget_label(bb6,value='    ') ;  NOT OK here (does not do anything)
  beg_pt= cw_field(b6,UVALUE='bpt', VALUE= '', $
                          title='Profile End Points: ',/row,/ALL_EVENTS)
  end_pt= cw_field(b6,UVALUE='ept', VALUE= '', $
                          title='and',/row,/ALL_EVENTS)
  colb1= widget_base(b2,/ROW)
  txt= widget_label(bb3,value='                        ')
  b3=  widget_base(bb3,/ROW,/frame)
  txt= widget_label(b3,value=' ')
  quit = WIDGET_BUTTON(b3, VALUE='Quit', UVALUE='Done',/frame)
  txt= widget_label(b3,value='           ')
  help= WIDGET_BUTTON(b3, VALUE='Help',UVALUE='Help',/frame)
  txt= widget_label(b3,value=' ')
;  rowb1= widget_base(colb1,/ROW,/frame)
  r0= widget_base(colb1,/COLUMN,/frame)
;  rowb1= widget_base(r0,/ROW,/frame)
  rowb1= widget_base(r0,/ROW)
  rb2= widget_base(r0,/ROW)
  rb3= widget_base(r0,/ROW)

;   yr1= widget_slider(rb2,xsize=200,title='         set min. y-range',$
;                      value=0,uvalue='ymin',minimum=min(img),maximum=max(img))
;   chy= WIDGET_BUTTON(rb2,VALUE='Apply', UVALUE='new_y') 
;   yr2= widget_slider(rb2,xsize=200,title='         set max. y-range',$
;                      value=0,uvalue='ymax',minimum=min(img),maximum=max(img))

;  txt= widget_label(rb2,value="               ")
  txt= widget_label(rb2,value="     ")
  xzm= WIDGET_BUTTON(rb2,VALUE='ZOOM',UVALUE='xzm',/FRAME)
  org= WIDGET_BUTTON(rb2,VALUE='ORIG-PLOT',UVALUE='orp',/FRAME)
  txt= widget_label(rb2,value="   ")
	max = WIDGET_BUTTON(rb2,VALUE='FWHM',UVALUE='max',/FRAME)
	sav = WIDGET_BUTTON(rb2,VALUE='SAVE FWHM',UVALUE='sav',/FRAME)

  txt= widget_label(rb2,value="   ")
  mk_pk= widget_button(rb2, VALUE="Mark Plot Peaks",UVALUE="mkpk",/frame)
; msg='Select a new x-axis range by clicking on two points on any plot.'
  msg='                                                        '
  msg= msg+msg
  ptmsg= widget_label(rb3,value=msg,uvalue='pmsg',FONT=font)

  b0=    widget_base(b2,/COLUMN,/frame) ; /frame frames plot and options sec.
;  colb2= widget_base(b0,/ROW,/frame) 
  cb2= widget_base(b0,/ROW)
  colb3= widget_base(b0,/ROW,/frame)
  colb4= widget_base(b0,/ROW)
;  colb5= widget_base(b0,/ROW)
  colbt= widget_base(b2,/ROW)
;  b7=    widget_base(b2,/COLUMN,/frame) ; /frame frames print & save section.
  b7=    widget_base(b2,/ROW)
  b8=    widget_base(b2,/ROW)
  b9=    widget_base(b2,/ROW)
  colbb6= widget_base(b7,/COLUMN)
  colb6= widget_base(colbb6,/COLUMN,/frame)
  colbb7= widget_base(b7,/COLUMN)
  colb7= widget_base(colbb7,/COLUMN,/frame)
  colbb8= widget_base(b8,/COLUMN)
;  colb8= widget_base(colbb8,/ROW,/frame)
  colb8= widget_base(colbb8,/ROW)
  colbb9= widget_base(b9,/COLUMN)
;  colb9= widget_base(colbb9,/ROW)
  

  plot_types=['Linear Plot','Log Plot']
  txt= widget_label(cb2,value="    ")
  colb2= widget_base(cb2,/ROW,/frame)
  ptid= cw_bselector(colb2, UVALUE='ptype',plot_types)
  txt= widget_label(colb2,value=" ")
  axis_types=["Index (Intensity)", $
              "Distance (pixels)","Distance (Solar Radii)", $
              "X Component (pixels)","X Component (Solar Radii)", $
              "Y Component (pixels)","Y Component (Solar Radii)"]
  axid= cw_bselector(colb2, UVALUE='Xaxis',axis_types)
  txt= widget_label(colb2,value=" vs ")
  txt= widget_label(colb2,value="Intensity",/frame)
  prof_types=['Point to Point','Trace','Ring','Cross Section','Radial (sun center)', $
              'Radial (user defined)','None']
  prof_id= cw_bselector(colb3, UVALUE='popt',prof_types, $
                               label_left="Options:")
  cent_id= cw_field(colb3,UVALUE='cxy', VALUE= 'Not Applicable', $
                          title='centered at',/row,/ALL_EVENTS) 
;  txt= widget_label(colb4,value='    ')
  txt= widget_label(colb4,value=' ')
  ec_id= widget_button(colb4, VALUE="Mark End of Trace", UVALUE="mkend",/frame)
;  txt= widget_label(colb4,value='                     ')
  txt= widget_label(colb4,value='  ')
  bsize= 1
  bw= cw_field(colb4,UVALUE='boxw',VALUE= bsize,title="Box Width:", $
               /row,/ALL_EVENTS,xsize=3,/frame)
  txt= widget_label(colb4,value='  ')
  r1= widget_base(colb4,/ROW,/NONEXCLUSIVE,/frame)
  oplt= widget_button(r1, VALUE="Overplot profiles", UVALUE="oplot")
  
;  txt= widget_label(colbt,value=' ') ; leave a blank section
  b_id= widget_button(colb6, VALUE="Print Profile", UVALUE="prn")
  fname="soho-laser1"
   val= cw_field(colb6,UVALUE='pnm', VALUE= fname,title=" Printer:", $
                       /row,/ALL_EVENTS) ; can add /frame 

   asc_name= strmid(img_name,9,8)+'.txt'
   f_id= widget_button(colb7, VALUE="Save Profile", UVALUE="asc")
   val= cw_field(colb7,UVALUE='nasc', VALUE= asc_name,title="Filename:", $
                       /row,/ALL_EVENTS) 

   c3v= widget_button(colb8,VALUE="Apply C3 Vignetting", UVALUE="c3vig",/frame)
   txt= widget_label(colb8,value=" ")
   cb8= widget_base(colb8,/ROW,/frame)
;   dbx= widget_button(colb8, VALUE="Draw-Box/Sum-Intensities:",UVALUE='dbox')
;   sum_box= cw_field(colb8,UVALUE='sumi', VALUE=' ',title=" ",/row,/ALL_EVENTS)
   dbx= widget_button(cb8, VALUE="DrawBox/SumIntens:",UVALUE='dbox')
   sum_box= cw_field(cb8,UVALUE='sumi', VALUE=' ',title=" ",/row,/ALL_EVENTS)
;   txt= widget_label(colb9,value="                         ")
;   c3v= widget_button(colb9, VALUE="Apply C3 Vignetting", UVALUE="c3vig",/frame)

   lineprofile= widget_draw(rowb1,xsize=447,ysize=250,retain=2,/button_events, $
                    /viewport_events,UVALUE='pwin',/frame)
   draw= widget_draw(b4,xsize=s(1),ysize=s(2),retain=2,x_scroll_size=500, $
                    y_scroll_size=500,/button_events,/motion_events, $
                    /viewport_events,UVALUE='iwin',/frame)

  rowb4= widget_base(b4,/ROW,/frame)
;  txt= widget_label(rowb4,value="       ")
  bmin= abs(min(img)) & bmax= abs(max(img))
;  bmx= string(abs(min(img)),'(f5.2)')+","+string(max(img),'(f10.4)')
  bmx= string(abs(min(img)),'(i5)')+","+string(max(img),'(i7)')
  xldct= WIDGET_BUTTON(rowb4, VALUE='xloadct',UVALUE='xld')
;  txt= widget_label(rowb4,value="    ")
  bscl= cw_field(rowb4,UVALUE='scle', VALUE= bmx,title="ByteScale:", $
               /row,/ALL_EVENTS,xsize=14,/frame)
  rimg= widget_button(rowb4, VALUE="Refresh Image", UVALUE="ref")
  txt= widget_label(rowb4,value="  ")
  motion_id= cw_field(rowb4,UVALUE='mtd', VALUE= '',xsize=16,/frame, $
                          title='cursor:',/row,/ALL_EVENTS)
;  txt= widget_label(rowb4,value="    ")

  rowb5= widget_base(b4,/ROW)
  txt= widget_label(rowb5,value="  ")
  c_img= widget_button(rowb5,VALUE="Use Calibrated Image", UVALUE="cimg",/frame)
  dimg_id= cw_field(rowb5,UVALUE='dimg', VALUE= '>  Original Image', $
                 title='At Display: ',/ALL_EVENTS,/frame) 
;  txt= widget_label(rowb5,value=" ")
  o_img= widget_button(rowb5, VALUE="Use Original Image", UVALUE="oimg",/frame)

  widget_control,/realize,base
  widget_control,lineprofile,get_value= prof_win 
  widget_control,draw,get_value= img_win 

  wset,img_win 
;  tvscl,img
  tv,bytscl(img,bmin,bmax)

  struct = { $
    base:base $
  }
  
  save= 0 ; default - do not save the list of selected image names
  ssfname= ['CURRENT_SCR.GIF']

  widget_control,base, SET_UVALUE=struct

  XMANAGER, 'IMG_SELECT', base, EVENT_HANDLER='IMG_SELECT_EVENT'


  return

end
