; $Id: cwo_autographnse__define.pro,v 1.15 2005/11/16 17:07:08 kneller Exp $
;###############################################################################
;
;
;CLASS NAME:
;    pro cwo_autographNSE__define,struct
;
;PURPOSE:
;
;CATEGORY:
;
;
;SUPERCLASSES:
;    myproperties
;
;
;METHODS:
;    cwo_autographNSE
;    runag_event
;    runag
;    cwo_autographNSE::draw
;    nse_expdecay
;    nse_deformation
;    cwo_autographNSE::fit
;    cwo_autographNSE::openFiles
;    cwo_autographNSE::resize
;    cwo_autographNSE::zoom
;    cwo_autographNSE::event
;    cwo_autographNSE_event
;    cwo_autographNSE_realize
;    cwo_autographNSE::realize
;    cwo_autographNSE::cleanup
;    cwo_autographNSE_cleanup
;    cwo_autographNSE::init
;    cwo_autographNSE__define
;
;
; AUTHOR:
; Larry Kneller
; NIST Center for Neutron Research
; 100 Bureau Drive, Gaithersburg, MD 20899
; United States
; kneller@nist.gov  301-975-8839
; Thu May 26 21:00:27 2005
;
; LICENSE:
; The software in this file is written by an employee of
; National Institute of Standards and Technology
; as part of the DAVE software project.
;
; The DAVE software package is not subject to copyright protection
; and is in the public domain. It should be considered as an
; experimental neutron scattering data reduction, visualization, and
; analysis system. As such, the authors assume no responsibility
; whatsoever for its use, and make no guarantees, expressed or
; implied, about its quality, reliability, or any other
; characteristic. The use of certain trade names or commercial
; products does not imply any endorsement of a particular product,
; nor does it imply that the named product is necessarily the best
; product for the stated purpose. We would appreciate acknowledgment
; if the DAVE software is used or if the code in this file is
; included in another product.
;
;###############################################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_autographNSE,parent,workdir=workdir,objref = objref,_Extra=_Extra

    objref = obj_new('cwo_autographnse',parent,obj_ref=obj_ref,workdir=workdir)

    return,objref->getproperty(/tlb)

end;cwo_autographNSE
;###############################################################################
;
;NAME:
;        nse_expdecay
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function nse_expdecay,X,P;INDEPENDENT VAR IS t*Q^2
;
;NAME:
;        nse_expdecay
;
;PURPOSE:
;       function for fitting the data.
;PARAMETERS:
;       X   data values
;       P   parameter values.
;KEYWORDS:
;       none
;RETURN VALUE:
;       function values at the X avlues.
    ;DECAYING EXPONENTIAL FOR FITTING I(Q,t) CURVES

    ;A=P[0]
    ;D=P[1]
    ;X=t*Q^2

    return,P[0]*exp(-1.0*P[1]*X)

end;nse_expdecay

function nse_deformation,X,P
;
;NAME:
;        nse_deformation
;
;PURPOSE:
;       function for fitting the data.
;PARAMETERS:
;       X   data values
;       P   parameter values.
;KEYWORDS:
;       none
;RETURN VALUE:
;       function values at the X avlues.


;THE FOLLOWING LINES ARE TAKEN DIRECTLY FROM THE IGOR
;DEFORMATION FUNCTION CODE  WITH ONLY MINOR MODIFICATIONS WHERE
;IDL COMMANDS DIFFER FROM IGOR COMMANDS.

;p is the input coefficients
;Variable lam,a2,rad,Dtr,def,qr,f2,j0,j2,j3
lam = p[0]		;damping freq (Hz)
lam = lam/1.0e9		; 1/s to 1/ns
a2 = p[1]		;amplitude squared (dimensionless)
rad = p[2]	;mean droplet radius (A)
Dtr = p[3]	;q-independent translational diffusion (A^2/ns)

qr = x*rad
j0 = sin(qr)/qr
j2 = (3.0/qr^(3.0d) - 1.0/qr)*sin(qr) - (3.0/qr^(2.0d))*cos(qr)


order = 3.5d
j3 = sqrt(!PI/2.0/qr)*beselJ(qr,order ,/double)

f2 = 5.0d*(4.0d*j2-qr*j3)^(2.0d)

def = 5.0d*lam*f2*a2/(x*x*(4.0d*!PI*j0*j0+5*f2*a2))

;f(x) = (def + Dtr)
return,(def + Dtr)

end;nse_deformation

;###############################################################################
;
;NAME:
;        runag_event
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro runag_event,event

    ;print,tag_names(event,/structure_name)
    ;print,tag_names(event)

end;runag_event

;###############################################################################
;
;NAME:
;        runag
;
;PURPOSE:
;        TESTING PROGRAM TO RUN THE CLASS.
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro runag,title=title
    ;FOR TESTING
    b = widget_base(title='autograph group leader',xsize=100,ysize=100)
    a = cwo_autographnse(b,objref=objref)
    widget_control,b,/realize
    xmanager,'runag',a,/no_block

end;runag
;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE::draw
;
;PURPOSE:
;           Draw the data.
;PARAMETERS:
;           none
;KEYWORDS:
;           zoomwin     The id of the drawwindow to put a zoombox in.
;###############################################################################
pro cwo_autographNSE::draw,zoomwin=zoomwin

