; NAME:      scroll_spectra_Masking
;PD Dr. Philip Tregenna-Piggott,
;Laboratory for Neutron Scattering,
;ETHZ and Paul-Scherrer Institute,
;CH-5232 Villigen PSI,
;Switzerland.
;
;Tel. :+41 56 310 54 05
;Fax. :+41 56 310 29 39
;Email:philip.tregenna@psi.ch
;
;Based on Programs written by:
;       Robert M. Dimeo, Ph.D.
;     NIST Center for Neutron Research
;       100 Bureau Drive
;     Gaithersburg, MD 20899
;       Phone: (301) 975-8135
;       E-mail: robert.dimeo@nist.gov
;       http://www.ncnr.nist.gov/staff/dimeo
;
; CATEGORY:
;
;       Focus Utilities
;
; CALLING SEQUENCE:
;
;      Scroll_Spectra_Masking
;
;
; INPUT FIELDS:
;
;
; EXAMPLES FOR POTENTIALS (must use IDL syntax as shown below):
;
;
; DISCLAIMER
;
;     This software is provided as is without any warranty whatsoever.
;     Permission to use, copy, modify, and distribute modified or
;     unmodified copies is granted, provided this disclaimer
;     is included unchanged.
;
; MODIFICATION HISTORY:
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMCancel,event
widget_control,event.top,get_uvalue = pState
detarr1d=(*pState).detarr1d
wherezero=where(detarr1d eq 0,count)
if count ne 0 then begin
detarr1d[wherezero]=1
(*pState).detarr1d=detarr1d
endif
widget_control,event.top,/destroy
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMAccept,event
widget_control,event.top,/destroy
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMReset,event
widget_control,event.top,get_uvalue = pState
detarr1d=(*pState).detarr1d
wherezero=where(detarr1d eq 0,count)
if count eq 0 then return
detarr1d[wherezero]=1
(*pState).detarr1d=detarr1d
widget_control,(*pState).omit1d,set_value = ''
widget_control,(*pState).remain1d,set_value = n_elements(detarr1d)
      ssmplot,event
      (*pState).mouse1d = 0B
      widget_control,(*pState).win1d,draw_motion_events = 0
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMReset2d,event
widget_control,event.top,get_uvalue = pState
detarr2d=(*pState).detarr2d
wherezero=where(detarr2d eq 0,count)
if count eq 0 then return
detarr2d[wherezero]=1
(*pState).detarr2d=detarr2d
widget_control,(*pState).omit2d,set_value = 'Detectors to be omitted {x,y}'
widget_control,(*pState).remain2d,set_value = n_elements(detarr2d)
widget_control,(*pState).Display2d,set_value = 0
widget_control,(*pState).grpSlider2dy,sensitive = 1
ssmplot2d,event
(*pState).mouse2d = 0B
widget_control,(*pState).win2d,draw_motion_events = 0
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro ssmdisplay,event
widget_control,event.top,get_uvalue = pState
ssmPlot,event
widget_control,(*pState).win1d,draw_motion_events = 0
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro ssmPlot,event
widget_control,event.top,get_uvalue = pState
data1d=(*pState).data1d
error1d=(*pState).error1d
x1d = (*pState).x1d
y1d = (*pState).y1d
detnum1d = (*pState).detnum1d
detarr1d = (*pState).detarr1d
widget_control,(*pState).grpSlider1d,get_value = val
widget_control,(*pState).twotheta,set_value = detnum1d[val-1]
;val=fix(val[0])
;help,detarr1d
;help,val
if detarr1d[val-1] eq 1 then widget_control,(*pState).Remove1d,set_value = 0
if detarr1d[val-1] eq 0 then widget_control,(*pState).Remove1d,set_value = 1
;if (size(*self.dataPtr))[0] eq 1 then val = 1
;if val gt (size(*self.dataPtr))[2] then return
;print,'val =',val
;print,'(size(*self.dataPtr))[2] =',(size(*self.dataPtr))[2]
;val = fix(val[0])
z = reform(data1d[*,val-1])
zerr = reform(error1d[*,val-1])
;print,'x1d =',x1d
;print,''
;print,'y1d =',y1d
;print,''
;print,'z =',z
;print,''
if (*pState).autoscale1d eq 1 then begin
  (*pState).xrange1d = [min(x1d),max(x1d)]
  dz = 0.1*(max(z)-min(z))
  (*pState).yrange1d = [min(z)-max(zerr)-dz, $
                 max(z)+max(zerr)+dz]
