; $Id: cwo_mergeiqttodave.pro,v 1.8 2007/05/02 21:34:42 kneller Exp $
;###############################################################################
;
;
;CLASS NAME:
;    cwo_mergeIQTToDave
;
;PURPOSE:
;
;CATEGORY:
;
;
;SUPERCLASSES:
;    inherits idl_container
;
;
;METHODS:
;    cwo_mergeIQTToDave_event
;    cwo_mergeIQTToDave::event
;    cwo_mergeIQTToDave::displayHelp
;    cwo_mergeIQTToDave::quit
;    cwo_mergeIQTToDave::selectFiles
;    cwo_mergeIQTToDave::mergeFiles
;    cwo_mergeIQTToDave::mergeData
;    cwo_mergeIQTToDave::getExt
;    cwo_mergeIQTToDave::writeDave
;    cwo_mergeIQTToDave::sortIQT
;    cwo_mergeIQTToDave::fillIn_Ts
;    cwo_mergeIQTToDave::readIQTFile
;    cwo_mergeIQTToDave::readDaveFile
;    cwo_mergeIQTToDave::readDatFile
;    cwo_mergeIQTToDave::draw
;    cwo_mergeIQTToDave::setproperty
;    cwo_mergeIQTToDave::getproperty
;    cwo_mergeIQTToDave_cleanup
;    cwo_mergeIQTToDave::cleanup
;    cwo_mergeIQTToDave::init
;    cwo_mergeIQTToDave__define
;    cwo_mergeIQTToDave
;
;
; AUTHOR:
; Larry Kneller
; NIST Center for Neutron Research
; 100 Bureau Drive, Gaithersburg, MD 20899
; United States
; kneller@nist.gov  301-975-8839
; Fri Oct 27 20:53:03 2006
;
; 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.
;
;###############################################################################



;
;WHY CAN I NOT GET AN EVENT _FUNCTION_ TO WORK??????????????????????
;
;THE REASON WAS THAT XMANAGER FORCES EVENT HANDLER TO BE PROCEDURE.
;A CALL TO WIDGET_CONTROL,WID,EVENT_FUNC='EVENT_FUNC_NAME' OVERRIDES THIS.
;
;
;function cwo_mergeIQTToDave_event,event
;    widget_control,event.handler,get_uvalue=obj
;    return,obj->event(event)
;end;cwo_mergeIQTToDave_event
;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave_event
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_mergeIQTToDave_event,event
    widget_control,event.handler,get_uvalue=obj

    ret = obj->event(event)

    ;DO I HAVE TO PASS THIS EVENT DIRECTLY TO THE PARENT SOMEHOW??????
end;cwo_mergeIQTToDave_event
;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::event
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_mergeIQTToDave::event,event

    case event.id of
    self.quitbutton:begin
        self->quit
    end;quitbutton
    self.filebutton:begin
        self->selectFiles
    end;filebutton
    self.mergebutton:begin
        self->mergeFiles
    end;mergebutton
    self.helpbutton:begin
        self->displayHelp
    end;helpbutton
    else:
    endcase

    return,-1
end;cwo_mergeIQTToDave_event

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

    b = widget_base(group_leader=self.tlb,title='Help on Merge I(Q,t)',/floating,/col)
    text = widget_text(b,xsize=60,ysize = 10)
    s = ['Merge I(Q,t): Written by Larry Kneller',$
         'Use this to merge multiple different I(Q,t) files into a single',$
         'DAVE file to facilitate analysis using PAN.',$
         '',$
         'NOTE: At this point, the program relies on the user to select multiple',$
         'files with the same values for all Fourier Time arrays.' $
         ]

    widget_control,text,set_value=s

    widget_control,b,/realize


end;cwo_mergeIQTToDave::displayHelp


;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::quit
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_mergeIQTToDave::quit
    widget_control,self.tlb,/destroy