;print,'draw'
    if ptr_valid(self.data) ne 0 then begin

        help,self.data,output=out
        helppos = strpos(out,'Null')
        ;print,out
        if max(helppos) eq -1 then begin    ;CHECK FOR DATA


            if n_elements(zoomwin) eq 0 then zoomwin = 0L

            if widget_info(zoomwin,/valid_id) ne 0 then begin
                widget_control,zoomwin,get_value=zoomid
            endif

            device,get_decomposed = dc
            device,decomposed = 1


            data = *self.data


            black = 0L
            white = 255L + 256L*(255L +256L*255L)
            blue = 256L*256L*255L
            lightblue = 100L*256L*255L + 100L*255L
            red = 255L
            green = 256L*255L
            magenta = blue+red
            yellow = blue+green

            ;OFFSET color AND symbol BY 1 TO YIELD 30 DIFFERENT COMBINATIONS
            color = [black,blue,red,green,magenta,yellow]
            symbol = [1,3,4,5,6]


            ;PLOT I(Q,t)
            wset,self.idrawpixid

            x = *(data[0].pt) & y = *(data[0].pi) & sy = *(data[0].psi)

            xrange = [self.ixmin,self.ixmax]
            yrange = [self.iymin,self.iymax]


            plot,x,y,xrange=xrange,yrange=yrange,$
                        ytitle='I(Q,t)/I(Q,0)',xtitle='t [ns]',$
                        title = 'I(Q,t)/I(Q,0) v t',$
                        background=white,$
                        color=color[0],psym=symbol[0];,$
                        ;xstyle=1,ystyle=1
            p = (*(data[0].pparms))[0:1]
            ;print,p
            oplot,x,nse_expdecay(x*(data[0].Q)^(2.0d),p),color=color[0],psym=0
            errplot,x,y-sy,y+sy
            nse_legend,self.idrawpixid,0.8,0.90,'Q='+strtrim(string(data[0].Q,format='(f8.6)'),2),$
                                        color=color[0],psym=symbol[0]

            for i=1,n_elements(data)-1 do begin
                p = (*(data[i].pparms))[0:1]
                x = *(data[i].pt) & y = *(data[i].pi) & sy = *(data[i].psi)
                oplot,x,y,color=color[i mod 6],psym=symbol[i mod 5]
                oplot,x,nse_expdecay(x*(data[i].Q)^(2.0d),p),color=color[i mod 6],psym=0
                errplot,x,y-sy,y+sy,color=color[i mod 6]
                nse_legend,self.idrawpixid,0.8,0.90-i*0.04,'Q='+strtrim(string(data[i].Q,format='(f8.6)'),2), $
                                    color=color[i mod n_elements(color)],psym = symbol[i mod n_elements(symbol)]
            endfor

            if self.mousepressed eq 1 then begin
                if zoomwin eq self.idraw then $
                    self->zoombox,self.idrawpixid
            endif

        ;SET THE idraw AXIS POINTERS HERE.
        ;RELEASE AXIS POINTERS FOR WINDOW
        ptr_free,self.ixptr
        ptr_free,self.iyptr

        ;RESET AXIS POINTERS
        self.ixptr = ptr_new(!x)   ;SET THESE VALUES AT THIS POINT TO
        self.iyptr = ptr_new(!y)   ;PREVENT AXIS CONFUSION


            wset,self.idrawid
            ;COPY IMAGE IN VIRTUAL WINDOW TO CURRENT WINDOW
            device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.idrawpixid]


            ;PLOT D(Q)
            wset,self.ddrawpixid

            xall = [data[*].Q]
            x = [0.0d]
            y = [0.0d] & sy = [0.0d]
            yall = [0.0d] & syall = [0.0d]


            ;print,data[*].masked
            for i=0,n_elements(data)-1 do begin
                yall  = [yall, (*(data[i].pparms))[1]]
                syall = [syall,(*(data[i].pparms))[3]]
                if (data[i].masked) eq 0 then begin
                    x  = [x,data[i].Q]
                    y  = [y, (*(data[i].pparms))[1]]
                    sy = [sy,(*(data[i].pparms))[3]]
                endif
            endfor;i

            if n_elements(y) gt 1 then begin;2 then begin
                x = x[1:*] & y = y[1:*] & sy = sy[1:*]
                yall = yall[1:*] & syall = syall[1:*]

                xrange = [self.dxmin,self.dxmax]
                yrange = [self.dymin,self.dymax]
                plot,xall,yall,xrange=xrange,yrange=yrange,$
                        color=black,$
                        background=white,$
                        psym=8,$;1,$
                        xtitle='Q [1/A]',$
                        ytitle='D(Q) [A^2/ns]',$
                        title = 'D(Q) v Q',/nodata;,$
                        ;xstyle=1,ystyle=1
                oplot,xall,yall,color=lightblue,psym=8
                oplot,x,y,color=black,psym=8

                ;GET p LATER ON
                p = (*self.dfitparms);[0:(fix((double(n_elements(*self.dfitparms)-1))/2.0))-1];[double(6.8e7),0.014d,27.0d,17.0d]
                ;print,p
                p[0] = p[0]*(1.0e6);CONVERT TO Hz FOR CALCULATION OF DEFORMATION
                p[4] = p[4]*(1.0e6);CONVERT TO Hz FOR CALCULATION OF DEFORMATION
                errplot,x,y-sy,y+sy,color=black;,psym = 1
                xind = findgen(10*n_elements(x))
                xmin = !x.crange[0];min(xrange);min(x)
                xmax = !x.crange[1];max(xrange);max(x)
                x5 = xmin + xind*(xmax-xmin)/(max(xind))

                nparms = (fix((double(n_elements(*self.dfitparms)-1))/2.0))
    ;            print,nparms
    ;            print,n_elements(*self.dfitparms)
    ;            help,*self.dfitparms
                oplot,x5,nse_deformation(x5,p[0:nparms-1]),$
                                color=red,psym=0;color[0],psym=0

            ;    nse_legend,self.ddrawid,0.5,0.5,'CENTER',color=black
;        deformationLabels = ['!4abcdefghijklmnopqrstuvwxyz!32',$
        deformationLabels = ['Damp freq  (!4k!3!d2!n)=',$; (MHz)',$
                             'Amplit. (<|a!d2!n|!e2!n>)=',$
                             'Mean Rad.  (R!do!n)=',$; (A)',$
                             'D trans     (D!dtr!n)=']; (A^2/ns)']
        deformationunits = [' MHz',' ',' A',' A!e2!n/ns']
                ;print,p[0],p[4]
                p[0] = p[0]/1e6;CONVERT FREQUENCY TO MHz FOR LEGEND
                ;print,p[0],p[4]
                p[4] = p[4]/1e6
                ;print,p[0],p[4]
                formatg1 = '(f10.4)';'(e12.4)'
                formatl1 = '(f10.7)';'(e12.4)'
                for i=0,nparms-1 do begin
                    format =  (p[i] gt 0.1) ? formatg1 : formatl1
                    nse_legend,!d.window,0.30,0.95-i*0.05,$;self.ddrawpixid,0.3,0.5-i*0.05,$
                        deformationlabels[i]+string(p[i],format=format)+' +/- '+ $
                                             string(p[i+nparms],format=format)+ $
                                                 deformationunits[i],color=black
    ;                nse_legend,!d.window,0.4,0.9-i*0.05,$;self.ddrawpixid,0.3,0.5-i*0.05,$
    ;                    'P['+strtrim(string(i),2)+']='+string(p[i],format=format)+' +/- '+string(p[i+nparms],format=format),color=black
                endfor;i
                nse_legend,!d.window,0.3,0.95-nparms*0.05,$;,self.ddrawpixid,0.3,0.5-nparms*0.05,$
                                'chisq='+string(p[2*nparms],format=format),color=black


                if self.mousepressed eq 1 then begin
                    if zoomwin eq self.ddraw then $
                        self->zoombox,self.ddrawpixid
                endif

        ;SET THE ddraw AXIS POINTERS HERE.
        ;RELEASE AXIS POINTERS FOR WINDOW
        ptr_free,self.dxptr
        ptr_free,self.dyptr

        ;RESET AXIS POINTERS
        self.dxptr = ptr_new(!x)   ;SET THESE VALUES AT THIS POINT TO
        self.dyptr = ptr_new(!y)   ;PREVENT AXIS CONFUSION


                wset,self.ddrawid
                ;COPY IMAGE IN VIRTUAL WINDOW TO CURRENT WINDOW
                device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.ddrawpixid]

            endif else begin
                print,'NOT ENOUGH DATA TO PLOT.'
            endelse
        endif else begin
            ;print,'self.data IS "Null"'
        endelse
    endif else begin    ;NO DATA RESIZE
        ;print,'HERE!!!'
        white = 255L + 256L*(255L + 256L*255L)
        black = 0L

        x=findgen(100)
        y = cos(x/100*2*!PI)


        wset,self.idrawpixid
        plot,x,y,xrange=[0,0.5],yrange = [0,100],color=black,background=white,/nodata,$
                    ytitle='D(Q) [A^2/ns]',xtitle='Q [1/A]',$
                    title = 'D(Q) v Q'

        wset,self.idrawid
        ;COPY IMAGE IN VIRTUAL WINDOW TO CURRENT WINDOW
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.idrawpixid]

        y = sin(x/100*2*!PI)

        wset,self.ddrawpixid
        plot,x,y,xrange=[0,1],yrange = [0,1],color=black,background=white,/nodata,$
                    ytitle='I(Q,t)/I(Q,0)',xtitle='t [ns]',$
                    title = 'I(Q,t)/I(Q,0) v t'

        wset,self.ddrawid
        ;COPY IMAGE IN VIRTUAL WINDOW TO CURRENT WINDOW
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.ddrawpixid]







    endelse
    device,decomposed = dc