endif

wset,(*pState).winPix1d
plot,x1d,z,xrange = (*pState).xrange1d,yrange = (*pState).yrange1d, $
     xstyle = 1,ystyle = 1,xtitle = 'Time / microseconds', $
     ytitle = 'Intensity', title = 'Intensity vs. Time',linestyle = 0, $
     thick = 3.0
errplot,x1d,z-zerr,z+zerr,width = 0.0
wset,(*pState).winVis1d
device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix1d]
(*pState).pix=0
end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro ssmPlot2d,event
widget_control,event.top,get_uvalue = pState
data2d=(*pState).data2d
error2d=(*pState).error2d
tof2d=(*pState).tof2d
detarr2d = (*pState).detarr2d
widget_control,(*pState).grpSlider2dx,get_value = grpSlider2dx
widget_control,(*pState).grpSlider2dy,get_value = grpSlider2dy

widget_control,(*pState).display2d,get_value = display2d

if display2d eq 0 then begin
z = reform(data2d[*,grpSlider2dy,grpSlider2dx])
zerr = reform(Error2d[*,grpSlider2dy,grpSlider2dx])
    if detarr2d[grpSlider2dy,grpSlider2dx] eq 1 then begin
    widget_control,(*pState).Remove2d,set_value = 0
    endif else begin
    widget_control,(*pState).Remove2d,set_value = 1
    endelse
endif else begin
z = reform(data2d[*,*,grpSlider2dx])
z=total(z,2)
zerr = reform(Error2d[*,*,grpSlider2dx])
zerr = sqrt(total(zerr^2,2))
    if total(detarr2d[*,grpSlider2dx]) eq 0 then begin
    widget_control,(*pState).Remove2d,set_value = 1
    endif else begin
    widget_control,(*pState).Remove2d,set_value = 0
    endelse
endelse

if (*pState).autoscale2d eq 1 then begin
  (*pState).xrange2d = [min(tof2d),max(tof2d)]
  dz = 0.1*(max(z)-min(z))
  (*pState).yrange2d = [min(z)-max(zerr)-dz, $
                 max(z)+max(zerr)+dz]
endif

wset,(*pState).winPix2d
plot,tof2d,z,xrange = (*pState).xrange2d,yrange = (*pState).yrange2d, $
     xstyle = 1,ystyle = 1,xtitle = 'Time / microseconds', $
     ytitle = 'Intensity', title = 'Intensity vs. Time',linestyle = 0, $
     thick = 3.0
errplot,tof2d,z-zerr,z+zerr,width = 0.0
wset,(*pState).winVis2d
device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix2d]
(*pState).pix=1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro ssmdraw,event
widget_control,event.top,get_uvalue = pState

if (*pState).pix eq 1 then begin
ssmPlot,event
endif

case event.type of
0:  begin       ; button press
      (*pState).mouse1d = event.press
      if (*pState).mouse1d eq 4 then begin
        (*pState).autoscale1d = 1
        ssmPlot,event
      endif
      if (*pState).mouse1d eq 1 then begin
        (*pState).xbox1d[0] = event.x
        (*pState).ybox1d[0] = event.y
        wset,(*pState).winVis1d
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix1d]
        empty
        (*pState).autoscale1d = 0
        widget_control,(*pState).win1d,/draw_motion_events
      endif
    end
1:  begin    ; button release
     if (*pState).mouse1d eq 1 then begin
      xll = (*pState).xbox1d[0] < (*pState).xbox1d[1]
      yll = (*pState).ybox1d[0] < (*pState).ybox1d[1]
      w = abs((*pState).xbox1d[1] - (*pState).xbox1d[0])
      h = abs((*pState).ybox1d[1] - (*pState).ybox1d[0])
      xur = xll + w
      yur = yll + h
      ll = convert_coord(xll,yll,/device,/to_data)
      ur = convert_coord(xur,yur,/device,/to_data)
      (*pState).xrange1d = [ll[0],ur[0]]
      (*pState).yrange1d = [ll[1],ur[1]]
      ssmplot,event
      (*pState).mouse1d = 0B
      widget_control,(*pState).win1d,draw_motion_events = 0
     endif
     if (*pState).mouse1d eq 4 then begin
      ssmplot,event
      (*pState).mouse1d = 0B
      widget_control,(*pState).win1d,draw_motion_events = 0
     endif
    end
