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

Last change on this file since 167 was 167, checked in by srkline, 16 years ago

Changed NSORT to display rescaling and overlap constants behind the OS file save dialog, allowing the user to cancel the save it something is amiss.

No significant change in trans=1 panel behavior in Correct.ipf

Cosmetic changes to RawWindowHook? (drawing order) to look nicer w/OS native panels.

File size: 14.0 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
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]
243                                Variable/G root:myGlobals:gQQ = CalcQval(xaxval+1,yaxval+1,xctr,yctr,sdd,lam)
244                                Variable/G root:myGlobals:gQX = CalcQX(xaxval+1,xctr,sdd,lam)
245                                Variable/G root:myGlobals:gQY = CalcQY(yaxval+1,yctr,sdd,lam)
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)
275        Variable xaxval,yaxval,xctr,yctr,sdd,lam
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       
283        sdd *=100               //convert to cm
284        dx = (xaxval - xctr)*pixSizeX           //delta x in cm
285        dy = (yaxval - yctr)*pixSizeY           //delta y in cm
286        thetax = atan(dx/sdd)
287        thetay = atan(dy/sdd)
288        qx = 4*Pi/lam*sin(thetax/2)
289        qy = 4*Pi/lam*sin(thetay/2)
290        qval = sqrt(qx^2 + qy^2)
291       
292        return qval
293End
294
295//calculates just the q-value in the x-direction on the detector
296//input/output is the same as CalcQval()
297//ALL inputs are in detector coordinates
298//
299// generalized to read the detector pixel dimension from the file header...
300//
301Function CalcQX(xaxval,xctr,sdd,lam)
302        Variable xaxval,xctr,sdd,lam
303        //NOTE: detector locations passed in are pixel = 0.5cm real space on the Ordela detector
304        //sdd is in meters
305        //wavelength is in Angstroms
306       
307        Wave realW=$"root:raw:realsRead"
308        Variable pixSize = realW[10]/10         //header is in mm, want cm
309       
310        Variable dx,thetax,qx
311       
312        sdd *=100               //convert to cm
313        dx = (xaxval - xctr)*pixSize    //delta x in cm
314        thetax = atan(dx/sdd)
315        qx = 4*Pi/lam*sin(thetax/2)
316       
317        return qx
318End
319
320//calculates just the q-value in the y-direction on the detector
321//input/output is the same as CalcQval()
322//ALL inputs are in detector coordinates
323//
324// generalized to read the detector pixel dimension from the file header...
325//
326Function CalcQY(yaxval,yctr,sdd,lam)
327        Variable yaxval,yctr,sdd,lam
328        //NOTE: detector locations passed in are pixel = 0.5cm real space on the Ordela detector
329        //sdd is in meters
330        //wavelength is in Angstroms
331       
332        Wave realW=$"root:raw:realsRead"
333        Variable pixSize = realW[13]/10         //header is in mm, want cm
334               
335        Variable dy,thetay,qy
336       
337        sdd *=100               //convert to cm
338        dy = (yaxval - yctr)*pixSize            //delta y in cm
339        thetay = atan(dy/sdd)
340        qy = 4*Pi/lam*sin(thetay/2)
341       
342        return qy
343End
344
345//function to set the q-axis scaling after the data has been read in
346// - needs the location of the currently displayed data to get the header information
347// to be able to calculate q-values at the edges of the detector
348//** assumes a linear correspondence between pixel->q-values (which should bea a really
349// safe bet, since we're using the small -angle approximation...)
350//
351// actually re-scales the qy wave that is on the SANS_Data image
352// the qy dataset is 2 values, plotted as "dots", nearly invisible...
353// but does an adequate job of getting ticks on the right and top axes
354//
355Function Set_Q_Axes(qx,qy,curPath)
356        Wave qx,qy
357        String curPath
358
359        NVAR pixelsX = root:myGlobals:gNPixelsX
360        NVAR pixelsY = root:myGlobals:gNPixelsY
361       
362        WAVE reals=$(curPath + ":realsread")
363        Variable xctr=reals[16],yctr=reals[17],sdd=reals[18],lam=reals[26]
364        Variable maxX,minX,maxY,minY
365       
366        minX = CalcQX(1,xctr,sdd,lam)
367        maxX = CalcQX(pixelsX,xctr,sdd,lam)
368        SetScale/I x minX,maxX,"",qx
369       
370        minY = CalcQY(1,yctr,sdd,lam)
371        maxY = CalcQY(pixelsY,yctr,sdd,lam)
372        qy[0] = minY
373        qy[1] = maxY
374       
375        return(0)
376End
377
378Function ToggleDefaultMapping()
379        NVAR value = root:myGlobals:gLogScalingAsDefault
380        value = !(value)
381End
382
Note: See TracBrowser for help on using the repository browser.