end;draw
;###############################################################################
;
;NAME:
;        cwo_autographNSE::zoomBox
;
;PURPOSE:
;           Draw a zoombox in zoomwin
;PARAMETERS:
;           zoomwin     The window to draw the box in.
;KEYWORDS:
;           none
;###############################################################################
pro cwo_autographNSE::zoomBox,zoomid

;    print,'zoomid=',zoomid
;    print,'widget_info(zoomid)=',widget_info(zoomid)

device,get_decomposed=dc
device,decomposed=1
    black = 0L
    if zoomid ne 0L then begin
        ;print,'**********************************************************'
        wset,zoomid
        x1 = min([self.mousex1,self.mousex2])
        x2 = max([self.mousex1,self.mousex2])
        y1 = min([self.mousey1,self.mousey2])
        y2 = max([self.mousey1,self.mousey2])
        plots,[x1,x2],[y1,y1],color=black,/device
        plots,[x2,x2],[y1,y2],color=black,/device
        plots,[x2,x1],[y2,y2],color=black,/device
        plots,[x1,x1],[y2,y1],color=black,/device
        plots,[x1,x2],[y1,y1],color=black,/device
    endif;zoom

device,decomposed=dc

end;zoomBox

;###############################################################################
;
;NAME:
;        cwo_autographNSE::fit
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_autographNSE::fit,x,y,sy
print,'cwo_autographNSE::fit'
            ny = where(y ne double('Nan'))
            if ny[0] ne -1 then begin
                x = x[where(y ne double('Nan'))]
                y = y[where(y ne double('Nan'))]
                sy = sy[where(sy ne double('Nan'))]
            endif
;print,'TEST1'
            nz  = where(sy eq 0.0)
            if nz[0] ne -1 then begin
                sy[where(sy eq 0.0)] = 1.0d
            endif
;print,'TEST2'

            if n_elements(y) gt 3 then begin
                start = [1.0d,double(-1.0*alog(y[n_elements(y)/2])/x[n_elements(y)/2])]
            endif else begin
                start = [1.0d,10.0d]
            endelse
            print,start
;print,'TEST3'

            parinfo = replicate({value:0.0d,$
                                 fixed:0,$
                                 limited:[0,0], $
                                 limits:[0.0d,0.0d],$
                                 parname:'',tied:''},$
                                 2)
            parinfo[*].value = start
            parinfo[*].fixed = 0

            ;AMPLITUDE SHOULD BE FIXED TO 1
            if nse_comboindex(self.ifcombo) eq 1 then begin
                parinfo[0].fixed = 1
            endif else begin
                parinfo[0].fixed = 0
            endelse


            parinfo[0].limits = [0.00000001d,1000.0d]
            parinfo[1].limits = [0.00000001d,100000000.0d]
            perror = dindgen(2)
            dumfits = mpfitfun('nse_expdecay',x,y,sy,parinfo=parinfo,/quiet,perror=perror,bestnorm=bestnorm)
            if n_elements(bestnorm) eq 0 then bestnorm = double('nan');n_elements(x)*100000000.0000
            chisq = bestnorm/double(n_elements(x)-2)


            return,[dumfits,perror,chisq]

end;fit
;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE::fitD
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_autographNSE::fitD,x,y,sy,functionIndex,start=start,fixed=fixed,$
                            deformation=deformation,$
                            dq3=dq3

        if n_elements(functionIndex) eq 0 then functionIndex = 0
        if n_elements(fixed) ne 4 then fixed = intarr(4)

        ;GET STARTING VALUES
        text = *(self.dfittext)

        if n_elements(start) eq 0 then begin
            start = dblarr(4)
            for i=0,n_elements(start)-1 do begin
                widget_control,text[i],get_value=parm
                start[i] = double(parm)
            endfor
            ;CONVERT FROM MHz TO Hz FOR FIT.
            start[0] = 1.0e6*start[0]
        endif
        if min(fixed) eq 1 then begin
            void = dialog_message('FIXING ALL FIT PARAMETERS NOT ALLOWED')
            result =  [start,0.0*start,double('nan')]
        endif else begin
            ;print,'start=',start
            ;help,start

            ny = where(y ne double('Nan'))
            if ny[0] ne -1 then begin
                x = x[where(y ne double('Nan'))]
                y = y[where(y ne double('Nan'))]
                sy = sy[where(sy ne double('Nan'))]
            endif

            nz  = where(sy eq 0.0)
            if nz[0] ne -1 then begin
                sy[where(sy eq 0.0)] = 1.0d
            endif


            parinfo = replicate({value:0.0d,$
                                 fixed:0,$
                                 limited:[0,0], $
                                 limits:[0.0d,0.0d],$
                                 parname:'',tied:''},$
                                 n_elements(start))
            parinfo[*].value = start
            parinfo[*].fixed = fixed
    ;        parinfo[*].limited = [1,1]
    ;        parinfo[0].limited = [1,0]
    ;        parinfo[0].limited = [1,0]
            for i=0,n_elements(start)-1 do begin
                parinfo[i].limits = [start[i]-0.3*start[i],start[i]+0.3*start[i]]
            endfor;i
            perror = dblarr(n_elements(start))

            functionName = ['nse_deformation']
            fcn = functionName[functionIndex]
            ;print,fcn
            ;print,start
            ;print,'parinfo[*].value',parinfo[*].value
            ;print,nse_deformation(x,start)-y
            ;help,perror
            ;print,perror
            dumfits = mpfitfun('nse_deformation',x,y,sy,parinfo=parinfo,perror=perror,bestnorm=bestnorm,/quiet)
    ;        dumfits = mpfitfun(fcn,x,y,sy,parinfo=parinfo,perror=perror,bestnorm=bestnorm)
            if n_elements(bestnorm) eq 0 then bestnorm = double('nan');n_elements(x)*100000000.0000
            chisq = bestnorm/double(n_elements(x)-n_elements(start))
            ;help,perror
            ;print,perror

            ;self->draw
    ;help,dumfits
    ;help,perror
    ;help,chisq
    ;        dumfits[0] = dumfits[0]/1.0e6  ;DO CONVERSION OUTSIDE FIT METHOD.
    ;        perror[0] = perror[0]/1.0e6
            ;print,'dumfits=',dumfits
            ;print,'perror=',perror
            ;print,'chisq=',chisq
            result = [dumfits,perror,chisq]
            ;print,result

        endelse

        return,result

end;fitD
;###############################################################################
;
;NAME:
;        cwo_autographNSE::openFiles
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
function cwo_autographNSE::openFiles


    if self.workdir ne '' then begin
        workdir = self.workdir
    endif else workdir = ''

    fn = dialog_pickfile(/read,/multi,path = workdir)