end;cwo_mergeIQTToDave::quit

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

    fn = dialog_pickfile(title='Select I(Q,t) Files:',$
                         /multi,$
                         path=self.datadir,$
                         filter = ['*.dave','*.dat','*.iqt'])

    if fn[0] ne '' then begin
        widget_control,self.filelist,set_value=file_basename(fn),set_uvalue=fn

        self.datadir = file_dirname(fn[0])
        self.workdir = file_dirname(fn[0])
    endif

end;cwo_mergeIQTToDave::selectFiles

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

    widget_control,self.filelist,get_uvalue=uval


    selection = widget_info(self.filelist,/list_select)

    ;help,uval
    ;print,selection

    if selection[0] ne -1 then begin
        sel = uval[selection]
        self->mergeData,sel
    endif else begin
        void = dialog_message('Please select files from the list.')
    endelse
end;cwo_mergeIQTToDave::mergeFiles

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


    catch,es
    if es ne 0 then begin
        print,'Error occurred!'
        print,tag_names(!error_state)
        print,'!error_state=',!error_state
        print,'!error_state.msg=',!error_state.msg
        void = dialog_message('Error occurred below cwo_mergeIQTToDave::mergeData')
        print,'line 271'
        catch,/cancel
        return
    endif

    ;NOW OPEN FILES AND READ EACH I(Q,t) INTO A STRUCTURE:
    ;   s = {Q:Q,t:t,I:I,sI:sI}
    ;
    ;THEN CREATE A 2d DATA SET WITH
    ;
    ;   I[nQ,nt],sI[nQ,nT]
    ;   IF nt VARIES, THEN FILL IN I AT UNIQUE t'S WITH NaN'S --- WHAT ABOUT ROUNDING FOR Q,t????
    ;                                                             SEE WHAT WAS DONE IN ooEcho.
    ;
    ; THEN WRITE A DAVE FILE.

;#####################################
;
;   CHECK FOR MEMORY LEAK IN THIS PROCEDURE!!!!!!!!!!!!
;
;#####################################

    nfn = n_elements(fn)
    ;help,self.pdata
    ;help,*self.pdata
    ;help,/heap,/brief
    if ptr_valid(self.pdata) then begin
        if n_elements(*self.pdata) ne 0 then begin
            ;print,'test'
            ;help,*self.pdata
            ;print,'test'
            ;help,(*self.pdata)[0]
            ;print,'test'
            if ptr_valid((*self.pdata)[0]) then ptr_free,(*self.pdata)
            ;print,'test'
        endif

        ptr_free,self.pdata
    endif

    ;self.pdata = ptr_new(nfn)

    pdata = ptrarr(1)
;help,/traceback
    ;print,nfn
    for i=0,nfn-1 do begin
;        print,i,n_elements(pdata)
        ;print,file_test(fn[i]),' ',fn[i]

;        iext = strpos(fn[i],'.',/reverse_search)
;        len  = strlen(fn[i])
;        ext  = strmid(fn[i],iext+1,len-iext)


;NOW NEED TO ADD TWO THINGS:

;READER FOR OTHER ASCII FILE
;SORT BY Q AND WRITE DAVE




;012307
;NEED TO IMPROVE THIS SO THAT IT SORTS OUT THE TIMES AND Q's
;
;THE ISSUE WITH TIMES MEANS THAT I HAVE TO FIGURE OUT WHICH TIMES
;ARE IN THE FILES, SORT THEM, AND FILL IN THE MISSING TIMES.
;
;THERE IS PROBABLY AN ISSUE WITH THE TIMES IN THAT THEY ARE
;VERY SIMILAR FOR MANY SETS BUT NOT IDENTICAL.
;
;FIRST TRY TO GET t's AND Q's

