PRO PQLPROFILE,DAT,XSCALE,length=length,vertical=vertical,average=average,$ title=title,xtitle=xtitle,ytitle=ytitle,datatitle=datatitle,$ subtitle=subtitle,$ xformat=xformat,yformat=yformat,$ x_size=x_size,y_size=y_size,$ outside=outside,cursor=cursor,$ event=ev,P_reg=P_reg,change=change,$ GROUP=GROUP,reset=reset,kill=kill,active=active common PQLPROFILE,DZ,lastwhich,lastdata,textw On_Error,2 IF !DEBUG ne 0 THEN On_Error,0 IF Keyword_SET(reset) THEN BEGIN DZ = 0 return EndIF ; ; Check if we have enough information ; sz = Size(DAT) Ndims = sz(0) IF (N_elements(DAT) le 1 or Ndims gt 2) and NOT Keyword_SET(change) THEN $ message,'Data must be either 1D or 2D array' IF Ndims eq 1 THEN BEGIN IF N_elements(XSCALE) ne 0 and N_elements(XSCALE) ne sz(1) THEN $ message,'XSCALE must have same number of elements as DATA' EndIF IF N_elements(ev) gt 0 THEN BEGIN P_reg = pfind(ev,found) IF NOT found THEN return END ELSE IF N_elements(P_reg) eq 1 THEN BEGIN prestore,P_reg IF since_version('5.3') then begin ev = {Widget_DRAW} ev.x = !P.clip(0)+1 ev.y = !P.clip(0)+1 END ELSE begin command = ' ev = {Widget_DRAW, ID:0L, TOP:0L, HANDLER:0L, TYPE:0, ' + $ 'X:fix(!P.clip(0)+1), Y:fix(!P.clip(0)+1), press:0b, release:0b' IF since_version('5') THEN command = command + ', clicks:0L}' ELSE $ command = command + '}' test = execute(command) ENDELSE END ELSE message,'Need to have either event or Plot Region' ; ; We now have reasonable event coordinates, and we have the P_region ; ; Defaults ; IF N_elements(length) eq 0 THEN length=20 IF N_elements(vertical) eq 0 THEN vertical=0B IF N_elements(average) eq 0 THEN average=1 IF N_elements(title) eq 0 THEN title='' IF N_elements(xtitle) eq 0 THEN xtitle='' IF N_elements(ytitle) eq 0 THEN ytitle='' IF N_elements(datatitle) eq 0 THEN datatitle='' IF N_elements(subtitle) eq 0 THEN subtitle='' IF N_elements(xformat) eq 0 THEN xformat='' IF N_elements(yformat) eq 0 THEN yformat='' IF N_elements(x_size) eq 0 THEN BEGIN IF N_elements(Y_size) eq 1 THEN x_size = 2*y_size $ ELSE x_size = 500 EndIF IF N_elements(y_size) eq 0 THEN y_size = fix(x_size/sqrt(2)) IF Ndims eq 1 THEN BEGIN IF N_elements(XSCALE) eq 0 THEN BEGIN span = pconvert(P_reg,sz(1),/pix,/to_dat)$ -pconvert(P_reg,0,/pix,/to_dat) XSCALE = findgen(sz(1))/(sz(1)-1)*span $ + pconvert(P_reg,0,/pix,/to_data) END END ELSE XSCALE=0 IF N_elements(DAT) gt 0 THEN DATA = { X:XSCALE, D:DAT} ; If no Pqlprofile has been invoked before, we need to init common block DZ ; (and the structure type) IF DATATYPE(DZ) ne 'STC' THEN BEGIN info = {QLPINFO,$ base : 0L, $ ; Top level base init_ev : ev, $ ; (dummy) initial event P_reg : -1, $ ; The source Plot Region mbase : 0L, $ ; Uvalue used to store data. ndims : Ndims, $ ; Data dimensionality length : length, $ lenmax : 0, $ fit : 0, $ ; Fit switch average : average, $ vertical : vertical, $ len_text : 0L, $ avg_txtID: 0L, $ x : EV.X, $ ; Center of source line/box y : EV.Y, $ ; Center of source line/box ac : EV.X, $ ; Actual center Plotreg : -1, $ ; Plot region for the profile title : title, $ xtitle : xtitle, $ ytitle : ytitle, $ dtitle : datatitle, $ subtitle : subtitle, $ xformat : xformat, $ yformat : yformat, $ polyx : [0,0], $ ; polyy : [0,0] $ } dz = [info] lastwhich = -1 END ; ; Is there already a widget corresponding to the call? ; active = 0 which = (where(dz(*).P_reg eq P_reg,count))(0) ; ; If so, just update it.. ; IF count gt 0 THEN BEGIN IF Keyword_SET(kill) THEN BEGIN Widget_CONTROL,dz(which).base,/destroy return EndIF active = 1 IF lastwhich ne which or Keyword_SET(change) THEN BEGIN IF N_elements(data) eq 1 THEN BEGIN lastwhich = which lastdata = data END ELSE BEGIN Widget_CONTROL,dz(which).mbase,Get_UVALUE=lastdata lastwhich = which END IF Keyword_SET(change) THEN BEGIN Widget_CONTROL,dz(which).mbase,Set_UVALUE=lastdata IF Keyword_SET(title) THEN dz(which).title=title IF Keyword_SET(xtitle) THEN dz(which).xtitle=xtitle IF Keyword_SET(ytitle) THEN dz(which).ytitle=ytitle IF Keyword_SET(datatitle) THEN dz(which).dtitle=datatitle IF Keyword_SET(subtitle) THEN dz(which).subtitle=subtitle IF Keyword_SET(xformat) THEN dz(which).xformat=xformat IF Keyword_SET(yformat) THEN dz(which).yformat=yformat END END pqlp_plot,ev,which,change=change return END ; ; If this was just notification of change - don't make new widget. ; IF Keyword_SET(change) or Keyword_SET(kill) THEN return ; ; Else: Create new widget to show data.. ; which = N_elements(dz) dz = [dz,{QLPINFO}] ; ; Determine where to place top level base.... ; p = tlb_place(x_size+20,y_size+50,pwindow=P_reg) xpos = p(0) ypos = p(1) ; ; Creation of widget base/other widgets.... ; PQLPROFILEbase = Widget_BASE(TITLE = "PQLPROFILE",/column,$ GROUP_LEADER=ev.top,Uvalue=which,space=0,$ xoffset=xpos,yoffset=ypos) qlp = PQLPROFILEBASE ;shorthand qcol = Widget_BASE(qlp,/column,/frame) cmouse_s = {CMOUSE_S, btext:'', mtext:'', uvalue:'', avail:0} menu=[{CMOUSE_S,"Zoom out", "Zoom out (display more pixels)","ZOUT",7+8},$ {CMOUSE_S,"Recenter", "Recenter on a pixel","RECENTER",7},$ {CMOUSE_S,"Zoom in", "Zoom in (display fewer pixels)","ZIN",7},$ ; Paal {CMOUSE_S,"Select line", "Select line","LINE",7+8} ] cmouse,qlp,qcol,menu ; label1 = Widget_LABEL(qcol,value='Mouse button action:') ; rowbase0 = Widget_BASE(qcol,/row) ; label2 = Widget_LABEL(rowbase0,value='1: Recenter',/frame) ; label2 = Widget_LABEL(rowbase0,value='2: No action',/frame) ; label2 = Widget_LABEL(rowbase0,value='3: No action',/frame) rowbase = Widget_BASE(qlp,/row) b = Widget_BUTTON(rowbase,value='Done',Uvalue='DONE') XPdMenu,['"Plot" {','"Plot to file" PSFILE','"Print" PSPRINT','}'],rowbase inner = Widget_BASE(qlp) b = Widget_BUTTON(rowbase,value='Save',Uvalue='SAVE') b = Widget_BUTTON(rowbase,value='Help',Uvalue='HELP') dummy = {PSELECT_S, btext:'', mtext:'', uvalue:'', flags:0} menu=[{PSELECT_S, ' None', 'No line fit','NOFIT',0},$ {PSELECT_S, ' Gaussian', 'Gaussian profile', 'IGAUSS',0}] dummy = cw_pselect(rowbase,'Line fit:',menu) ; ; XPdMenu,['"Line Fitting" {','"Gaussian Fit" GAUSS',$ ; '"Amoebe" AMOEBE','"Other" OTHER','}'],rowbase ; plotwin = Widget_DRAW(inner,xsize=x_size,ysize=y_size,uvalue='DRAW',$ /button_events,/motion_events) ; ; Length slider ; The appearance of slider widgets differs from 3.0 to 3.X ; sub_version = float(!version.release) IF sub_version gt 3.0 THEN slide_offs=40 $ ELSE slide_offs=0 len_base = Widget_BASE(qlp,/frame) len_text_base = Widget_BASE(len_base,/row) dummy = Widget_LABEL(len_text_base,value='Length of profile: ') len_text_id = Widget_TEXT(len_text_base,value=trim(length),$ xsize=12,ysize=1) dummy = Widget_LABEL(len_text_base,value=' pixels') lenmax = max(sz(1:sz(0))) length = (length>3)<lenmax dummy = Widget_SLIDER(len_base,min=3,max=lenmax,xsize=x_size,$ yoffset=slide_offs,$ uvalue='LENGTH',/suppress,/drag,value=length) textbase = WIDGET_BASE(qlp,/column) textw = WIDGET_TEXT(textbase,xsize = 80,ysize = 1,/frame) ; ; 2D DATA ONLY: ; IF Ndims eq 2 THEN BEGIN ; ; Orientation ; xmenu,['Horizontal','Vertical'],qlp,/exclusive,/row,$ UVALUE=['HORIZONTAL','VERTICAL'], buttons=buttons Widget_CONTROL,buttons(0),/set_button ; ; AVERAGE slider (only for 2D data) ; avgmax = max(sz(1:2)) npix_base = Widget_BASE(qlp,/frame) avg_txt_base = Widget_BASE(npix_base,/row) dummy = Widget_LABEL(avg_txt_base,value='Average over ') avg_txtID = Widget_TEXT(avg_txt_base,value=trim(average),$ xsize=5,ysize=1) dummy = Widget_LABEL(avg_txt_base,value=' pixels') dummy = Widget_SLIDER(npix_base,min=1,max=avgmax,xsize=x_size,$ yoffset=slide_offs,$ $ uvalue='AVERAGE',/suppress,/drag,value=average) END ELSE avg_txtID = 0L ; ; That's the setup, now show ourselves... ; Widget_CONTROL, PQLPROFILEbase, /REALIZE ; ; And store vital information in the information block. ; Widget_CONTROL,plotwin,Get_VALUE=qlpwnd SetWindow,qlpwnd Plotreg = pstore(1,0,0,/clean) dz(which).P_reg = P_reg dz(which).x = ev.x ; Center of source box dz(which).y = ev.y dz(which).ndims = Ndims dz(which).length = length dz(which).lenmax = lenmax dz(which).vertical = vertical dz(which).average = average dz(which).title = title dz(which).xtitle= xtitle dz(which).ytitle= ytitle dz(which).dtitle=datatitle dz(which).xformat=xformat dz(which).yformat=yformat dz(which).plotreg = plotreg dz(which).base = PQLPROFILEbase dz(which).mbase=rowbase dz(which).len_text =len_text_id dz(which).avg_txtID=avg_txtID dz(which).polyx(*)=-1 Widget_CONTROL,dz(which).mbase,Set_UVALUE=DATA lastdata = DATA lastwhich = which ; ; Sign up ; Xmanager, "PQLPROFILE", PQLPROFILEbase, CLEANUP='pqlp_cleanup' ; ; Update display.. ; pqlp_plot,ev,which END