CATCH, Error_status
   ;HANDLE ERRORS IN READING THE STATE FILE.
   IF (Error_status NE 0) THEN BEGIN
        print,tag_names(!Error_state)
        print,!Error_state
      free_lun,lun,/force
      CATCH, /CANCEL
      void = dialog_message('Please choose multiple correct I(Q,t) files.',/info)
      return,0
   ENDIF



    if n_elements(fn) gt 1 and fn[0] ne '' then begin
    ;print,fn

        order = sort(file_basename(fn))

        self.workdir = file_dirname(fn[0])
        ;print,self.workdir

        bfn = file_basename(fn)
        n = n_elements(fn)

        struct = {IQTDataStruct,$
                    Q:0.0d,$
                    pt:ptr_new(),$
                    pi:ptr_new(),$
                    psi:ptr_new(),$
                    pparms:ptr_new(),$
                    masked:0}

        data = replicate(struct,n)



        line = ''
        for i=0,n-1 do begin

            ii = order[i]
            nlines = file_lines(fn[ii])

            if ptr_valid(data[i].pt) gt 0 then ptr_free,data[i].pt
            data[i].pt = ptr_new((dblarr(nlines-1)+1.0d)*double('nan'))
            if ptr_valid(data[i].pi) gt 0 then ptr_free,data[i].pi
            data[i].pi = ptr_new((dblarr(nlines-1)+1.0d)*double('nan'))
            if ptr_valid(data[i].psi) gt 0 then ptr_free,data[i].psi
            data[i].psi = ptr_new((dblarr(nlines-1)+1.0d)*double('nan'))
            if ptr_valid(data[i].pparms) gt 0 then ptr_free,data[i].pparms
            data[i].pparms = ptr_new((dblarr(5)+1.0d)*double('nan'))


            openr,lun,fn[ii],/get_lun

    ;        ;REMOVE 1st AND last 4 LETTERS IN bfn
    ;        data[i].Q = double(strmid(bfn[i],4,strlen(bfn[i]-8-1)))

            for j=0,nlines-1 do begin
                if j ne 0 then begin
                    ;READ THE DATA
                    readf,lun,line
    ;                print,line
                    segs = strsplit(line,/extract)
    ;                print,segs
                    (*(data[i].pt))[j-1] = double(segs[1])
                    (*(data[i].pi))[j-1] = double(segs[2])
                    (*(data[i].psi))[j-1] = double(segs[3])


                endif else begin
                    readf,lun,line  ;READ HEADER LINE
                endelse
            endfor;j
            data[i].Q = double(segs[0])

            free_lun,lun

        ;FIT THE I(Q,t) DATA TO GET D(Q)
            xarr = (*(data[i].pt))*((data[i].Q)^2.0d)
            yarr = (*(data[i].pi))
            syarr = (*(data[i].psi))
            (*(data[i].pparms)) = self->fit(xarr,yarr,syarr)
            ;print,data[*].Q

        endfor;

        if ptr_valid(self.data) then ptr_free,self.data
        self.data = ptr_new(data)

        self->setScale,open=1
    text = *(self.dfittext)

    if n_elements(start) eq 0 then begin
        start = dblarr(4)
        for i=0,n_elements(start)-1 do begin
            widget_control,text[i],get_value=parm
            start[i] = double(parm)
        endfor
        ;CONVERT FROM MHz TO Hz FOR FIT.
        ;start[0] = 1.0e6*start[0]
    endif
    help,*self.dfitparms
    (*self.dfitparms)[0:3] = start
    (*self.dfitparms)[4:8] = double('nan')


        return,1
    endif else begin
        void = dialog_message('Please choose multiple correct I(Q,t) files.',/info)
        return,0
    endelse

end;open
;#######################################################


;###############################################################################
;
;NAME:
;        cwo_autographNSE::setScale
;
;PURPOSE:
;           Set ranges on the plots.
;PARAMETERS:
;           none
;KEYWORDS:
;           open    Flag to reset scales to initial values.
;           reseti  Flags to reset each plot to initial scaling.
;           resetd
;           qrange
;           trange
;           irange
;           drange
;###############################################################################
pro cwo_autographNSE::setScale,open=open,qrange=qrange,trange=trange,irange=irange,drange=drange,$
                                reseti=reseti,resetd=resetd

    if n_elements(reseti) eq 0 then reseti = 0
    if n_elements(resetd) eq 0 then resetd = 0

    if n_elements(open) eq 0 then open = 0
    if (open eq 1) then begin
        reseti = 1
        resetd = 1
    endif


    D = (*((*self.data)[0].pparms))[1]
    sD = (*((*self.data)[0].pparms))[3]
    for i=1,n_elements(((*self.data)[*].pparms))-1 do begin
        D = [D,(*((*self.data)[i].pparms))[1]]
        sD = [sD,(*((*self.data)[i].pparms))[3]]
    endfor
;print,'D=',D
;print,'sD=',sD


    t = (*((*self.data)[0].pt))
    iqt = (*((*self.data)[0].pi))
    siqt = (*((*self.data)[0].psi))
    for i=1,n_elements(((*self.data)[0].pt))-1 do begin
        t = [t,(*((*self.data)[i].pt))]
        iqt = [iqt,(*((*self.data)[i].pi))]
        siqt = [siqt,(*((*self.data)[i].psi))]
    endfor


    if (reseti eq 1) or (resetd eq 1) then begin
        if reseti eq 1 then begin
            self.ixmin = min(t)
            self.ixmax = max(t)
            self.iymin = min(iqt-siqt) - 0.5*abs(min(iqt-siqt))
            self.iymax = max(iqt+siqt) + 0.5*abs(max(iqt+siqt))
        endif;reseti
        if resetd eq 1 then begin
            self.dxmin = min(((*self.data)[*].Q))
            self.dxmax = max(((*self.data)[*].Q))
            self.dymin = min(D-sD) - 0.5*abs(min(D-sD))
            self.dymax = max(D+sD) + 0.5*abs(max(D+sD))
        endif;resetd
    endif else begin
        if n_elements(qrange) eq 2 then begin
            self.dxmin = qrange[0]
            self.dxmax = qrange[1]
        endif;qrange
        if n_elements(qrange) eq 2 then begin
            self.dymin = drange[0]
            self.dymax = drange[1]
        endif;qrange
        if n_elements(qrange) eq 2 then begin
            self.ixmin = trange[0]
            self.ixmax = trange[1]
        endif;qrange
        if n_elements(qrange) eq 2 then begin
            self.iymin = irange[0]
            self.iymax = irange[1]
        endif;qrange
    endelse

end;setScale


;###############################################################################
;
;NAME:
;        cwo_autographNSE::resize
;
;PURPOSE:
;           Handle resize events
;PARAMETERS:
;
;KEYWORDS:
;
;###############################################################################
pro cwo_autographNSE::resize,event

    ;print,'cwo_autographNSE::resize'


    xsize = event.x-100
    ysize = event.y
    if event.x le 300 then xsize=400
    if event.y le 300 then ysize=300

    winysize = (ysize-20)/2
    widget_control,self.idraw,xsize=xsize-150,ysize=winysize
    widget_control,self.ddraw,xsize=xsize-150,ysize=winysize

    wdelete,self.idrawpixid
    window,/free,/pixmap,xsize=xsize-150,ysize=winysize
    self.idrawpixid = !d.window

    wdelete,self.ddrawpixid
    window,/free,/pixmap,xsize=xsize-150,ysize=winysize
    self.ddrawpixid = !d.window

    if ptr_valid(self.data) ne 0 then self->draw

    self->draw

end;resize

;###############################################################################
;
;NAME:
;        cwo_autographNSE::zoom
;
;PURPOSE:
;           Handle zoom events in the D(Q) plot.
;PARAMETERS:
;           event   The mouse event to handle.
;KEYWORDS:
;           none
;###############################################################################
pro cwo_autographNSE::zoom,event,id


    ;if id eq self.idraw then print,id,event.id,'zoom_i'
    ;if id eq self.ddraw then print,id,event.id,'zoom_d'
    ;print,'cwo_autographNSE::zoom'

;        print,tag_names(event)
;        print,event