;AT THIS STAGE THERE IS NO NEED FOR SORTING SINCE THERE ARE SORTIQT AND REMOVENAN PROCEDURES
;BELOW.  SORTIQT SEEMS LIKE A NATURAL PLACE TO PUT THE FUNCTIONALITY TO FILL IN THE MISSING
;T'S AND Q'S.
        ext = self->getExt(fn[i])
        if strcmp(ext,'dat',/fold_case) gt 0 then begin
            str = self->readDatFile(fn[i])

            sz = size(str,/type)
            if size(str,/type) eq 8 then begin;stregex(out,'struct',/fold,/bool) ne 0 then begin
                pdata = [pdata,ptr_new(str)]
            endif
;help,str
;print,tag_names(str)
;print,(str.t)
;print,(str.q)
        endif;dat
        if strcmp(ext,'iqt',/fold_case) gt 0 then begin
            str = self->readIQTFile(fn[i])

            sz = size(str,/type)
            if size(str,/type) eq 8 then begin;stregex(out,'struct',/fold,/bool) ne 0 then begin
                pdata = [pdata,ptr_new(str)]
            endif


        endif;iqt
        if strcmp(ext,'dave',/fold_case) gt 0 then begin
            str = self->readDaveFile(fn[i])
            ;print,n_elements(str)
            for j=0,n_elements(str)-1 do begin
                pdata = [pdata,ptr_new(str[j])]
            endfor;j
        endif;dave
        if strcmp(ext,'iqt',/fold_case) eq 0 and $
            strcmp(ext,'dave',/fold_case) eq 0 and $
             strcmp(ext,'dat',/fold_case) eq 0 then begin
            str = self->readIQTFile(fn[i])

            sz = size(str,/type)
            if size(str,/type) eq 8 then begin;stregex(out,'struct',/fold,/bool) ne 0 then begin
                pdata = [pdata,ptr_new(str)]
            endif

        endif;iqt
    endfor;i


    p = pdata[0]

    if n_elements(pdata) gt 1 then begin
        pdata = pdata[1:*]

        self->sortIQT,pdata
        self->removeNaNs,pdata
        self->fillIn_Ts,pdata

        self.pdata = ptr_new(pdata)

        q = dblarr(n_elements(pdata))

        for j=0,n_elements(pdata)-1 do begin
            q[j] = (*(pdata[j])).q
        endfor;j

        t = (*(pdata[0])).t

        I  = dblarr(n_elements(t),n_elements(pdata))
        sI = dblarr(n_elements(t),n_elements(pdata))


        for j=0,n_elements(q)-1 do begin
            I[*,j] = (*(pdata[j])).I
            sI[*,j] = (*(pdata[j])).sI
        endfor;j

        self->writedave,q,t,i,si

    endif else begin
        void = dialog_message('No I(Q,t) data found.')
    endelse

end;cwo_mergeIQTToDave::mergeFiles

;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::getExt
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_mergeIQTToDave::getExt,s
        iext = strpos(s,'.',/reverse_search)

        if iext ne -1 then begin
            len  = strlen(s)
            ext  = strmid(s,iext+1,len-iext)
        endif else begin
            ext = ''
        endelse
        return,ext

end;cwo_mergeIQTToDave::getExt


