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

Last change on this file since 116 was 116, checked in by ajj, 16 years ago

Merged kline_29MAR07 branch (Separation of NCNR specific code) r66:115 into the trunk

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