;                    mousex1:0.0,$
;                    mousey1:0.0,$
;                    mousex2:0.0,$
;                    mousey2:0.0,$
;                    mousepressed:0,$

    case event.type of
    0:begin
        case event.press of
        1:begin
            ;print,'LEFT MOUSE BUTTON PRESSED'
            self.mousepressed = 1
            self.mousex1 = event.x
            self.mousey1 = event.y
        end;1
        4:begin
            ;print,'RIGHT MOUSE BUTTON PRESSED'

                if event.id eq self.ddraw then begin
                    !x = *self.dxptr
                    !y = *self.dyptr

                    niqt = n_elements(*self.data)
                    masked_tot = total((*self.data)[*].masked)
                    unmasked = niqt-masked_tot
                    print,'masked_tot=',masked_tot
                    print,'niqt-masked_tot=',niqt-masked_tot
                    ;CHECK THAT MOUSE IS IN PLOT BEFORE PROCEEDING.
                    check =  convert_coord(self.mousex2,self.mousey2,/device,/to_data)
                    ;print,check
                    if check[0] ge min(!x.crange) and $
                        check[0] le max(!x.crange) and $
                         check[1] ge min(!y.crange) and $
                          check[1] le max(!y.crange) then begin

                        ;USE event.x,event.y
                            result = convert_coord(event.x,event.y,/device,/to_normal);/to_data)
        ;                    print,'result=',result

                            masked_tot = total((*self.data)[*].masked)
                            print,masked_tot
                            print,'unmasked=',unmasked
                            if unmasked ge 2 then begin;n_elements(*self.data) gt 2 then begin
                                data = *self.data
                                x = [data[*].Q]
                                y = [0.0d] & sy = [0.0d]
                                for i=0,n_elements(data)-1 do begin
                                    y  = [y, (*(data[i].pparms))[1]]
                                endfor;i

                                ;print,(x-result)^2

                                newr = (convert_coord(x,y,/data,/to_normal))[0:1,*]

                                sz = size(newr)
                                ;print,'newr=',newr

                                ;GET CLOSEST POINT
                                print,'newr[0,*]='
                                print,transpose((newr[0,*]))
                                print,'result=',result
                                xsq = (newr[0,*] - result[0])^(2.0d)
                                xp = sqrt(xsq)
                                xmin = min(xp,imin)

            ;071205
            ;SET UP MASKING INSTEAD OF POINT REMOVAL
                                print,'imin=',imin
                                masked  = (*self.data)[imin].masked
                                print,(masked eq 1 ? 0 : 1)
                                (*self.data)[imin].masked = (masked eq 1 ? 0 : 1)
                                print,(*self.data)[imin].masked
                                ;CHECK THAT THERE ARE AT LEAST 2 UNMASKED POINTS
                                masked_tot = total((*self.data)[*].masked)
                                unmasked = niqt - masked_tot
                                if unmasked ge 2 then begin
                                    ;print,'AM I UNDOING THE RESULT?'
                                    (*self.data)[imin].masked = (masked eq 1 ? 0 : 1)
                                endif else begin
                                    (*self.data)[imin].masked = 0
                                    void = dialog_message('Must have at least two unmasked points.')
                                endelse
                        endif else begin
                            void = dialog_message('Must have at least two points.')
                        endelse
                   endif;mouse in plot

            endif;ddraw



        end;4
        5:begin
            print,'PRESS WITH TWO MOUSE BUTTONS'
            print,'P############################################################'


        end
        else:begin
        end;else
        endcase
    end
    1:begin

        print,'RELEASE'
        case event.release of
        1:begin
            print,'LEFT MOUSE BUTTON RELEASED'
            self.mousepressed = 0
            self.mousex2 = event.x
            self.mousey2 = event.y

            ;print,event.x,event.y
            if self.mousex1 ne self.mousex2 and self.mousey1 ne self.mousey2 then begin
                ;not same position
                if event.id eq self.idraw then begin
                    !x = *self.ixptr
                    !y = *self.iyptr

                    result1 = convert_coord(self.mousex1,self.mousey1,/device,/to_data)
                    ;print,result1
                    result2 = convert_coord(self.mousex2,self.mousey2,/device,/to_data)
                    ;print,result2
                    self.ixmin = min([result1[0],result2[0]])
                    self.ixmax = max([result1[0],result2[0]])
                    self.iymin = min([result1[1],result2[1]])
                    self.iymax = max([result1[1],result2[1]])
                endif
                if event.id eq self.ddraw then begin
                    !x = *self.dxptr
                    !y = *self.dyptr
                    result1 = convert_coord(self.mousex1,self.mousey1,/device,/to_data)
                    ;print,result1
                    result2 = convert_coord(self.mousex2,self.mousey2,/device,/to_data)
                    ;print,result2
                    self.dxmin = min([result1[0],result2[0]])
                    if self.dxmin le 0.0 then self.dxmin = 0.0  ;PROTECT FROM NEGATIVE Q WHICH CRASHES BESELJ
                    self.dxmax = max([result1[0],result2[0]])
                    self.dymin = min([result1[1],result2[1]])
                    self.dymax = max([result1[1],result2[1]])
                endif
            endif else begin

                ;RESET SCALE IF MOUSE DOESN'T MOVE ON CLICK
                if event.id eq self.idraw then self->setScale,reseti=1
                if event.id eq self.ddraw then self->setScale,resetd=1

            endelse
            self->draw
        end;left mouse button
        4:begin
;            print,'RIGHT MOUSE BUTTON RELEASED'
            self->draw
        end;right mouse button
        5:begin

            print,'RELEASE WITH TWO MOUSE BUTTONS'
            print,'R############################################################'
        end
        else:begin
        end;else
        endcase
    end
    2:begin
        ;print,'MOTION'
        if self.mousepressed eq 1 then begin
            ;print,'DRAG'
            self.mousex2 = event.x
            self.mousey2 = event.y

            self->draw,zoomwin = event.id

        endif
    end
    else:
    endcase



end;zoom



;###############################################################################
;
;NAME:
;        cwo_autographNSE::updateDparmwidgets
;
;PURPOSE: Update the fitting widgets on change in model selection.
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
pro cwo_autographNSE::updateDparmwidgets,selection


;071905
;ENCAPSULATE THE NEXT BLOCK FOR REDEFINITION FOR DIFFERENT MODELS.

    case selection of
    0:begin
        deformationLabels = ['Damping frequency (MHz)',$
                             'Amplitude',$
                             'Mean Radius (A)',$
                             'D trans (A^2/ns)']
        tooltip = ['lambda2','<|a2|^2>','Ro','Dtr']

        initVals = [double(68),0.014d,27.0d,17.0d]
        if ptr_valid(self.dfitparms) gt 0 then ptr_free,self.dfitparms
        self.dfitparms =  ptr_new([double(6.8e7),0.014d,27.0d,17.0d,double(6.8e7),0.014d,27.0d,17.0d,0.0]  )
        fields = lonarr(n_elements(deformationLabels))
        field_cb = lonarr(n_elements(deformationLabels))


        usub_b = widget_info(self.bbase,find_by_uname='DPARAMETERBASE')
        if widget_info(usub_b,/valid_id) gt 0 then widget_control,usub_b,/destroy


        usub_b = widget_base(self.bbase,/column,frame = 2,uname='DPARAMETERBASE')

        ;usub_b = widget_base(self.bbase,/column,frame = 2)
        label = widget_label(usub_b,value='Start Values for D(Q) Fitting')
    ;    label = widget_label(self.bbase,value='D(Q) Start Parameters')
        ;parmbase = widget_base(self.bbase,frame=2)
        fvtext = ['VARY','FIX']
        for i=0,n_elements(fields)-1 do begin
            sub_b1 = widget_base(usub_b,/col,frame = 2)
            dum_l = widget_label(sub_b1,value=deformationLabels[i]+': '+tooltip[i]);deformationLabels[i]);,label=deformationlabels[i])
            sub_b2 = widget_base(sub_b1,/row)
            field_cb[i] = widget_combobox(sub_b2,value = fvtext,uvalue = self)
            fields[i] = cw_field(sub_b2,$;self.bbase,$
                                    title = '',$;title=deformationLabels[i],$
                                    value=initVals[i],$
                                    uvalue=self,$
                                    /row,/floating,/return_events);,tooltip = tooltip[i])
        endfor

        if ptr_valid(self.dfittext) gt 0 then ptr_free,self.dfittext
        self.dfittext = ptr_new(fields)
        if ptr_valid(self.dfitfix) gt 0 then ptr_free,self.dfitfix
        self.dfitfix = ptr_new(field_cb)
    end;0 Deformation
    1:begin