;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::writeDave
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_mergeIQTToDave::writeDave,q,t,i,si


    filename = dialog_pickfile(/write,$
                    title='I(Q,t) DAVE export file:',$
                    path=self.workdir,$
                    /overwrite_prompt,$
                    filter = '*.dave')


    if filename eq '' then begin
        void = dialog_message('NO FILE SELECTED.')
        filename = 'CombinedIQT.dave'
    endif else begin

        ext = self->getExt(filename)
        if strcmp(ext,'dave',/fold_case) le 0 then begin
            filename = filename + '.dave'
        endif

        instrument = 'NSE'
        qty = i
        dqty = si
        x = t
        y = q

        ;CREATE PAN_MASK
        pan_mask = long(0*i)

        ;CHECK FOR NON FINITE VALUES AND IF PRESENT REPLACE WITH FILLER
        whnefinite = where(finite(qty) eq 0,nefinitecount)
        if nefinitecount ne 0 then begin
            ;print,'NON FINITE VALUES PRESENT'
            ;pan_mask[whnefinite] = 0   ;DEFAULT VALUES ARE ZERO, SO THIS STEP IS NOT NECESSARY.
            qty[whnefinite] = -9999
            dqty[whnefinite] = 9999
        endif

        ;DEFINE MASK IN TERMS OF POSITIONS OF FILLER VALUES IN QTY.
        whnefiller = where(qty ne -9999,nefillercount)
        if nefillercount ne 0 then begin
            pan_mask[whnefiller] = 1
        endif

        ;print,where(finite(qty) eq 0)

        xlabel = 'time (s)'
        ylabel = 'Q '
        xunits = 'time:s'
        yunits = 'wavevector:A-1'
        histlabel = 'I (arbitrary units)'
        histunits = ''

        ;print,'cwo_mergeIQTToDave::writeDave:   bits2bytes(pan_mask)=',bits2bytes(pan_mask)
        specificstr = {NSE_FILLER:-9999,PAN_MASK:ptr_new(bits2bytes(pan_mask))}
        treatment = 'NSE data reduced'
        ret = create_dave_pointer( $
                    daveptr,              $
                    instrument = instrument,    $
                    qty = qty,            $
                    qtunits = histunits,       $
                    qtlabel = histlabel,       $
                    err = dqty,            $
                    xvals = x,          $
                    xtype = 'point',          $
                    xunits = xunits,         $
                    xlabel = xlabel,         $
                    yvals = y,          $
                    ytype = 'point',          $
                    yunits = yunits,         $
                    ylabel = ylabel,         $
                    specificstr = specificstr,  $
                    treatment = treatment)

        save,filename=filename,daveptr
    endelse

end;writeDave



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

;    ngood = 0
    goodarr = intarr(n_elements(p))

    for j=0,n_elements(p)-1 do begin
        arr = (*(p[j])).I
        npts = n_elements(arr)
        if total(finite(arr,/nan)) lt npts then goodarr[j] = 1
    endfor;j

    if total(goodarr) lt n_elements(p) then begin
        if total(goodarr) gt 0 then begin


            ;050207
            ;AT THIS POINT IT LOOKS LIKE THE ALL-NAN GROUPS SHOULD BE REMOVED AUTOMATICALLY.
            ;IS THIS THE CASE?????
            pnew = ptrarr(fix(total(goodarr)))
            inew = 0
            for j=0,n_elements(p)-1 do begin
                if goodarr[j] eq 1 then begin
                    pnew[inew] = ptr_new(*(p[j]))
                    inew++
                endif
            endfor;j

            for k=0,n_elements(p)-1 do begin
                ptr_free,p[k]
            endfor;k

            p = pnew

        endif else begin
            void = dialog_message('All data NaN!!!')
        endelse

    endif


end;cwo_mergeIQTToDave::removeNaNs

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

    swapped = 0

    for j=0,n_elements(p)-1 do begin
        swapped = 0
        for i=0,n_elements(p)-2 do begin
            if (*(p[i])).q gt (*(p[i+1])).q then begin

                temp = p[i]
                p[i] = p[i+1]
                p[i+1] = temp
                swapped = 1
            endif
        endfor;i
        if swapped eq 0 then begin
            break
        endif
    endfor;j

end;cwo_mergeIQTToDave::sortIQT

;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::fillIn_Ts
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_mergeIQTToDave::fillIn_Ts,p
    on_error,2
    print,"FILL IN T's HERE.  Update 4% Tolerance here if updated in ooEcho."


;THERE ARE A FEW PROBLEMS AT THIS POINT.
;
;1) THE T's ARE REPORTED IN ns AND s DEPENDING ON FILETYPE  --- SO CHANGE ALL TO ns.
;2) SIMILAR T's COULD BE EFFECTIVELY THE SAME VALUE.
;       WHAT IS THE TOLERANCE?              ---- LOOK AT CODE FOR CHOOSING RES POINTS.  --- Currently 4%.
;       HOW DO I CHOOSE THE "RIGHT" ONE?
;
;3) WHAT VALUES SHOULD I PLACE IN THE FIELDS? 0.0, Inf?
;