2:  begin    ; mouse motion
      if (*pState).mouse1d eq 1 then begin
       (*pState).xbox1d[1] = event.x
       (*pState).ybox1d[1] = event.y
       xc = [(*pState).xbox1d[0],event.x,event.x,$
             (*pState).xbox1d[0],$
             (*pState).xbox1d[0]]
       yc = [(*pState).ybox1d[0],(*pState).ybox1d[0],$
             event.y,event.y,$
             (*pState).ybox1d[0]]
       wset,(*pState).winVis1d
       device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix1d]
       plots,xc,yc,/device
       empty
      endif
    end
else:
endcase
return
end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro ssmdraw2d,event
widget_control,event.top,get_uvalue = pState

if (*pState).pix eq 0 then begin
ssmPlot2d,event
endif

case event.type of
0:  begin       ; button press
      (*pState).mouse2d = event.press
      if (*pState).mouse2d eq 4 then begin
        (*pState).autoscale2d = 1
        ssmPlot2d,event
      endif
      if (*pState).mouse2d eq 1 then begin
        (*pState).xbox2d[0] = event.x
        (*pState).ybox2d[0] = event.y
        wset,(*pState).winVis2d
        device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix2d]
        empty
        (*pState).autoscale2d = 0
        widget_control,(*pState).win2d,/draw_motion_events
      endif
    end
1:  begin    ; button release
     if (*pState).mouse2d eq 1 then begin
      xll = (*pState).xbox2d[0] < (*pState).xbox2d[1]
      yll = (*pState).ybox2d[0] < (*pState).ybox2d[1]
      w = abs((*pState).xbox2d[1] - (*pState).xbox2d[0])
      h = abs((*pState).ybox2d[1] - (*pState).ybox2d[0])
      xur = xll + w
      yur = yll + h
      ll = convert_coord(xll,yll,/device,/to_data)
      ur = convert_coord(xur,yur,/device,/to_data)
      (*pState).xrange2d = [ll[0],ur[0]]
      (*pState).yrange2d = [ll[1],ur[1]]
      ssmplot2d,event
      (*pState).mouse2d = 0B
      widget_control,(*pState).win2d,draw_motion_events = 0
     endif
     if (*pState).mouse2d eq 4 then begin
      ssmplot2d,event
      (*pState).mouse2d = 0B
      widget_control,(*pState).win2d,draw_motion_events = 0
     endif
    end
2:  begin    ; mouse motion
      if (*pState).mouse2d eq 1 then begin
       (*pState).xbox2d[1] = event.x
       (*pState).ybox2d[1] = event.y
       xc = [(*pState).xbox2d[0],event.x,event.x,$
             (*pState).xbox2d[0],$
             (*pState).xbox2d[0]]
       yc = [(*pState).ybox2d[0],(*pState).ybox2d[0],$
             event.y,event.y,$
             (*pState).ybox2d[0]]
       wset,(*pState).winVis2d
       device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix2d]
       plots,xc,yc,/device
       empty
      endif
    end
else:
endcase
return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMremove_detectors,event
widget_control,event.top,get_uvalue = pState
detarr1d=(*pState).detarr1d
widget_control,(*pState).grpSlider1d,get_value = grpSlider1d
grpSlider1d-=1
widget_control,(*pState).Remove1d,get_value = Remove1d
;print,'Remove1d =',Remove1d
Remove1d=Remove1d[0]
if Remove1d eq 1 then detarr1d[grpSlider1d]=0
if Remove1d eq 0 then detarr1d[grpSlider1d]=1
(*pState).detarr1d=detarr1d
wherezero=where(detarr1d eq 0,count)
num=n_elements(detarr1d)-count
if num eq 0 then begin
SSMReset,event
return
endif
if count ne 0 then begin
;print,wherezero
wherezero+=1
;print,wherezero
n=n_elements(wherezero)
omit1d=string(wherezero[0])
for i=1,n-1 do begin
omit1d=[omit1d,','+strtrim(string(wherezero[i]),2)]
endfor
;help,omit1d
widget_control,(*pState).omit1d,set_value = strtrim(omit1d,2)
endif
widget_control,(*pState).remain1d,set_value = num
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMremove_detectors2d,event
widget_control,event.top,get_uvalue = pState
detarr2d=(*pState).detarr2d
widget_control,(*pState).display2d,get_value = display2d
widget_control,(*pState).grpSlider2dx,get_value = grpSlider2dx
widget_control,(*pState).grpSlider2dy,get_value = grpSlider2dy
widget_control,(*pState).Remove2d,get_value = Remove2d
Remove2d=Remove2d[0]
IF display2d eq 0 THEN BEGIN
    if Remove2d eq 1 then begin
    detarr2d[grpSlider2dy,grpSlider2dx]=0
    endif else begin
    detarr2d[grpSlider2dy,grpSlider2dx]=1
    endelse