;        ;NEED TO GET THE HANDOUT FROM DOBRIN WHICH WAS LEFT AT HOME TODAY.
;
;
;        dq3Labels = ['Damping frequency (MHz)',$
;                             'Amplitude',$
;                             'Mean Radius (A)',$
;                             'D trans (A^2/ns)']
;        tooltip = ['lambda2','<|a2|^2>','Ro','Dtr']
;        fvtext = ['VARY','FIX']
;
;        initVals = [double(68),0.014d,27.0d,17.0d]
;        if ptr_valid(self.dfitparms) gt 0 then ptr_free,self.dfitparms
;        self.dfitparms =  ptr_new([double(6.8e7),0.014d,27.0d,17.0d,double(6.8e7),0.014d,27.0d,17.0d,0.0]  )
;        fields = lonarr(n_elements(dq3Labels))
;        field_cb = lonarr(n_elements(dq3Labels))
;
;        usub_b = widget_info(self.bbase,find_by_uname='DPARAMETERBASE')
;        if widget_info(usub_b,/valid_id) gt 0 then widget_control,usub_b,/destroy
;
;
;        usub_b = widget_base(self.bbase,/column,frame = 2,uname='DPARAMETERBASE')
;        label = widget_label(usub_b,value='Start Values for D(Q) Fitting')
;        for i=0,n_elements(fields)-1 do begin
;            sub_b1 = widget_base(usub_b,/col,frame = 2)
;            dum_l = widget_label(sub_b1,value=deformationLabels[i]+': '+tooltip[i]);deformationLabels[i]);,label=deformationlabels[i])
;            sub_b2 = widget_base(sub_b1,/row)
;            field_cb[i] = widget_combobox(sub_b2,value = fvtext,uvalue = self)
;            fields[i] = cw_field(sub_b2,$;self.bbase,$
;                                    title = '',$;title=deformationLabels[i],$
;                                    value=initVals[i],$
;                                    uvalue=self,$
;                                    /row,/floating,/return_events);,tooltip = tooltip[i])
;        endfor
;
;        if ptr_valid(self.dfittext) gt 0 then ptr_free,self.dfittext
;        self.dfittext = ptr_new(fields)
;        if ptr_valid(self.dfitfix) gt 0 then ptr_free,self.dfitfix
;        self.dfitfix = ptr_new(field_cb)
    end;1
    else:begin
        print,'Unknown choice.  No changes made.'
    end
    endcase


;########################################





end;updateDparmwidgets

;###############################################################################
;
;NAME:
;        cwo_autographNSE::event
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_autographNSE::event,event

    e = event
;print,'cwo_autographNSE::event'
if ptr_valid(self.data) eq 0 then begin
    case event.id of
    self.obutton:begin
        ;print,'obutton'
        status = self->openFiles()
        if status eq 1 then self->draw
    end;obutton
    self.tlb:begin
        ;print,'tlb'
        self->resize,event
    end;tlb
    self.quitbutton:begin
        widget_control,self.tlb,/destroy
        ;widget_control,widget_info(self.tlb,/parent),/destroy
    end;quitbutton
    else:
    endcase
endif else begin
    case event.id of
    self.tlb:begin
        ;print,'tlb'
        self->resize,event
    end;tlb
    self.obutton:begin
        ;print,'obutton'
        status = self->openFiles()
        if status eq 1 then self->draw
    end;obutton
    self.writeDButton:begin
        ;print,'Write D(Q)'
        ;print,tag_names(*self.data)
        ;help,(*self.data).Q
        ;help,*((*self.data).pparms)[0]

        fn = dialog_pickfile(path = self.workdir,/write,/overwrite_prompt,title='Select D(Q) file for writing:')

        if fn[0] eq '' then begin
            void = dialog_message('No file selected.')
        endif else begin
            self.workdir = file_dirname(fn)
            openw,lun,fn[0],/get_lun

            format = '(e14.4 )'
            printf,lun,'# Q [1/A]             D(Q) [A^2/ns]      sD(Q)       '
            print,'# Q [1/A]             D(Q) [A^2/ns]      sD(Q)       '
            for i=0,n_elements((*self.data).Q)-1 do begin
                D = (*(((*self.data).pparms)[i]))[1]
                sD = (*(((*self.data).pparms)[i]))[3]
                printf,lun,string(((*self.data).Q)[i],format=format)+ $
                      string(D,format=format)+string(sD,format=format)
                print,string(((*self.data).Q)[i],format=format)+ $
                      string(D,format=format)+string(sD,format=format)
            endfor;i

            free_lun,lun
        endelse



    end;writeDButton
    self.writeDParmsButton:begin


        fn = dialog_pickfile(path = self.workdir,/write,/overwrite_prompt,title='Select D(Q) fit-parm file for writing:')

        if fn[0] eq '' then begin
            void = dialog_message('No file selected.')
        endif else begin
            self.workdir = file_dirname(fn)

            openw,lun,fn[0],/get_lun

                deformationLabels = ['Damping frequency (MHz) = ',$
                                     'Amplitude               = ',$
                                     'Mean Radius (A)         = ',$
                                     'D trans (A^2/ns)        = ']

                print,'Write D(Q) fit parms.'
                format = '(e12.4)'
                for i=0,3 do begin
                    printf,lun,deformationLabels[i]+string((*self.dfitparms)[i],format=format)+ $
                                           ' +/- ' +string((*self.dfitparms)[i+4],format=format)
                    print,deformationLabels[i]+string((*self.dfitparms)[i],format=format)+ $
                                      ' +/- ' +string((*self.dfitparms)[i+4],format=format)
                endfor
                printf,lun,'Chi-squared             = '+string((*self.dfitparms)[8],format=format)
                print,'Chi-squared             = '+string((*self.dfitparms)[8],format=format)
            free_lun,lun
        endelse

    end;writeDParmsButton
    self.quitbutton:begin
        widget_control,self.tlb,/destroy
        ;widget_control,widget_info(self.tlb,/parent),/destroy
    end;quitbutton
    self.ifcombo:begin
        ;IQT fit function choices
;        print,'ifcombo'
        widget_control,self.ifcombo,get_value=val
        selection = nse_comboindex(self.ifcombo)
        ;print,val[selection]
        ;NO draw HERE SINCE THIS ONLY AFFECTS DATA ON OPEN???
        ;THERE NEEDS TO BE A CALL TO A REFIT FUNCTION HERE AND
        ;D(Q) VALUES NEED TO BE CHANGED.
    end;ifcombo
    self.dfcombo:begin
        ;D(Q) fit function choices
        ;print,'dfcombo'
        widget_control,self.dfcombo,get_value=val
        selection = nse_comboindex(self.dfcombo)

        self->updateDparmwidgets,selection

        ;print,val[selection]
        self->draw
    end;dfcombo
    self.dfbutton:begin
        ;Fit D(Q) with parms in dfittext