;FIRST COPY THE INPUT DATA SETS
pnew = ptrarr(n_elements(p))
for i = 0,n_elements(p)-1 do begin
    d = (*p[i])
    order = sort(d.t)
    d.t = d.t[order]
    d.i = d.i[order]
    d.si = d.si[order]

    pnew[i] = ptr_new(d)
endfor;i




;SECOND GET ALL THE UNIQUE TIMES (WITHIN THE 4% MARGIN USED ELSEWHERE IN NSE REDUCTION)
    allT = [-1.0]
    for i=0,n_elements(p)-1 do begin
        ti = (*p[i]).t
        if min(ti) gt 1.0e-5 then ti = (1.0e-9)*ti
        if i eq 0 then begin
            allT = [ti]
        endif else begin

            for j=0,n_elements(ti)-1 do begin
                wh = where(abs((ti[j] - allT)/ti[j]) lt 0.04,count)
                if count eq 0 then allT = [allT,ti[j]]
            endfor;j
        endelse
    endfor;i


    format = '(' + strtrim(string(n_elements(allT)),2) + 'g15.7)'
    print,'allT = '
    print,allT,format = format

;THIRD FILL IN ALL THE NEW DATA SETS WITH THE EXTRA T'S

    iqtReplacement = -9999;abs(!values.d_nan);double('NaN');0.0
    siqtReplacement = 9999;abs(!values.d_nan);double('NaN');double('Infinity')
    for i=0,n_elements(pnew)-1 do begin
        t = (*pnew[i]).t
        iqt = (*pnew[i]).i
        siqt = (*pnew[i]).si

;THE ALGORITHM IN THIS SECTION SHOULD BE USEFUL ELSEWHERE AS WELL.

        for j=0,n_elements(allT)-1 do begin
            wh = where(abs((allT[j] - t)/allT[j]) lt 0.04,count)
            if count eq 0 then begin

                ;INSERT A TIME
                if allT[j] lt t[0] then begin

                    ;INSERT AT BEGINNING OF ARRAY
                    t = [allT[j],t]
                    iqt = [iqtReplacement,iqt]
                    siqt = [siqtReplacement,siqt]
                endif else begin
                    if allT[j] gt t[0] and allt[j] lt t[n_elements(t)-1] then begin

                        ;FIGURE OUT WHERE THE NEW TIME BELONGS AND PLACE IT
                        whless = where(t lt allT[j],count)
;;;;;print,'whless=',whless
;;;;;print,'n_elements(t)=',n_elements(t)
;;;;;print,'allt[j]=',allt[j]
;;;;;print,'t=',t
                        if count gt 0 then begin
                            t = [t[0:max(whless)],allT[j],t[max(whless)+1:*]]
                            iqt = [iqt[0:max(whless)],iqtReplacement,iqt[max(whless)+1:*]]
                            siqt = [siqt[0:max(whless)],siqtReplacement,siqt[max(whless)+1:*]]

                        endif
                    endif else begin
                        ;APPEND TO END OF ARRAY
                        t = [t,allT[j]]
                        iqt = [iqt,iqtReplacement]
                        siqt = [siqt,siqtReplacement]
                    endelse
                endelse
            endif;count ne 0
        endfor;j
;;;;;print,'First i=',i
        ;CONVERT ALL TIMES TO UNITS OF ns.
        for it=0,n_elements(t)-1 do begin
            if t[it] gt 1.0e-5 then t[it] = t[it]*1.0e-9
        endfor;i
        dnew = {Q:(*pnew[i]).q,t:t,i:iqt,si:siqt}
;;;;;        help,(*pnew[i]).q,t,iqt,siqt
        if ptr_valid(pnew[i]) gt 0 then ptr_free,pnew[i]
        pnew[i] = ptr_new(dnew)