ENDIF ELSE BEGIN
    if Remove2d eq 1 then begin
    detarr2d[*,grpSlider2dx]=0
    endif else begin
    detarr2d[*,grpSlider2dx]=1
    endelse
ENDELSE
(*pState).detarr2d=detarr2d
wherezero=where(detarr2d eq 0,count)
num=n_elements(detarr2d)-count
if num eq 0 then begin
SSMReset2d,event
return
endif
if count ne 0 then begin
ydim=(*pState).dimensions2d[2]
omitted=strarr(count+1)
omitted[0]='Detectors to be omitted {x,y}'
for k = 1, count do begin
xcoord=wherezero[k-1]/ydim
ycoord=wherezero[k-1]-xcoord*ydim
omitted[k]='{'+strtrim(string(xcoord),2)+','+strtrim(string(ycoord),2)+'}'
endfor
widget_control,(*pState).omit2d,set_value = omitted
(*pState).detarr2d=detarr2d
left=n_elements(detarr2d)-count
widget_control,(*pState).remain2d,set_value = left
endif
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMLoadPrevious,event
widget_control,event.top,get_uvalue = pState
file='BadDetParameters1D.sav'
fileout= (*pState).workDir+file
    if file_test(fileout) eq 0 then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'The file: '+fileout+' has not been found')
    return
    endif
    restore, fileout
if (n_elements(detarr1d) eq 0) then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'The required information is not contained in this file')
return
endif
(*pState).detarr1d=detarr1d
wherezero=where(detarr1d eq 0,count)
num=n_elements(detarr1d)-count
if num eq 0 then begin
SSMReset,event
return
endif
if count ne 0 then begin
;print,wherezero
wherezero+=1
;print,wherezero
n=n_elements(wherezero)
omit=string(wherezero[0])
for i=1,n-1 do begin
omit=[omit,','+strtrim(string(wherezero[i]),2)]
endfor
;help,omit
widget_control,(*pState).omit1d,set_value = strtrim(omit,2)
endif
widget_control,(*pState).remain1d,set_value = num
SSMplot,event
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMLoadPrevious2d,event
widget_control,event.top,get_uvalue = pState
file='BadDetParameters2d.sav'
fileout= (*pState).workDir+file
    if file_test(fileout) eq 0 then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'The file: '+fileout+' has not been found')
    return
    endif
    restore, fileout
if (n_elements(BadDet2d) eq 0) then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'The required information is not contained in this file')
return
endif
if ((tag_names(BadDet2d))[0] ne 'DETARR2D') then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'The required information is not contained in this file')
return
endif
detarr2d=BadDet2d.detarr2d
dimensions2d=(*pState).dimensions2d
if ((size(detarr2d))[1] ne dimensions2d[2]) or ((size(detarr2d))[2] ne dimensions2d[3]) then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'Incompatible array dimensions2d')
return
endif
wherezero=where(detarr2d eq 0,count)
left=n_elements(detarr2d)-count
if left eq 0 then begin
SSMReset2d,event
endif
(*pState).detarr2d=detarr2d
widget_control,(*pState).omit2d,set_value = BadDet2d.omitted
widget_control,(*pState).remain2d,set_value = left
SSMplot2d,event
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMLoadFile,event
widget_control,event.top,get_uvalue = pState
workDir=(*pState).workDir
    filename=dialog_pickfile(path=workDir,$
      file='BadDetParameters1d.sav',/read,filter="*.sav",/fix_filter)
if n_elements(filename) eq 0 then return
if filename eq '' then return
    restore, filename