;        print,'dfbutton'
        widget_control,self.dfcombo,get_value=val
        selection = nse_comboindex(self.dfcombo)
        print,'D(Q) fit function ='+val[selection]


        ;GET THE DATA FOR THE FIT
        data = *self.data
        ;x = data[*].Q
        x = [0.0d] & y = [0.0d] & sy = [0.0d]
        for i=0,n_elements(data)-1 do begin
            if data[i].masked eq 0 then begin
                x  = [x,data[i].Q]
                y  = [y, (*(data[i].pparms))[1]]
                sy = [sy,(*(data[i].pparms))[3]]
            endif
        endfor;i
        x = x[1:*] & y = y[1:*] & sy = sy[1:*]


        case selection of
        0:begin

            ;NEED VALUES FROM ALL TEXT WIDGETS
            start = dblarr(4)
            text = *self.dfittext
            for i=0,n_elements(text)-1 do begin
                widget_control,text[i],get_value=val
                if i eq 0 then val = val*1e6    ;CONVERT FROM MHz TO Hz
                start[i] = double(val)
            endfor
            ;print,start

            fixfit = *self.dfitfix
            fixed = intarr(n_elements(fixfit))
            for i=0,n_elements(text)-1 do begin
                fixed[i] = nse_comboindex(fixfit[i])
            endfor

            result = self->fitD(x,y,sy,functionIndex,start=start,fixed=fixed,deformation=1)
            ;print,result
            result[0] = result[0]/1e6   ;CONVERT FROM Hz TO MHz
            result[4] = result[4]/1e6
            if ptr_valid(self.dfitparms) gt 0 then ptr_free,self.dfitparms
            self.dfitparms = ptr_new(result)

            ;print,result
            ;print,*self.dfitparms
        end;0 Deformation
        1:begin
            ;NEED VALUES FROM ALL TEXT WIDGETS
            start = dblarr(4)
            text = *self.dfittext
            for i=0,n_elements(text)-1 do begin
                widget_control,text[i],get_value=val
                if i eq 0 then val = val*1e6    ;CONVERT FROM MHz TO Hz
                start[i] = double(val)
            endfor
            ;print,start

            fixfit = *self.dfitfix
            fixed = intarr(n_elements(fixfit))
            for i=0,n_elements(text)-1 do begin
                fixed[i] = nse_comboindex(fixfit[i])
            endfor

            result = self->fitD(x,y,sy,functionIndex,start=start,fixed=fixed,dq3=1)
            ;print,result
            result[0] = result[0]/1e6   ;CONVERT FROM Hz TO MHz
            result[4] = result[4]/1e6
            if ptr_valid(self.dfitparms) gt 0 then ptr_free,self.dfitparms
            self.dfitparms = ptr_new(result)

        end;1 DQ^3
        else:begin
            print,'Unknown Fit Selection'
        end
        endcase
        self->draw
    end;dfbutton
    self.iprintbutton:begin
        wset,self.idrawid
        resulti = tvrd(true=3)
        nse_ps_plotter,resulti,object=object
        obj_destroy,object
    end;iprintbutton
    self.dprintbutton:begin
        wset,self.ddrawid
        resultd = tvrd(true=3)
        nse_ps_plotter,resultd,object=object
        obj_destroy,object
    end;dprintbutton
    self.idraw:begin

        if ptr_valid(self.data) then self->zoom,event,self.idraw

    end;idraw
    self.ddraw:begin
        if ptr_valid(self.data) then self->zoom,event,self.ddraw

    end;ddraw
    else:begin
        text = *self.dfittext
        eid = where(event.id eq text)
        if eid ne -1 then begin ;EVENT CAME FROM A TEXT FIELD
;            widget_control,event.id,get_value=val
;            if eid eq 0 then val = val*1e6
;            (*self.dfitparms)[eid] = double(val)

            ;NEED VALUES FROM ALL TEXT WIDGETS
            for i=0,n_elements(text)-1 do begin
                widget_control,text[i],get_value=val
                ;if i eq 0 then val = val*1.0e6    ;CONVERT FROM MHz TO Hz
                (*self.dfitparms)[i] = double(val)
                (*self.dfitparms)[i+4] = double('nan')
            endfor

            self->draw
        endif else begin
            fixed = *self.dfitfix
            fid = where(event.id eq fixed)
            if fid ne -1 then begin
            endif else begin
                print,'Unsure of event source.'
            endelse
        endelse
    end
    endcase
endelse
    return,e
end;event
;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE_event
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
pro cwo_autographNSE_event,event

    ;print,'cwo_autographNSE_event_pro'

    widget_control,event.id,get_uvalue=o
    e = o->event(event)

end;event
;###############################################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE_event_pro
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
pro cwo_autographNSE_event_pro,event

    ;print,'cwo_autographNSE_event_pro'

    widget_control,event.id,get_uvalue=o
    e = o->event(event)

end;event
;###############################################################################
;
;NAME:
;        cwo_autographNSE_event_func
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_autographNSE_event_func,event

    print,'cwo_autographNSE_event_func'

    widget_control,event.id,get_uvalue=o
    e = o->event(event)

    return,e
end;event
;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE_realize
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_autographNSE_realize,val


    ;help,val
    ;print,val

    widget_control,val,get_uvalue=o

    ;help,o
    o->realize,val


end;cwo_autographNSE_realize
;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE::realize
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_autographNSE::realize,val

device,get_decomposed=dc
device,decomposed = 1

    print,'cwo_autographNSE::realize'

    widget_control,self.idraw,get_value=id
    self.idrawid = id
    widget_control,self.ddraw,get_value=id
    self.ddrawid = id

    white = 255L + 256L*(255L + 256L*255L)
    black = 0L

    x=findgen(100)
    y = cos(x/100*2*!PI)
    wset,self.ddrawpixid
    plot,x,y,xrange=[0,1],yrange = [0,1],color=black,background=white,/nodata,$
                ytitle='I(Q,t)/I(Q,0)',xtitle='t [ns]',$
                title = 'I(Q,t)/I(Q,0) v t'

    wset,self.ddrawid
    ;COPY IMAGE IN VIRTUAL WINDOW TO CURRENT WINDOW
    device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.ddrawpixid]


    y = sin(x/100*2*!PI)




    wset,self.idrawpixid
    plot,x,y,xrange=[0,0.5],yrange = [0,100],color=black,background=white,/nodata,$
                ytitle='D(Q) [A^2/ns]',xtitle='Q [1/A]',$
                title = 'D(Q) v Q'

    wset,self.idrawid
    ;COPY IMAGE IN VIRTUAL WINDOW TO CURRENT WINDOW
    device,copy = [0,0,!d.x_size,!d.y_size,0,0,self.idrawpixid]


device,decomposed = dc

end;realize
;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE::cleanup
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_autographNSE::cleanup

    print,'cwo_autographNSE::cleanup'

    if ptr_valid(self.ixptr) gt 0 then ptr_free,self.ixptr
    if ptr_valid(self.iyptr) gt 0 then ptr_free,self.iyptr
    if ptr_valid(self.dxptr) gt 0 then ptr_free,self.dxptr
    if ptr_valid(self.dyptr) gt 0 then ptr_free,self.dyptr

    if ptr_valid(self.dfittext) gt 0 then ptr_free,self.dfittext
    if ptr_valid(self.dfitfix) gt 0 then ptr_free,self.dfitfix
    if ptr_valid(self.dfitparms) gt 0 then ptr_free,self.dfitparms
    if ptr_valid(self.data) gt 0 then begin
        for i=0,n_elements(*self.data)-1 do begin
            s = (*self.data)[i]
            if ptr_valid(s.pt) ne 0 then ptr_free,s.pt
            if ptr_valid(s.pi) ne 0 then ptr_free,s.pi
            if ptr_valid(s.pparms) ne 0 then ptr_free,s.pparms
        endfor
        ptr_free,self.data
    endif