;;;;;print,'Second i=',i
    endfor;i

    for i=0,n_elements(p)-1 do begin
        if ptr_valid(p[i]) then ptr_free,p[i]
    endfor;i

    p = pnew

;;;;;    print,(*pnew[0])
    ;help,/traceback

end;cwo_mergeIQTToDave::fillIn_Ts



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


    catch,es
    if es ne 0 then begin
        s = -1
        catch,/cancel
        return,s
    endif

    nlines = file_lines(fn)
    s = strarr(nlines)
    openr,lun,fn,/get_lun
    readf,lun,s
    free_lun,lun

    segs = strsplit(s[2],/extract)
    nq = (n_elements(segs)-1)/2
    nt = nlines - 2
    Q  = dblarr(nq)
    t  = dblarr(nt)
    I  = dblarr(nt,nq)
    sI = dblarr(nt,nq)

    segs = strsplit(s[0],/extract)

    for j=2,nlines-1 do begin

        segs = strsplit(s[j],/extract)

        t[j-2] = double(segs[0])
        for k=0,nq-1 do begin
            I[j-2,k]  = double(segs[k+1])
            sI[j-2,k] = double(segs[k+2])
        endfor;k
    endfor;j

    s = {t:t,q:q[0],I:I[*,0],sI:sI[*,0]}
    str = replicate(s,n_elements(q))

    for j=0,n_elements(q)-1 do begin
        str[j].t  = t
        str[j].q  = q[j]
        str[j].I  = I[*,j]
        str[j].sI = sI[*,j]
    endfor;j
    s = {t:t,q:q[0],I:I[*,0],sI:sI[*,0]}
    str = replicate(s,n_elements(q))

    for j=0,n_elements(q)-1 do begin
        str[j].t  = t
        str[j].q  = q[j]
        str[j].I  = I[*,j]
        str[j].sI = sI[*,j]
    endfor;j

    return,s

end;cwo_mergeIQTToDave::readIQTFile



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

	restore, fn, restored_objects=someObjects
	heap_free,someObjects


    t  = (*((*(*davePtr).datastrptr).commonstr).histptr).x
    q  = (*((*(*davePtr).datastrptr).commonstr).histptr).y
    I  = (*((*(*davePtr).datastrptr).commonstr).histptr).qty
    sI = (*((*(*davePtr).datastrptr).commonstr).histptr).err


	free_all_ptrs,davePtr

    s = {t:t,q:q[0],I:I[*,0],sI:sI[*,0]}
    str = replicate(s,n_elements(q))

    for j=0,n_elements(q)-1 do begin
        str[j].t  = t
        str[j].q  = q[j]
        str[j].I  = I[*,j]
        str[j].sI = sI[*,j]
    endfor;j

    return,str
end;cwo_mergeIQTToDave::readDaveFile
;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::readDatFile
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_mergeIQTToDave::readDatFile,fn

    s = 0
    catch,es
    if es ne 0 then begin
        s = -1
        catch,/cancel
        return,s
    endif

    nlines = file_lines(fn)

    in = strarr(nlines)
    openr,lun,fn,/get_lun
    readf,lun,in
    free_lun,lun

    Q  = 0.0
    t  = dblarr(nlines-1)
    I  = dblarr(nlines-1)
    sI = dblarr(nlines-1)
    for j=1,nlines-1 do begin
        ;print,in[j]
        segs = strsplit(in[j],/extract)
        ;print,j,nlines,n_elements(segs),in[j]
        Q     = double(segs[0])
        t[j-1]  = double(segs[1])
        I[j-1]  = double(segs[2])
        sI[j-1] = double(segs[3])
    endfor;j

    s = {Q:Q,t:t,I:I,sI:sI}

    return,s
end;cwo_mergeIQTToDave::readDatFile

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

;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::setproperty
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_mergeIQTToDave::setproperty,_Extra=extra
    if n_elements(tlb) ne 0 then self.tlb =tlb