if (n_elements(detarr1d) eq 0) then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'The required information is not contained in this file')
return
endif
(*pState).detarr1d=detarr1d
wherezero=where(detarr1d eq 0,count)
num=n_elements(detarr1d)-count
if num eq 0 then begin
SSMReset,event
return
endif
if count ne 0 then begin
;print,wherezero
wherezero+=1
;print,wherezero
n=n_elements(wherezero)
omit=string(wherezero[0])
for i=1,n-1 do begin
omit=[omit,','+strtrim(string(wherezero[i]),2)]
endfor
;help,omit
widget_control,(*pState).omit1d,set_value = strtrim(omit,2)
endif
widget_control,(*pState).remain1d,set_value = num
SSMplot,event
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMLoadFile2d,event
widget_control,event.top,get_uvalue = pState
workDir=(*pState).workDir
    filename=dialog_pickfile(path=workDir,$
      file='BadDetParameters2d.sav',/read,filter="*.sav",/fix_filter)
if n_elements(filename) eq 0 then return
if filename eq '' then return
    restore, filename
if (n_elements(BadDet2d) eq 0) then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'The required information is not contained in this file')
return
endif
if ((tag_names(BadDet2d))[0] ne 'DETARR2D') then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'The required information is not contained in this file')
return
endif
detarr2d=BadDet2d.detarr2d
dimensions2d=(*pState).dimensions2d
if ((size(detarr2d))[1] ne dimensions2d[2]) or ((size(detarr2d))[2] ne dimensions2d[3]) then begin
    void=dialog_message(dialog_parent=event.top,/error, $
    'Incompatible array dimensions2d')
return
endif
wherezero=where(detarr2d eq 0,count)
left=n_elements(detarr2d)-count
if left eq 0 then begin
SSMReset2d,event
endif
(*pState).detarr2d=detarr2d
widget_control,(*pState).omit2d,set_value = BadDet2d.omitted
widget_control,(*pState).remain2d,set_value = left
SSMplot2d,event
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMSaveFile,event
widget_control,event.top,get_uvalue = pState
detarr1d=(*pState).detarr1d
workDir=(*pState).workDir
    filename=dialog_pickfile(path=workDir,$
      file='BadDetParameters1d.sav',/write,filter="*.sav",/fix_filter)
save,filename=filename,detarr1d
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMSaveFile2d,event
widget_control,event.top,get_uvalue = pState
workDir=(*pState).workDir
detarr2d=(*pState).detarr2d
widget_control,(*pState).omit2d,get_value = omitted
BadDet2d={detarr2d:detarr2d,omitted:omitted}
    filename=dialog_pickfile(path=workDir,$
      file='BadDetParameters2d.sav',/write,filter="*.sav",/fix_filter)
save,filename=filename,BadDet2d
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro Display2dTypes,event
widget_control,event.top,get_uvalue = pState
widget_control,(*pState).Display2d,get_value = Display2d
if Display2d eq 0 then begin
widget_control,(*pState).grpSlider2dy,sensitive = 1
endif else begin
widget_control,(*pState).grpSlider2dy,sensitive = 0
endelse
ssmPlot2d,event
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro options,event
widget_control,event.top,get_uvalue = pState
dimensions2d=(*pState).dimensions2d
dimensions1d=(*pState).dimensions1d
if dimensions2d[0] eq 0 then widget_control,(*pState).opt_tab,SET_TAB_CURRENT = 0
if dimensions1d[0] eq 0 then widget_control,(*pState).opt_tab,SET_TAB_CURRENT = 1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro SSMSpikes,event
widget_control,event.top,get_uvalue = pState
detarr2d=(*pState).detarr2d
dimensions2d=(*pState).dimensions2d
SpikeFactor=(*pState).SpikeFactor
ydim=dimensions2d[2]
xdim=dimensions2d[3]
data2d=(*pState).data2d
SumData2d=total(data2d,1)
temp=fltarr(4)
;timestart=systime(1,/seconds)
for i = 0, ydim-1 do begin
    for j = 0, xdim- 1 do begin
       if i eq 0 then temp[0]=-1
       if i eq (ydim-1) then temp[1]=-1
       if j eq 0 then temp[2]=-1
       if j eq (xdim-1) then temp[3]=-1
