source: sans/SANSReduction/trunk/Put in User Procedures/SANS_Reduction_v5.00/RawWindowHook.ipf @ 260

Last change on this file since 260 was 260, checked in by srkline, 15 years ago

Changed the IgorVersion? pragma to = 6.0. No turning back now.

File size: 14.3 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.0
4
5//*****************************
6// Vers. 1.2 092101
7//
8// hook function and associated procedures that interact with the user
9// and the SANS_Data window
10// -displays pixel counts
11// - displays Q, qx, qy values
12// - displays q axes and pixel axes
13//
14// - of course, displays the detector image, w/ nice colors, legend, sliders to adjust color mapping
15// and a control bar to let the user adjust scaling, do averaging...
16//
17// allows the display default to be set to log scaling
18//*****************************
19
20
21//main procedure for display of SANS data files
22//uses "hook" functions to interact witht the user to get live cursor readout
23//based on the IGOR Pro Demo experiment- "SimpleDemoHook" - see the original
24//demo for more details of implementation
25//
26Function fRawWindowHook()
27        //globals for the main data display window are kept in root:myGlobals
28        Variable/G root:myGlobals:gXPos=0
29        Variable/G root:myGlobals:gYPos=0
30        Variable/G root:myGlobals:gQX=0
31        Variable/G root:myGlobals:gQY=0
32        Variable/G root:myGlobals:gQQ=0
33        Variable/G root:myGlobals:gNCounts=0
34        String/G root:myGlobals:gCurDispFile = "default string"
35        String/G root:myGlobals:gCurTitle = ""
36        Make/O/N=2 root:myGlobals:q_x_axis,root:myGlobals:q_y_axis
37       
38        NVAR pixelsX = root:myGlobals:gNPixelsX
39        NVAR pixelsY = root:myGlobals:gNPixelsY
40       
41        //get the current displayed data (so the correct folder is used)
42        SVAR cur_folder=root:myGlobals:gDataDisplayType
43        SVAR cur_title = root:myGlobals:gCurTitle
44        String curPath = "root:"+cur_folder
45        Wave/T tw=$(curPath+":TextRead")
46        cur_title = tw[6]                       //always update the title string
47       
48        DoWindow/F SANS_Data
49        if( V_Flag==0 )
50                //no SANS_Data window - make one
51
52                //Create NIH colors if needed
53                if(!WaveExists($"root:myGlobals:NIHColors"))
54                        NIHColorIndex()
55                Endif
56               
57                //window creation stuff
58                Display /W=(10,50,400,490) /K=1 //K=1 flag suppresses saveMacro dialog
59                DoWindow/C SANS_Data
60                DoWindow/T SANS_Data,cur_folder
61                SetWindow SANS_Data,hook=RawWindowHook,hookevents=2
62                ControlBar 100
63
64                SetVariable xpos,pos={7,5},size={50,17},title="X"
65                SetVariable xpos,limits={-Inf,Inf,0},value= root:myGlobals:gXPos
66                SetVariable xpos,help={"x-position on the detector"},frame=0,noedit=1
67                SetVariable ypos,pos={7,29},size={50,17},title="Y"
68                SetVariable ypos,limits={-Inf,Inf,0},value= root:myGlobals:gYPos
69                SetVariable ypos,help={"y-position on the detector"},frame=0,noedit=1
70                SetVariable counts,pos={7,59},size={150,17},title="Counts"
71                SetVariable counts,limits={-Inf,Inf,0},value= root:myGlobals:gNCounts
72                SetVariable counts,help={"Neutron counts"},frame=0,noedit=1
73                Button bisLin,pos={230,23},size={50,20},proc=Log_Lin,title="isLin"
74                Button bisLin,help={"\"isLin\" means the counts displayed are on linear scale. \"isLog\" means the counts displayed are on log(base10) scale."}
75                SetVariable qxval,pos={68,2},size={85,17},title="qX"
76                SetVariable qxval,help={"q value in the x-direction on the detector"},frame=0,noedit=1
77                SetVariable qxval,format="%+7.5f",limits={-Inf,Inf,0},value= root:myGlobals:gQX
78                SetVariable qyval,pos={68,21},size={85,17},title="qY"
79                SetVariable qyval,help={"q value in the y-direction on the detector"},frame=0,noedit=1
80                SetVariable qyval,format="%+7.5f",limits={-Inf,Inf,0},value= root:myGlobals:gQY
81                SetVariable q_pos,pos={68,40},size={85,17},title="q "
82                SetVariable q_pos,help={"q-value on the detector at (x,y)"},format="%+7.5f"
83                SetVariable q_pos,limits={-Inf,Inf,0},value= root:myGlobals:gQQ,frame=0,noedit=1
84                SetVariable CurFile,pos={170,4},size={210,17},title="File"
85                SetVariable CurFile,help={"Currently displayed file"},frame=0,noedit=1
86                SetVariable CurFile,limits={-Inf,Inf,0},value= root:myGlobals:gCurDispFile
87               
88                SetVariable CurTitle,pos={4,81},size={260,17},title=" "//,title="LABEL:"
89                SetVariable CurTitle,help={"Title string for currently displayed file"},frame=0,noedit=1
90                SetVariable CurTitle,fstyle=1,limits={-Inf,Inf,0},value= root:myGlobals:gCurTitle
91                Button Print_status,pos={170,23},size={50,20},proc=StatusButton,title="Status"
92                Button Print_status,help={"Print out information about the currently displayed file into the history window"}
93                Button maskButton size={84,20}, pos={170,53}, proc=maskButtonProc,title="Show Mask"
94                Button maskButton help={"If a mask has been loaded this will overlay it on the current plot"}
95               
96                GroupBox slideGrp,pos={268,46},size={124,48},title="Color Map"
97                //draw after the group box so these are on "top" of the group box
98                Button doAve,pos={290,23},size={50,20},proc=ShowAvgPanel_SANSData,title="I vs. Q"
99                Button doAve,help={"This will circularly average the data to I vs. Q"}
100                Slider loSlide,pos={280,77},size={100,16},proc=MapSliderProc
101                Slider loSlide,limits={0,1,0.01},value= 0,vert= 0,ticks= 0
102                Slider loSlide,help={"Adjust the low threshold of the color map"}
103                Slider hiSlide,pos={280,60},size={100,16},proc=MapSliderProc
104                Slider hiSlide,limits={0,1,0.01},value= 1,vert= 0,ticks= 0
105                Slider hiSlide,help={"Adjust the high threshold of the color map"}
106
107        endif
108       
109        //window was already open, or has just been created, add (or remove)
110        //controls specific for RAW data (specified by the current folder)
111        if(cmpstr(cur_folder,"RAW")==0)
112                //show the "next" buttons
113                //these buttons should only be available in RAW data type
114                Button backOne size={20,20},pos={350,23},proc=BackOneFileButtonProc,title="<"
115                Button backOne help={"Display the previous RAW data file run number"}
116                Button forwardOne size={20,20},pos={375,23},proc=ForwardOneFileButtonProc,title=">"
117                Button forwardOne help={"Display the next RAW data file run number"}
118                //
119        else
120                //kill them
121                KillControl backOne
122                KillControl forwardOne
123        Endif
124       
125        //reset the slider values to 0,1
126        Slider loSlide,value=0
127        Slider hiSlide,value=1
128       
129        //remove old data and add new data to it
130        //data display/modification stuff
131        RemoveImage/Z data
132        WAVE data = $(curPath + ":data")
133        WAVE NIHColors = $"root:myGlobals:NIHColors"
134        AppendImage data
135        WaveStats/Q $(curPath + ":data")
136        if(cmpstr(cur_folder,"MSK")==0)
137                ModifyImage data ctab={0,1,BlueRedGreen,0}
138   else
139                //Call the procedure that would normally be called if the sliders were moved
140//              MapSliderProc("both", 0, 1)
141                MapSliderProc("reset", 0, 1)
142    //  ScaleColorsToData(V_min, V_max, NIHColors)
143         //  ModifyImage data cindex=NIHColors
144        endif
145        //make the pixels square, color the backgrounds
146        ModifyGraph width={plan,1,bottom,left},mirror=0
147        ModifyGraph axisenab(bottom)={0,0.7}
148        ModifyGraph axOffset(left)=-3
149        ModifyGraph standoff=0
150        ModifyGraph wbRGB=(65535,54611,49151),gbRGB=(65535,54611,49151),cbRGB=(1,52428,52428)
151       
152        //add the qx and qy axes
153        Wave q_x_axis=$"root:myGlobals:q_x_axis"
154        Wave q_y_axis=$"root:myGlobals:q_y_axis"
155        Set_Q_Axes(q_x_axis,q_y_axis,curPath)
156        RemoveFromGraph/Z q_x_axis,q_y_axis
157        AppendToGraph/T q_x_axis
158        AppendToGraph/R=Right_Q q_y_axis                                //plot on a free axis, crossing at x=127 (pixelsX)
159        ModifyGraph freePos(Right_q)={pixelsX-1,bottom}
160        ModifyGraph minor(top)=1,minor(Right_Q)=1,lowTrip(top)=1e-05,lowTrip(Right_Q)=1e-05
161        ModifyGraph mode(q_x_axis)=2,mode(q_y_axis)=2           //dots
162        ModifyGraph axisEnab(top)={0,0.7}
163
164        //add the color bar
165        ColorScale/N=colBar/A=RT/X=-3/Y=-1.5/Z=1 image=data, heightPct=100, widthPct=4,notation=1
166        ColorScale/C/N=colBar/B=(65535,60076,49151)
167       
168        //update the displayed filename, using FileList in the current data folder
169        SVAR FileList = $(curPath + ":FileList")
170        String/G root:myGlobals:gCurDispFile = FileList
171       
172        //update the window title
173        DoWindow/T SANS_Data,cur_folder
174       
175        // reset the initial state of the "isLin" button if it is reading "isLog", since the initial data state is
176        //always set to linear
177        //re-draw the data on the graph to make sure "data" from the current folder is being used
178        ControlInfo bisLog
179        if(V_flag ==1)  //if bisLog exists, this will return true
180                Button bisLog,title="isLin",rename=bisLin
181        endif
182        //now that button state and data are sure to match (both are linear)
183        // set the display to log scale, if the global has been set
184        NVAR gLogScalingAsDefault=root:myGlobals:gLogScalingAsDefault
185        if(gLogScalingAsDefault)
186                Log_lin("bisLin")
187        endif
188       
189        //force an update of everything in the window
190        DoUpdate
191       
192        //return data folder to root before exiting (redundant)
193        SetDataFolder root:     
194End
195
196//this is the hook function that is associated with the SANS_Data graph window
197//only mouse moved events are processed, although much more could be done
198//for more elaborate interaction with the user.
199//- sets globals (that are displayed in the control bar of the graph) for the
200//x and y positions (in Detector coordinates (1,128))
201//qx, qy, and q (in Angstroms)
202//and the actual neutron counts (if raw)
203//or the data array value
204//
205Function RawWindowHook(s)
206        String s
207       
208        //get the current displayed data (so the correct folder is used)
209        SVAR cur_folder=root:myGlobals:gDataDisplayType
210        SetDataFolder "root:"+cur_folder                //use the full path, so it will always work
211        String curPath = "root:" + cur_folder
212        NVAR dataIsLog=$(curPath + ":gIsLogScale")              //now a global variable in the current folder, not the globals folder
213        if (dataIsLog)
214                wave w=$(curPath + ":linear_data")
215        else
216                wave w=$(curPath + ":data")
217      endif
218        wave reals=$(curPath + ":realsread")
219       
220        String/G root:myGlobals:gHookStr= s
221        Variable xpix,ypix,xaxval,yaxval,xint,yint,rawval
222        String msg
223       
224        NVAR pixelsX = root:myGlobals:gNPixelsX
225        NVAR pixelsY = root:myGlobals:gNPixelsY
226       
227        //only do something for mousemoved events
228        if( StrSearch(s,"EVENT:mousemoved;",0) > 0 )
229                xpix= NumberByKey("MOUSEX",s)
230                ypix= NumberByKey("MOUSEY",s)
231                xaxval= AxisValFromPixel("","bottom",xpix)
232                yaxval= AxisValFromPixel("","left",ypix)
233                xint = round(xaxval)
234                yint = round(yaxval)
235               
236                if((xint<0) || (xint>pixelsX-1) || (yint<0) || (yint>pixelsY-1))        //make sure cursor is on the image
237                        rawval = 0
238                else
239                        rawval = w[xint][yint] 
240                        //update q, qX, and qY
241                        if(cmpstr(cur_folder,"MSK")!=0)
242                                Variable xctr=reals[16],yctr=reals[17],sdd=reals[18],lam=reals[26],pixSize=reals[13]
243                                Variable/G root:myGlobals:gQQ = CalcQval(xaxval+1,yaxval+1,xctr,yctr,sdd,lam,pixSize)
244                                Variable/G root:myGlobals:gQX = CalcQX(xaxval+1,xctr,sdd,lam,pixSize)
245                                Variable/G root:myGlobals:gQY = CalcQY(yaxval+1,yctr,sdd,lam,pixSize)
246                        else
247                                Variable/G root:myGlobals:gQQ = 0
248                                Variable/G root:myGlobals:gQX = 0
249                                Variable/G root:myGlobals:gQY = 0
250                        endif
251                        //add one to the x and y values to get from IGOR array indexing 0->127 to 1->128 detector
252                        Variable/G root:myGlobals:gXPos=xint+1
253                        Variable/G root:myGlobals:gYPos=yint+1
254                        Variable/G root:myGlobals:gNCounts=rawval
255                endif
256        endif
257       
258        //set data folder back to root
259        SetDataFolder root:
260       
261        return 0
262end
263       
264//function to calculate the overall q-value, given all of the necesary trig inputs
265//NOTE: detector locations passed in are pixels = 0.5cm real space on the detector
266//and are in detector coordinates (1,128) rather than axis values
267//the pixel locations need not be integers, reals are ok inputs
268//sdd is in meters
269//wavelength is in Angstroms
270//returned q-value is in 1/Angstroms
271//
272// generalized to read the detector pixel dimension from the file header...
273//
274Function CalcQval(xaxval,yaxval,xctr,yctr,sdd,lam,pixSize)
275        Variable xaxval,yaxval,xctr,yctr,sdd,lam,pixSize
276       
277        Variable dx,dy,thetax,thetay,qval,qx,qy
278       
279//      Wave realW=$"root:raw:realsRead"
280//      Variable pixSizeX = realW[10]/10                //header is in mm, want cm
281//      Variable pixSizeY = realW[13]/10                //header is in mm, want cm
282        Variable pixSizeX=pixSize
283        Variable pixSizeY=pixSize
284       
285        sdd *=100               //convert to cm
286        dx = (xaxval - xctr)*pixSizeX           //delta x in cm
287        dy = (yaxval - yctr)*pixSizeY           //delta y in cm
288        thetax = atan(dx/sdd)
289        thetay = atan(dy/sdd)
290        qx = 4*Pi/lam*sin(thetax/2)
291        qy = 4*Pi/lam*sin(thetay/2)
292        qval = sqrt(qx^2 + qy^2)
293       
294        return qval
295End
296
297//calculates just the q-value in the x-direction on the detector
298//input/output is the same as CalcQval()
299//ALL inputs are in detector coordinates
300//
301// generalized to read the detector pixel dimension from the file header...
302//
303Function CalcQX(xaxval,xctr,sdd,lam,pixSize)
304        Variable xaxval,xctr,sdd,lam,pixSize
305        //NOTE: detector locations passed in are pixel = 0.5cm real space on the Ordela detector
306        //sdd is in meters
307        //wavelength is in Angstroms
308       
309//      Wave realW=$"root:raw:realsRead"
310//      Variable pixSize = realW[10]/10         //header is in mm, want cm
311       
312        Variable dx,thetax,qx
313       
314        sdd *=100               //convert to cm
315        dx = (xaxval - xctr)*pixSize    //delta x in cm
316        thetax = atan(dx/sdd)
317        qx = 4*Pi/lam*sin(thetax/2)
318       
319        return qx
320End
321
322//calculates just the q-value in the y-direction on the detector
323//input/output is the same as CalcQval()
324//ALL inputs are in detector coordinates
325//
326// generalized to read the detector pixel dimension from the file header...
327//
328Function CalcQY(yaxval,yctr,sdd,lam,pixSize)
329        Variable yaxval,yctr,sdd,lam,pixSize
330        //NOTE: detector locations passed in are pixel = 0.5cm real space on the Ordela detector
331        //sdd is in meters
332        //wavelength is in Angstroms
333       
334//      Wave realW=$"root:raw:realsRead"
335//      Variable pixSize = realW[13]/10         //header is in mm, want cm
336               
337        Variable dy,thetay,qy
338       
339        sdd *=100               //convert to cm
340        dy = (yaxval - yctr)*pixSize            //delta y in cm
341        thetay = atan(dy/sdd)
342        qy = 4*Pi/lam*sin(thetay/2)
343       
344        return qy
345End
346
347//function to set the q-axis scaling after the data has been read in
348// - needs the location of the currently displayed data to get the header information
349// to be able to calculate q-values at the edges of the detector
350//** assumes a linear correspondence between pixel->q-values (which should bea a really
351// safe bet, since we're using the small -angle approximation...)
352//
353// actually re-scales the qy wave that is on the SANS_Data image
354// the qy dataset is 2 values, plotted as "dots", nearly invisible...
355// but does an adequate job of getting ticks on the right and top axes
356//
357Function Set_Q_Axes(qx,qy,curPath)
358        Wave qx,qy
359        String curPath
360
361        NVAR pixelsX = root:myGlobals:gNPixelsX
362        NVAR pixelsY = root:myGlobals:gNPixelsY
363       
364        WAVE reals=$(curPath + ":realsread")
365        Variable xctr=reals[16],yctr=reals[17],sdd=reals[18],lam=reals[26]
366        Variable pixSize=reals[13]/10           //pixel size in cm to pass
367        Variable maxX,minX,maxY,minY
368       
369        minX = CalcQX(1,xctr,sdd,lam,pixSize)
370        maxX = CalcQX(pixelsX,xctr,sdd,lam,pixSize)
371        SetScale/I x minX,maxX,"",qx
372       
373        minY = CalcQY(1,yctr,sdd,lam,pixSize)
374        maxY = CalcQY(pixelsY,yctr,sdd,lam,pixSize)
375        qy[0] = minY
376        qy[1] = maxY
377       
378        return(0)
379End
380
381Function ToggleDefaultMapping()
382        NVAR value = root:myGlobals:gLogScalingAsDefault
383        value = !(value)
384End
385
Note: See TracBrowser for help on using the repository browser.