end;cwo_mergeIQTToDave::setproperty


;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::getproperty
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_mergeIQTToDave::getproperty,tlb=tlb,_Extra=extra

    if arg_present(tlb) ne 0 then tlb = self.tlb
end;cwo_mergeIQTToDave::getproperty

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

;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::cleanup
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro cwo_mergeIQTToDave::cleanup
    print,'cwo_mergeIQTToDave::cleanup'
    if ptr_valid(self.pdata) then begin
        if ptr_valid((*self.pdata)[0]) then ptr_free,(*self.pdata)
        ptr_free,self.pdata
    endif
end;cwo_mergeIQTToDave::cleanup

;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave::init
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_mergeIQTToDave::init,parent,xsize=xsize,ysize=ysize,tlb=tlb,group_leader=group_leader,$
                                  datadir=datadir,workdir=workdir,_Extra=extra

    nobj = checkforobjinstance('cwo_mergeIQTToDave',ref=ref)
    if nobj gt 1 then begin
        help,ref[0],output=out0
        help,self,output=outself

        if strcmp(out0,outself,/fold_case) eq 0 then begin
            ref[0]->getproperty,tlb=tlb
        endif else begin
            ref[1]->getproperty,tlb=tlb
        endelse

        widget_control,tlb,/show
        return,0
    endif else begin

        if n_elements(parent) eq 0 then parent = -1L

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

        if parent ne -1L then begin
            tlb = widget_base(parent,title='Merge I(Q,t) to DAVE',group_leader=parent,/row,uvalue=self,$
                                kill_notify='cwo_mergeIQTToDave_cleanup')
        endif else begin
            tlb = widget_base(title='Merge I(Q,t) to DAVE',group_leader=group_leader,mbar=bar,/row,uvalue=self,$
                                kill_notify='cwo_mergeIQTToDave_cleanup')
        endelse

        llb1 = widget_base(tlb,/col)
        llb2 = widget_base(tlb,/col)

        value=['No Files Selected']
        self.filelist = widget_list(llb1,xsize=60,ysize = 15,$
                                    value=value,$
                                    uvalue=value,$
                                    /multiple)

        if n_elements(bar) ne 0 then begin
            filemenu = widget_button(bar,value='File',/menu)
            self.quitbutton = widget_button(filemenu,value='Quit')
        endif else begin
            self.quitbutton = widget_button(llb2,value='Quit')
        endelse

        self.fileButton  = Widget_button(llb2,value='Select Files to Merge',$
                                              tooltip='Choose files on system for possible merge')
        self.mergeButton = Widget_button(llb2,value='Merge Files',$
                                              tooltip='Merge selected files into single DAVE file')
        self.helpButton  = widget_button(llb2,value='Help',$
                                              tooltip='Help on Merge I(Q,t)')


        widget_control,tlb,/realize
        xmanager,'cwo_mergeIQTToDave',tlb,/no_block;,event_handler='cwo_mergeIQTToDave_event'
        centertlb,tlb

        self.tlb = tlb

        return,1
    endelse
end;init

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

    class = {cwo_mergeIQTToDave,$
                inherits idl_container,$
                pdata:ptr_new(),$
                datadir:'',$
                workdir:'',$
                tlb:0L,$
                filelist:0L,$
                quitbutton:0L,$
                filebutton:0L,$
                mergebutton:0L,$
                helpbutton:0L}

end;cwo_mergeIQTToDave__define



;###############################################################################
;
;NAME:
;        cwo_mergeIQTToDave
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function cwo_mergeIQTToDave,parent,obj=obj,xsize=xsize,ysize=ysize,group_leader=group_leader,_Extra=extra

    if n_elements(parent) eq 0 then parent = -1L
    obj = obj_new('cwo_mergeIQTToDave',parent,xsize=ysize,ysize=ysize,tlb=tlb,group_leader=group_leader,$
                                      _Extra=extra)

    return,tlb

end;cwo_mergeIQTToDave