if temp[0] ne -1 then temp[0] = SumData2d[i-1,j]
if temp[1] ne -1 then temp[1] = SumData2d[i+1,j]
if temp[2] ne -1 then temp[2] = SumData2d[i,j-1]
if temp[3] ne -1 then temp[3] = SumData2d[i,j+1]
newtemp=temp[where(temp ne -1)]
av=(moment(newtemp))[0]
if av lt 0.0 then av = 1.0
if SumData2d[i,j] gt av*SpikeFactor then detarr2d[i,j] = 0
temp[*]=0.0
    endfor
endfor
(*pState).detarr2d=detarr2d
wherezero= where(detarr2d eq 0,count)
if count ne 0 then begin
ydim=(*pState).dimensions2d[2]
omitted=strarr(count+1)
omitted[0]='Detectors to be omitted {x,y}'
for k = 1, count do begin
xcoord=wherezero[k-1]/ydim
ycoord=wherezero[k-1]-xcoord*ydim
omitted[k]='{'+strtrim(string(xcoord),2)+','+strtrim(string(ycoord),2)+'}'
endfor
widget_control,(*pState).omit2d,set_value = omitted
(*pState).detarr2d=detarr2d
left=n_elements(detarr2d)-count
widget_control,(*pState).remain2d,set_value = left
endif
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro ssmEvents,event
uname=widget_info(event.id,/uname)
case uname of
'Remove_Types':    $
begin
SSMremove_detectors,event
end
'SSM_Reset':    $
begin
SSMReset,event
end
'SSM_Reset2d':    $
begin
SSMReset2d,event
end
'SSM_LoadPrevious':    $
begin
SSMLoadPrevious,event
end
'SSM_LoadPrevious2d':    $
begin
SSMLoadPrevious2d,event
end
'SSM_LoadFile':    $
begin
SSMLoadFile,event
end
'SSM_LoadFile2d':    $
begin
SSMLoadFile2d,event
end
'SSM_SaveFile':    $
begin
SSMSaveFile,event
end
'SSM_SaveFile2d':    $
begin
SSMSaveFile2d,event
end
'Display2d_Types':    $
begin
Display2dTypes,event
end
'ssmdisplay2dy':    $
begin
ssmPlot2d,event
end
'ssmdisplay2dx':    $
begin
ssmPlot2d,event
end
'Remove_Types2d':    $
begin
SSMremove_detectors2d,event
end
'opttab':    $
begin
options,event
end
'Spikes':    $
begin
SSMSpikes,event
end
else:
endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function Scroll_Spectra_Masking,data1d,error1d,detnum1d,x1d,data2d,Error2d,tof2d,SpikeFactor, $
       group_leader=group_leader,WorkDir=Workdir
if n_elements(group_leader) eq 0 then begin
  tlb = widget_base(/col,title = 'Scroll Spectra Masking Utility')
endif else begin
  tlb = widget_base(group_leader = group_leader, /col,/modal, $
        title = 'Scroll Spectra Masking Utility')
endelse
nx=n_elements(x1d)
xlo=min(x1d, max = xhi)
  xrange1d = [xlo,xhi]
dimensions1d=size(data1d)
if dimensions1d[0] eq 0 then begin
z = 0.0
zerr = 0.0
dz = 0.0
ylo=0.0
yhi= 0.0
y1d=0.0
ndet=2
  yrange1d = [ylo,yhi]
detarr1d=0
endif else begin
z = data1d[*,0]
zerr = error1d[*,0]
dz = 0.1*(max(z)-min(z))
ylo=min(z)-max(zerr)-dz
yhi= max(z)+max(zerr)+dz
ndet=n_elements(detnum1d)
y1d=detnum1d[0]
  yrange1d = [ylo,yhi]
detarr1d=1+intarr(n_elements(detnum1d))
endelse
dimensions2d=size(data2d)
if dimensions2d[0] eq 0 then begin
detarr2d=0
num2d=0
ydim=2
xdim=2
xlo2d=0.0
xhi2d=0.0
ylo2d=0.0
yhi2d=0.0
endif else begin
;num2d=size(SumData2d,/dimension)
ydim=dimensions2d[2]
xdim=dimensions2d[3]
num2d=ydim*xdim
detarr2d=intarr(ydim,xdim)+1
xlo2d=min(tof2d)
xhi2d=max(tof2d)
z2d=data2d[*,0,0]
dz2d = 0.1*(max(z2d)-min(z2d))
ylo2d=min(z2d)-max(Error2d[*,0,0])-dz2d
yhi2d=max(z2d)+max(Error2d[*,0,0])+dz2d
endelse