end;cleanup
;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE_cleanup
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_autographNSE_cleanup,id
    widget_control,id,get_uvalue=o
    obj_destroy,o

end;cwo_autographNSE_cleanup

;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE::init
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_autographNSE::init,parent,uvalue=uvalue,obj_ref=obj_ref,workdir=workdir

;    if keyword_set(parent) ne 0 then begin
;        self.tlb = widget_base(parent,xsize=700,ysize=600,/row,event_func='cwo_autographNSE_event',uvalue=uvalue)
;    endif else begin
;        if n_elements(leader) eq 1 then begin
            self.tlb = widget_base(group_leader = parent,/floating,xsize=700,ysize=600,/row,$
                                    $;event_func='cwo_autographNSE_event_func',$
                                    uvalue=self,mbar=bar,/tlb_size_events)
;        endif else begin
;            return,0
;        endelse
;    endelse

    obj_ref=self

    if n_elements(workdir) eq 0 then workdir = ''
    self.workdir = workdir

    self.bbase = widget_base(self.tlb,/column,kill_notify='cwo_autographNSE_cleanup',uvalue=self,frame=2)
    self.dbase = widget_base(self.tlb,/column)

    filemenu = widget_button(bar,/menu,value='File')
    self.obutton = widget_button(filemenu,value='Open IQT Files',uvalue=self)
                                    ;tooltip='Open IQT_X.XXXX.dat files.'


    self.quitbutton = widget_button(filemenu,value='Quit',uvalue=self)


    printmenu = widget_button(bar,/menu,value='Output')
    self.writeDButton = widget_button(printmenu,value='Write D v Q to File',uvalue=self)
    self.writeDParmsButton = widget_button(printmenu,value='Write D(Q) Parms to File',uvalue=self)
    self.iprintbutton = widget_button(printmenu,value='Print I(Q,t) plot',uvalue=self)
    self.dprintbutton = widget_button(printmenu,value='Print D(Q) plot',uvalue=self)


    dum = widget_label(self.bbase,value='Choose I(Q,t) Model')
;    self.ifcombo = widget_combobox(self.bbase,value=['I(Q,t)=exp(-D(Q)*Q^2*t)'],uvalue=self,editable=0)
    self.ifcombo = widget_combobox(self.bbase,value=['I(Q,t)=A*exp(-D(Q)*Q^2*t)','I(Q,t)=exp(-D(Q)*Q^2*t)'],uvalue=self,editable=0)
    dum = widget_label(self.bbase,value='Choose D(Q) Model')

    dmodelchoices = ['Deformation'];,'D(Q)*Q^3']
    self.dfcombo = widget_combobox(self.bbase,value=dmodelchoices,uvalue=self,editable=0)

    self.dfbutton = widget_button(self.bbase,value='Fit D(Q)',uvalue=self)

;071905
;ENCAPSULATE THE NEXT BLOCK FOR REDEFINITION FOR DIFFERENT MODELS.
    deformationLabels = ['Damping frequency (MHz)',$
                         'Amplitude',$
                         'Mean Radius (A)',$
                         'D trans (A^2/ns)']
    tooltip = ['lambda2','<|a2|^2>','Ro','Dtr']

    initVals = [double(68),0.014d,27.0d,17.0d]
    if ptr_valid(self.dfitparms) gt 0 then ptr_free,self.dfitparms
    self.dfitparms =  ptr_new([double(6.8e7),0.014d,27.0d,17.0d,double(6.8e7),0.014d,27.0d,17.0d,0.0]  )
    fields = lonarr(n_elements(deformationLabels))
    field_cb = lonarr(n_elements(deformationLabels))

    usub_b = widget_base(self.bbase,/column,frame = 2,uname='DPARAMETERBASE')

    label = widget_label(usub_b,value='Start Values for D(Q) Fitting')
;    label = widget_label(self.bbase,value='D(Q) Start Parameters')
    ;parmbase = widget_base(self.bbase,frame=2)
    fvtext = ['VARY','FIX']
    for i=0,n_elements(fields)-1 do begin
        sub_b1 = widget_base(usub_b,/col,frame = 2)
        dum_l = widget_label(sub_b1,value=deformationLabels[i]+': '+tooltip[i]);deformationLabels[i]);,label=deformationlabels[i])
        sub_b2 = widget_base(sub_b1,/row)
        field_cb[i] = widget_combobox(sub_b2,value = fvtext,uvalue = self)
        fields[i] = cw_field(sub_b2,$;self.bbase,$
                                title = '',$;title=deformationLabels[i],$
                                value=initVals[i],$
                                uvalue=self,$
                                /row,/floating,/return_events);,tooltip = tooltip[i])
    endfor

    if ptr_valid(self.dfittext) gt 0 then ptr_free,self.dfittext
    self.dfittext = ptr_new(fields)
    self.dfitfix = ptr_new(field_cb)

;########################################


    self.idraw = widget_draw(self.dbase,xsize=450,ysize=300,uvalue=self,/button_events,/motion_events)
    self.ddraw = widget_draw(self.dbase,xsize=450,ysize=300,uvalue=self,$
                                            notify_realize='cwo_autographNSE_realize',/button_events,/motion_events)

    window,/free,/pixmap,xsize=450,ysize=300
    self.idrawpixid = !d.window
    window,/free,/pixmap,xsize=450,ysize=300
    self.ddrawpixid = !d.window

print,'REALIZE'
    widget_control,self.tlb,/realize
print,'MANAGE'
    xmanager,'cwo_autographnse',self.tlb,/no_block;,event_handler='cwo_autographnse_event_pro'
print,'RETURN'


    return,1


end;init


;#######################################################
;###############################################################################
;
;NAME:
;        cwo_autographNSE__define
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_autographNSE__define,struct

    struct = {  cwo_autographnse,$
                    inherits myproperties,$
                    workdir:'',$
                    tlb:0L,$
                    bbase:0L,$
                    dbase:0L,$
                    ifcombo:0L,$            ;IQT fit function choices
                    obutton:0L,$            ;OPEN I(Q,t) data button
                    dfcombo:0L,$            ;D(Q) fit function choices
                    dloglincombo:0L,$
                    iloglincombo:0L,$
                    dfittext:ptr_new(),$    ;PARAMETER ENTRY TEXT WIDGETS
                    dfitfix:ptr_new(),$
                    dfbutton:0L,$           ;Fit D(Q) with parms in dfittext
                    iprintbutton:0L,$
                    dprintbutton:0L,$
                    quitbutton:0L,$
                    writedbutton:0L,$
                    writeDparmsbutton:0L,$
                    idraw:0L,$
                    idrawid:0L,$
                    idrawpixid:0L,$
                    ddraw:0L,$
                    ddrawid:0L, $
                    ddrawpixid:0L, $
                    ixptr:ptr_new(),$
                    iyptr:ptr_new(),$
                    dxptr:ptr_new(),$
                    dyptr:ptr_new(),$
                    mousex1:0.0,$
                    mousey1:0.0,$
                    mousex2:0.0,$
                    mousey2:0.0,$
                    dxmin:0.0,$
                    dxmax:0.0,$
                    dymin:0.0,$
                    dymax:0.0,$
                    ixmin:0.0,$
                    ixmax:0.0,$
                    iymin:0.0,$
                    iymax:0.0,$
                    mousepressed:0,$
                    dfitparms:ptr_new(),$
                    data:ptr_new() $
                }

end;define