opt_tab=widget_tab(tlb,uname='opttab')
Base1d = widget_base(opt_tab,/row,title='Conventional Detector Bank(s)')

base1d_left = widget_base(base1d,/col,/align_center)

Remove_Types = ['Mark For Deletion']
;range=1
Remove1d = cw_bgroup(base1d_left,Remove_Types,/col,/nonexclusive,$
           set_value = 0,/return_index, /frame,$
           uname = 'Remove_Types')


omit1d = cw_field(base1d_left,/col,title = 'Detectors to be Omitted',/string, $
      /noedit)
remain1d = cw_field(base1d_left,/col,value=ndet,title = 'Number of Detectors Remaining',/string, $
      /noedit)
twotheta = cw_field(base1d_left,/col,value=detnum1d[0],title = 'Two*Theta For Current Group',/string, $
      /noedit)
;base1d_left1 = widget_base(base1d_left,/align_center,/col)
;base1d_left1 = widget_base(base1d_left,/align_center)
void = widget_button(base1d_left,value = 'Load Previous',uname = 'SSM_LoadPrevious')
void = widget_button(base1d_left,value = 'Load From File',uname = 'SSM_LoadFile')
void = widget_button(base1d_left,value = 'Save Selection',uname = 'SSM_SaveFile')
void = widget_button(base1d_left,value = 'Reset',uname = 'SSM_Reset')



;xsize = 500 & ysize = 400
GoldenRatio=0.5*(1.0+sqrt(5.0))
;xsize = 500 & ysize = 400
xsize = 700 & ysize = xsize/GoldenRatio

plotBase1d = widget_base(Base1d,/col)

win1d = widget_draw(plotBase1d,xsize = xsize,ysize = ysize, $
           /button_events,event_pro = 'ssmdraw')
grpSlider1d = widget_slider(plotBase1d,minimum = 1,maximum = ndet, $
          event_pro = 'ssmdisplay')


geom = widget_info(Base1d,/geometry)
newysize = geom.ysize
widget_control,win1d,draw_ysize = newysize


Base2d = widget_base(opt_tab,/row,title = '2d Detector')

base2d_left = widget_base(base2d,/col,/align_center)

Remove2d = cw_bgroup(base2d_left,Remove_Types,/col,/nonexclusive,$
           set_value = 0,/return_index, /frame,$
           uname = 'Remove_Types2d')

void = widget_button(base2d_left,value = 'Remove Spikes',uname = 'Spikes')


omit2d=widget_Droplist(base2d_left,value='Detectors to be omitted {x,y}', $
              /dynamic_resize,uname='omit2d' )


remain2d = cw_field(base2d_left,/col,value=num2d,title = 'Number of Detectors Remaining',/string, $
      /noedit)

Display2d_Types = ['Each Pixel', $
                  'Sum Over Y']
Display2d = cw_bgroup(base2d_left,Display2d_Types,/col,/exclusive,$
           set_value = 0,/return_index, /frame,label_top ='Display', $
           uname = 'Display2d_Types')

grpSlider2dy = widget_slider(base2d_left,minimum = 0,maximum = ydim-1, title = 'y co-ordinate', $
         uname = 'ssmdisplay2dy')

void = widget_button(base2d_left,value = 'Load Previous',uname = 'SSM_LoadPrevious2d')
void = widget_button(base2d_left,value = 'Load From File',uname = 'SSM_LoadFile2d')
void = widget_button(base2d_left,value = 'Save Selection',uname = 'SSM_SaveFile2d')
void = widget_button(base2d_left,value = 'Reset',uname = 'SSM_Reset2d')

xsize2d = 700 & ysize2d = xsize2d/GoldenRatio

plotBase2d = widget_base(Base2d,/col)

win2d = widget_draw(plotBase2d,xsize = xsize2d,ysize = ysize2d,/button_events, $
      event_pro = 'ssmdraw2d')

grpSlider2dx = widget_slider(plotBase2d,minimum = 0,maximum = xdim-1, title = 'x co-ordinate', $
         uname = 'ssmdisplay2dx')


geom2d = widget_info(Base2d,/geometry)
newysize2d = geom2d.ysize
widget_control,win2d,draw_ysize = newysize2d

courier_hugefont = get_font_name(/huge, /courier)

void = widget_button(tlb,value = 'Cancel',event_pro = 'SSMCancel',font=courier_hugefont)
;base1d_left3 = widget_base(base1d_left,/align_center)
void = widget_button(tlb,value = 'Accept',event_pro = 'SSMAccept',font=courier_hugefont)



widget_control,tlb,/realize


widget_control,win1d,get_value = winVis1d
window,/free,/pixmap,xsize = xsize,ysize = newysize
winPix1d = !d.window

widget_control,win2d,get_value = winVis2d
window,/free,/pixmap,xsize = xsize2d,ysize = newysize2d
winPix2d = !d.window



state = {winVis1d:winVis1d, $
         winPix1d:winPix1d, $
         winVis2d:winVis2d, $
         winPix2d:winPix2d, $
         autoscale1d:1, $
         autoscale2d:1, $
         xbox1d:[xlo,xhi], $
         ybox1d:[ylo,yhi], $
         xbox2d:[xlo2d,xhi2d], $
         ybox2d:[ylo2d,yhi2d], $
         mouse1d:0B, $
         mouse2d:0B, $
         win1d:win1d, $
         win2d:win2d, $
         xrange1d:[xlo,xhi], $
         yrange1d:[ylo,yhi], $
         xrange2d:[xlo2d,xhi2d], $
         yrange2d:[ylo2d,yhi2d], $
         data1d:data1d, $
         error1d:error1d, $
         data2d:data2d, $
         error2d:error2d, $
         x1d:x1d, $
         y1d:y1d, $
         detarr1d:detarr1d, $
         detarr2d:detarr2d, $
         twotheta:twotheta, $
         detnum1d:detnum1d, $
         base1d:base1d, $
         omit1d:omit1d, $
         remain1d:remain1d, $
         omit2d:omit2d, $
         remain2d:remain2d, $
         grpSlider1d:grpSlider1d, $
         Remove1d:Remove1d, $
         Remove2d:Remove2d, $
         Workdir:Workdir, $
         dimensions1d:dimensions1d, $
         dimensions2d:dimensions2d, $
         Display2d:Display2d, $
         grpSlider2dy:grpSlider2dy, $
         grpSlider2dx:grpSlider2dx, $
         tof2d:tof2d, $
         opt_tab:opt_tab, $
         SpikeFactor:SpikeFactor, $
         pix:1}



pState = ptr_new(state,/no_copy)
widget_control,tlb,set_uvalue = pState

;print,x1d
;print,''
;print,z

if dimensions1d[0] ne 0 then begin
wset,(*pState).winPix1d
plot,x1d,z,xrange = (*pState).xrange1d,yrange = (*pState).yrange1d, $
     xstyle = 1,ystyle = 1,xtitle = 'Time / microseconds', $
     ytitle = 'Intensity', title = 'Intensity vs. Time',linestyle = 0, $
     thick = 3.0
errplot,x1d,z-zerr,z+zerr,width = 0.0
wset,(*pState).winVis1d
device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix1d]
endif else begin
widget_control,(*pState).opt_tab,SET_TAB_CURRENT = 1
endelse

if dimensions2d[0] ne 0 then begin
wset,(*pState).winPix2d
z2d=reform(data2d[*,0,0])
zerr2d=reform(Error2d[*,0,0])
plot,tof2d,z2d,xrange = (*pState).xrange2d,yrange = (*pState).yrange2d, $
     xstyle = 1,ystyle = 1,xtitle = 'Time / microseconds', $
     ytitle = 'Intensity', title = 'Intensity vs. Time',linestyle = 0, $
     thick = 3.0
errplot,tof2d,z2d-zerr2d,z2d+zerr2d,width = 0.0
wset,(*pState).winVis2d
device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pState).winPix2d]
endif

xmanager,'Scroll_Spectra_Masking',tlb,event_handler = 'ssmEvents'

detarr1d=(*pState).detarr1d
detarr2d=(*pState).detarr2d
detarr={detarr1d:detarr1d,detarr2d:detarr2d}
wdelete,(*pState).winPix1d
ptr_free,pState
return,detarr
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;