1 | #pragma rtGlobals=1 // Use modern global access method. |
---|
2 | #pragma version=5.0 |
---|
3 | #pragma IgorVersion=6.1 |
---|
4 | |
---|
5 | //********************* |
---|
6 | // Vers 1.2 083101 |
---|
7 | // Procedures to interactively select the 2D to 1D averageing options and viewing the 1D data |
---|
8 | // - pink "Average" panel and associated functions, including drawing on the 2D display |
---|
9 | // - generation of the 1D graph, including rescaling options |
---|
10 | // (rescaling options are quite similar to those in FIT_Ops) |
---|
11 | //********************** |
---|
12 | |
---|
13 | //main entry for invoking the pink average panel |
---|
14 | Proc ShowAveragePanel() |
---|
15 | DoWindow/F Average_Panel |
---|
16 | If(V_flag == 0) |
---|
17 | InitializeAveragePanel() |
---|
18 | //draw panel |
---|
19 | Average_Panel() |
---|
20 | DisableUnusedParameters("Circular") //the default choice |
---|
21 | Endif |
---|
22 | End |
---|
23 | |
---|
24 | //creates the necessary globals for the operation of the panel |
---|
25 | Proc InitializeAveragePanel() |
---|
26 | //create the global variables needed to run the Average Panel |
---|
27 | //all are kept in root:myGlobals:Drawing |
---|
28 | If( ! (DataFolderExists("root:myGlobals:Drawing")) ) |
---|
29 | NewDataFolder/O/S root:myGlobals:Drawing |
---|
30 | Endif |
---|
31 | |
---|
32 | //ok, create the globals, fill the keyword string with all possible values (default) |
---|
33 | String/G root:myGlobals:Drawing:gDrawInfoStr = "AVTYPE=Circular;PHI=0;DPHI=0;WIDTH=0;SIDE=both;" |
---|
34 | root:myGlobals:Drawing:gDrawInfoStr += "QCENTER=0;QDELTA=0;" |
---|
35 | Variable/G root:myGlobals:Drawing:gDrawPhi =0 |
---|
36 | Variable/G root:myGlobals:Drawing:gDrawWidth = 1 |
---|
37 | Variable/G root:myGlobals:Drawing:gDrawDPhi = 0 |
---|
38 | Variable/G root:myGlobals:Drawing:gDrawQCtr = 0 |
---|
39 | Variable/G root:myGlobals:Drawing:gDrawQDelta = 1 |
---|
40 | |
---|
41 | //return to root |
---|
42 | SetDataFolder root: |
---|
43 | End |
---|
44 | |
---|
45 | //button procedure to close the panel, does nothing else |
---|
46 | Function AveDoneButtonProc(ctrlName) : ButtonControl |
---|
47 | String ctrlName |
---|
48 | |
---|
49 | DoWindow/K Average_Panel |
---|
50 | End |
---|
51 | |
---|
52 | //button procedure to clear the lines drawn on the graph |
---|
53 | //which were drawn in the "User Front" layer only |
---|
54 | Function ClearLinesButtonProc(ctrlName) : ButtonControl |
---|
55 | String ctrlName |
---|
56 | |
---|
57 | //Print "Clear the drawn lines from the graph" |
---|
58 | DoWindow/F SANS_Data |
---|
59 | SetDrawLayer/K UserFront |
---|
60 | End |
---|
61 | |
---|
62 | //button procedure that will perform the average on the currently displayed file |
---|
63 | //using the choices that are currently in the panel |
---|
64 | //the panel is not directly parsed, since each information box,SetVar,popup |
---|
65 | //sets a corresponding value in the global string root:myGlobals:Drawing:gDrawInfoStr |
---|
66 | Function Panel_DoAverageButtonProc(ctrlName) : ButtonControl |
---|
67 | String ctrlName |
---|
68 | |
---|
69 | // average the currently displayed data |
---|
70 | SVAR type=root:myGlobals:gDataDisplayType |
---|
71 | NVAR useXMLOutput = root:Packages:NIST:gXML_Write |
---|
72 | |
---|
73 | //Check for logscale data in "type" folder |
---|
74 | String dest = "root:Packages:NIST:"+type |
---|
75 | |
---|
76 | NVAR isLogScale = $(dest + ":gIsLogScale") |
---|
77 | Variable wasLogScale=isLogScale |
---|
78 | |
---|
79 | if(isLogScale) |
---|
80 | ConvertFolderToLinearScale(type) |
---|
81 | //rename the button to reflect "isLin" - the displayed name must have been isLog |
---|
82 | // DoWindow/F SANS_Data |
---|
83 | // MapSliderProc("reset", 0, 1) //force default values for color mapping |
---|
84 | // Button bisLog,title="isLin",rename=bisLin |
---|
85 | // DoWindow/F Average_Panel |
---|
86 | // DoUpdate |
---|
87 | Endif |
---|
88 | |
---|
89 | //set data folder back to root (redundant) |
---|
90 | SetDataFolder root: |
---|
91 | |
---|
92 | //build the string that the averaging routine is looking for |
---|
93 | //The draw string uses the SAME keywords and value list - just copy it |
---|
94 | SVAR tempstr=root:myGlobals:Drawing:gDrawInfoStr |
---|
95 | String/G root:myGlobals:Protocols:gAvgInfoStr=tempStr |
---|
96 | String choice = StringByKey("AVTYPE",tempStr,"=",";") |
---|
97 | |
---|
98 | //does the user want to save the averaged file to disk? |
---|
99 | //poll the checkbox - the keyword may not be in the string, and here we'll always ask for a filename |
---|
100 | ControlInfo/W=Average_Panel SaveCheck |
---|
101 | Variable doSave = V_Value |
---|
102 | //if the "average" choice is 2D ASCII or QxQy ASCII, then doSave=1 to force a save |
---|
103 | if(strsearch(choice,"ASCII",0) != -1) |
---|
104 | doSave = 1 |
---|
105 | endif |
---|
106 | |
---|
107 | If(doSave) |
---|
108 | //setup a "fake protocol" wave, sice I have no idea of the current state of the data |
---|
109 | Make/O/T/N=8 root:myGlobals:Protocols:fakeProtocol |
---|
110 | Wave/T fakeProtocol = $"root:myGlobals:Protocols:fakeProtocol" |
---|
111 | String junk="Unknown file from Average_Panel" |
---|
112 | fakeProtocol[0] = junk |
---|
113 | fakeProtocol[1] = junk |
---|
114 | fakeProtocol[2] = junk |
---|
115 | fakeProtocol[3] = junk |
---|
116 | fakeProtocol[4] = junk |
---|
117 | fakeProtocol[5] = junk |
---|
118 | fakeProtocol[6] = junk |
---|
119 | fakeProtocol[7] = tempStr |
---|
120 | //set the global |
---|
121 | String/G root:myGlobals:Protocols:gProtoStr = "fakeProtocol" |
---|
122 | Endif |
---|
123 | |
---|
124 | //dispatch to correct averaging routine - |
---|
125 | strswitch(choice) |
---|
126 | case "Rectangular": |
---|
127 | RectangularAverageTo1D(type) |
---|
128 | If(doSave) //save the file, acting on the currently displayed file |
---|
129 | if (useXMLOutput == 1) |
---|
130 | WriteXMLWaves_W_Protocol(type,"",1) |
---|
131 | else |
---|
132 | WriteWaves_W_Protocol(type,"",1) //"" is an empty path, 1 will force a dialog |
---|
133 | endif |
---|
134 | Endif |
---|
135 | break |
---|
136 | case "Annular": |
---|
137 | AnnularAverageTo1D(type) |
---|
138 | If(doSave) // XML here yet |
---|
139 | //save the file, acting on the currently displayed file |
---|
140 | WritePhiave_W_Protocol(type,"",1) //"" is an empty path, 1 will force a dialog |
---|
141 | Endif |
---|
142 | break |
---|
143 | case "Circular": |
---|
144 | case "Sector": |
---|
145 | //circular or sector |
---|
146 | CircularAverageTo1D(type) //graph is drawn here |
---|
147 | If(doSave) |
---|
148 | if (useXMLOutput == 1) |
---|
149 | WriteXMLWaves_W_Protocol(type,"",1) |
---|
150 | else |
---|
151 | WriteWaves_W_Protocol(type,"",1) //"" is an empty path, 1 will force a dialog |
---|
152 | endif |
---|
153 | Endif |
---|
154 | break |
---|
155 | case "2D ASCII": |
---|
156 | Fast2dExport(type,"",1) |
---|
157 | break |
---|
158 | case "QxQy ASCII": |
---|
159 | QxQy_Export(type,"",1) |
---|
160 | break |
---|
161 | default: |
---|
162 | Abort "no case match in average dispatch" |
---|
163 | endswitch |
---|
164 | |
---|
165 | //convert back to log scaling if I changed it... |
---|
166 | if(wasLogScale) |
---|
167 | ConvertFolderToLogScale(type) |
---|
168 | DoUpdate |
---|
169 | endif |
---|
170 | |
---|
171 | //clear the stuff that was created for case of saving files |
---|
172 | If(doSave) |
---|
173 | Killwaves/Z root:myGlobals:Protocols:fakeProtocol |
---|
174 | String/G root:myGlobals:Protocols:gProtoStr = "" |
---|
175 | Endif |
---|
176 | |
---|
177 | |
---|
178 | return(0) |
---|
179 | |
---|
180 | End |
---|
181 | |
---|
182 | //when "sides" popup is "popped", the value associated with the SIDE |
---|
183 | //keyword is updated in the global string |
---|
184 | //then the angles are redrawn based on the choice |
---|
185 | Function SidesPopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl |
---|
186 | String ctrlName |
---|
187 | Variable popNum |
---|
188 | String popStr |
---|
189 | |
---|
190 | ControlInfo/W=Average_Panel sides |
---|
191 | String side = S_Value |
---|
192 | SVAR tempStr = root:myGlobals:Drawing:gDrawInfoStr |
---|
193 | String newStr = ReplaceStringByKey("SIDE", tempStr, side, "=", ";") |
---|
194 | |
---|
195 | String/G root:myGlobals:Drawing:gDrawInfoStr = newStr |
---|
196 | |
---|
197 | //redraw the angles |
---|
198 | MasterAngleDraw() |
---|
199 | |
---|
200 | End |
---|
201 | |
---|
202 | |
---|
203 | //when the "type of average" popup is "popped", the value associated with the AVTYPE |
---|
204 | //keyword is updated in the global string |
---|
205 | //then the angles are redrawn based on the choice |
---|
206 | // |
---|
207 | // changes the title of the "do" button to "Save" if ASCII is chosen |
---|
208 | // disables all setVars (ASCII cases), then selectively enables them as choice dictates |
---|
209 | Function AvTypePopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl |
---|
210 | String ctrlName |
---|
211 | Variable popNum |
---|
212 | String popStr |
---|
213 | |
---|
214 | ControlInfo/W=Average_Panel av_choice |
---|
215 | String choice = S_Value |
---|
216 | SVAR tempStr = root:myGlobals:Drawing:gDrawInfoStr |
---|
217 | |
---|
218 | DisableUnusedParameters(choice) |
---|
219 | |
---|
220 | strswitch(choice) // string switch |
---|
221 | case "2D ASCII": // execute if case matches expression |
---|
222 | case "QxQy ASCII": |
---|
223 | String/G root:myGlobals:Drawing:gDrawInfoStr = ReplaceStringByKey("AVTYPE", tempStr, choice, "=", ";") |
---|
224 | Button P_DoAvg,title="Save ASCII" |
---|
225 | break |
---|
226 | case "Circular": |
---|
227 | case "Sector": |
---|
228 | case "Rectangular": |
---|
229 | case "Annular": |
---|
230 | String/G root:myGlobals:Drawing:gDrawInfoStr = ReplaceStringByKey("AVTYPE", tempStr, choice, "=", ";") |
---|
231 | Button P_DoAvg,title="Do Average" |
---|
232 | //redraw the angles |
---|
233 | MasterAngleDraw() |
---|
234 | break |
---|
235 | default: // optional default expression executed |
---|
236 | Abort "no case matches from averagePanel type popup" // when no case matches |
---|
237 | endswitch |
---|
238 | return(0) |
---|
239 | End |
---|
240 | |
---|
241 | // disables all of the type-specific buttons and popups on the average_Panel |
---|
242 | // currently ununsed, ans the logic is quite slippery |
---|
243 | Function DisableUnusedParameters(choice) |
---|
244 | String choice |
---|
245 | |
---|
246 | Variable yes=1,no=0 |
---|
247 | |
---|
248 | strswitch(choice) // string switch |
---|
249 | case "2D ASCII": |
---|
250 | case "QxQy ASCII": |
---|
251 | case "Circular": //disable everything for these three choices |
---|
252 | SetVariable Phi_p,disable=yes |
---|
253 | SetVariable Qctr_p,disable=yes |
---|
254 | SetVariable Qdelta_p,disable=yes |
---|
255 | SetVariable DPhi_p,disable=yes |
---|
256 | SetVariable width_p,disable=yes |
---|
257 | popupmenu sides,disable=yes |
---|
258 | break |
---|
259 | case "Sector": |
---|
260 | SetVariable Phi_p,disable=no |
---|
261 | SetVariable Qctr_p,disable=yes |
---|
262 | SetVariable Qdelta_p,disable=yes |
---|
263 | SetVariable DPhi_p,disable=no |
---|
264 | SetVariable width_p,disable=yes |
---|
265 | popupmenu sides,disable=no |
---|
266 | break |
---|
267 | case "Rectangular": |
---|
268 | SetVariable Phi_p,disable=no |
---|
269 | SetVariable Qctr_p,disable=yes |
---|
270 | SetVariable Qdelta_p,disable=yes |
---|
271 | SetVariable DPhi_p,disable=yes |
---|
272 | SetVariable width_p,disable=no |
---|
273 | popupmenu sides,disable=no |
---|
274 | break |
---|
275 | case "Annular": |
---|
276 | SetVariable Phi_p,disable=yes |
---|
277 | SetVariable Qctr_p,disable=no |
---|
278 | SetVariable Qdelta_p,disable=no |
---|
279 | SetVariable DPhi_p,disable=yes |
---|
280 | SetVariable width_p,disable=yes |
---|
281 | popupmenu sides,disable=yes |
---|
282 | break |
---|
283 | default: // optional default expression executed |
---|
284 | Abort "no case matches from averagePanel type popup" // when no case matches |
---|
285 | endswitch |
---|
286 | return(0) |
---|
287 | end |
---|
288 | |
---|
289 | //draws the Panel, with defaults for standard circular average |
---|
290 | Window Average_Panel() |
---|
291 | PauseUpdate; Silent 1 // building window... |
---|
292 | NewPanel /W=(638,65,933,347) /K=1 |
---|
293 | ModifyPanel cbRGB=(65535,49151,62258), fixedSize=1 |
---|
294 | SetDrawLayer UserBack |
---|
295 | // DrawText 192,121,"(pixels)" |
---|
296 | // DrawText 47,190,"(pixels)" |
---|
297 | GroupBox ann,pos={148,44},size={143,84},title="Annular" |
---|
298 | GroupBox rect,pos={7,133},size={134,71},title="Rectangular" |
---|
299 | GroupBox sect,pos={148,133},size={143,71},title="Sector" |
---|
300 | GroupBox sect_rect,pos={7,44},size={134,84},title="Sector/Rectangular" |
---|
301 | PopupMenu av_choice,pos={61,7},size={144,20},proc=AvTypePopMenuProc,title="AverageType" |
---|
302 | PopupMenu av_choice,help={"Select the type of average to perform, then make the required selections below and click \"DoAverage\" to plot the results"} |
---|
303 | PopupMenu av_choice,mode=1,popvalue="Circular",value= #"\"Circular;Sector;Annular;Rectangular;2D ASCII;QxQy ASCII\"" |
---|
304 | Button ave_help,pos={260,7},size={25,20},proc=ShowAvePanelHelp,title="?" |
---|
305 | Button ave_help,help={"Show the help file for averaging options"} |
---|
306 | Button ave_done,pos={199,245},size={50,20},proc=AveDoneButtonProc,title="Done" |
---|
307 | Button ave_done,help={"When done, this will close the panel. The panel may be recalled at any time from the SANS menu."} |
---|
308 | Button ClearLines,pos={198,212},size={50,20},proc=ClearLinesButtonProc,title="Clear" |
---|
309 | Button ClearLines,help={"This will clear the drawn lines from the SANS data"} |
---|
310 | SetVariable Phi_p,pos={32,92},size={70,15},proc=PhiSetVarProc,title="Phi" |
---|
311 | SetVariable Phi_p,help={"Enter the azimuthal angle phi (-90,90). Phi is defined CCW from zero at the positive x-axis. The phi line will be drawn in light green."} |
---|
312 | SetVariable Phi_p,limits={-90,90,1},value= root:myGlobals:Drawing:gDrawPhi |
---|
313 | SetVariable Qctr_p,pos={155,66},size={130,15},proc=QctrSetVarProc,title="Q-center" |
---|
314 | SetVariable Qctr_p,help={"Enter the q-center of the annular region (1/A). The circle will be drawn in light green."} |
---|
315 | SetVariable Qctr_p,limits={1e-05,0.7,0.001},value= root:myGlobals:Drawing:gDrawQCtr |
---|
316 | SetVariable QDelta_p,pos={155,90},size={130,15},proc=QDeltaSetVarProc,title="Q Delta (pixels)" |
---|
317 | SetVariable QDelta_p,help={"Enter the total width of the annulus in pixels. The bounding circles will be draw in blue."} |
---|
318 | SetVariable QDelta_p,limits={1,40,1},value= root:myGlobals:Drawing:gDrawQDelta |
---|
319 | SetVariable DPhi_p,pos={166,154},size={110,15},proc=DeltaPhiSetVarProc,title="Delta Phi" |
---|
320 | SetVariable DPhi_p,help={"Enter the +/- range (0,45) of azimuthal angles to be included in the average. The bounding angles will be drawin in blue."} |
---|
321 | SetVariable DPhi_p,limits={0,90,1},value= root:myGlobals:Drawing:gDrawDPhi |
---|
322 | SetVariable width_p,pos={15,155},size={115,15},proc=WidthSetVarProc,title="Width (pixels)" |
---|
323 | SetVariable width_p,help={"Enter the total width of the rectangular section in pixels. The bounding lines will be drawn in blue."} |
---|
324 | SetVariable width_p,limits={1,130,1},value= root:myGlobals:Drawing:gDrawWidth |
---|
325 | Button P_DoAvg,pos={30,247},size={90,20},proc=Panel_DoAverageButtonProc,title="Do Average" |
---|
326 | Button P_DoAvg,help={"This will do the averaging of the displayed dta based on the selection in this panel. The data will automatically be plotted. It will not be saved to disk unless the \"Save to disk\" box is checked BEFORE the average is performed."} |
---|
327 | PopupMenu sides,pos={16,67},size={97,20},proc=SidesPopMenuProc,title="Sides ?" |
---|
328 | PopupMenu sides,help={"Select the regions of the detector to include in the averaging. \"right\" denotes right or above the beamstop."} |
---|
329 | PopupMenu sides,mode=1,popvalue="both",value= #"\"both;left;right\"" |
---|
330 | CheckBox saveCheck,pos={14,215},size={102,14},title="Save file to disk?" |
---|
331 | CheckBox saveCheck,help={"If checked, the averaged data will be saved to disk. The user will always be prompted for the filename."} |
---|
332 | CheckBox saveCheck,value= 0 |
---|
333 | EndMacro |
---|
334 | |
---|
335 | Function ShowAvePanelHelp(ctrlName) : ButtonControl |
---|
336 | String ctrlName |
---|
337 | DisplayHelpTopic/Z/K=1 "SANS Data Reduction Tutorial[Average Options]" |
---|
338 | if(V_flag !=0) |
---|
339 | DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found" |
---|
340 | endif |
---|
341 | end |
---|
342 | |
---|
343 | //Sets global key=value for drawing phi-line on graph |
---|
344 | //and redraws the angles |
---|
345 | Function PhiSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl |
---|
346 | String ctrlName |
---|
347 | Variable varNum |
---|
348 | String varStr |
---|
349 | String varName |
---|
350 | |
---|
351 | ControlInfo/W=Average_Panel phi_p |
---|
352 | Variable phi = V_Value |
---|
353 | SVAR tempStr = root:myGlobals:Drawing:gDrawInfoStr |
---|
354 | String newStr = ReplaceNumberByKey("PHI", tempStr, phi, "=", ";") |
---|
355 | |
---|
356 | String/G root:myGlobals:Drawing:gDrawInfoStr = newStr |
---|
357 | |
---|
358 | //redraw the angles |
---|
359 | MasterAngleDraw() |
---|
360 | End |
---|
361 | |
---|
362 | //draws all of the lines specified by the global keyword string |
---|
363 | //clears the old lines, and parses the string |
---|
364 | Function MasterAngleDraw() |
---|
365 | //takes the global gDrawInfoStr and Parses it to determine what to redraw on the graph |
---|
366 | |
---|
367 | //first clear the old draw Layer |
---|
368 | DoWindow/F SANS_Data |
---|
369 | if(V_flag ==0) |
---|
370 | Abort "No SANS data. Use'Display Raw Data' to display a 2D data file" |
---|
371 | Endif |
---|
372 | SetDrawLayer/K UserFront |
---|
373 | SetDrawLayer UserFront |
---|
374 | |
---|
375 | //what average type are we drawing for? |
---|
376 | SVAR drawStr = root:myGlobals:Drawing:gDrawInfoStr |
---|
377 | |
---|
378 | //get the beam center from the currently displayed data type |
---|
379 | SVAR type = root:myGlobals:gDataDisplayType |
---|
380 | Wave reals = $("root:Packages:NIST:"+type+":RealsRead") |
---|
381 | Variable x0,y0,x1,y1 |
---|
382 | x0 = reals[16] - 1 //convert to [0,127] from (1,128) detector |
---|
383 | y0 = reals[17] - 1 |
---|
384 | |
---|
385 | //right, left, or both halves? |
---|
386 | //what type of average? |
---|
387 | String side = StringByKey("SIDE",drawStr,"=",";") |
---|
388 | String av_type = StringByKey("AVTYPE",drawStr,"=",";") |
---|
389 | Variable phi = NumberByKey("PHI",drawStr,"=",";") |
---|
390 | Variable dphi = NumberByKey("DPHI",drawStr,"=",";") |
---|
391 | Variable width = NumberByKey("WIDTH",drawStr,"=",";") |
---|
392 | |
---|
393 | Variable delx,dely,slope,intcp,rr,gg,bb,thick |
---|
394 | rr = 0 |
---|
395 | gg = 0 |
---|
396 | bb = 0 |
---|
397 | thick = 2 |
---|
398 | |
---|
399 | //if circular average, just get out |
---|
400 | if(cmpstr(av_type,"Circular")==0) |
---|
401 | //clear the drawing |
---|
402 | // DoWindow/F SANS_Data |
---|
403 | // SetDrawLayer/K UserFront |
---|
404 | //go back to the average panel |
---|
405 | DoWindow/F Average_Panel |
---|
406 | |
---|
407 | Return 0 //exit the Draw routine |
---|
408 | Endif |
---|
409 | |
---|
410 | //handle sector-type and annular type averages differently |
---|
411 | if(cmpstr(av_type,"Annular")==0) |
---|
412 | //do the annular drawing |
---|
413 | //need to go from q-value to y-axis value (since x will shift a lot) |
---|
414 | //and make sure that the (radius) is allowable for drawing |
---|
415 | Variable sdd=reals[18],lam=reals[26] |
---|
416 | |
---|
417 | sdd *=100 //convert to cm |
---|
418 | //find the radius (from the y-direction) |
---|
419 | Variable QCtr = NumberByKey("QCENTER",drawStr,"=",";") |
---|
420 | Variable QDelta = NumberByKey("QDELTA",drawStr,"=",";") |
---|
421 | Variable thetay,dy,pixelSize |
---|
422 | |
---|
423 | pixelSize = reals[10]/10 //this is ONLY the x-direction, converted to cm |
---|
424 | thetay = 2*asin(Qctr*lam/4/Pi) |
---|
425 | dy = sdd/pixelSize*tan(thetay) //pixelSize is to convert from cm on detector to pixel |
---|
426 | |
---|
427 | rr=0 |
---|
428 | gg=50000 |
---|
429 | bb=0 |
---|
430 | DrawACircle(x0,y0,dy,rr,gg,bb,thick) |
---|
431 | |
---|
432 | //then do the +/- Qdelta rings |
---|
433 | //QDelta is the width of the annulus, in pixels |
---|
434 | rr=0 |
---|
435 | gg=0 |
---|
436 | bb=50000 |
---|
437 | DrawACircle(x0,y0,dy+(QDelta/2),rr,gg,bb,thick) |
---|
438 | // then the (- delta) ring |
---|
439 | DrawACircle(x0,y0,dy-(QDelta/2),rr,gg,bb,thick) |
---|
440 | |
---|
441 | //go back to the average panel |
---|
442 | DoWindow/F Average_Panel |
---|
443 | |
---|
444 | Return 0 //exit the Draw routine |
---|
445 | Endif |
---|
446 | |
---|
447 | //else sector or rectangular - draw the lines |
---|
448 | |
---|
449 | //if sector or rectangular, draw the phi line (on the desired side) |
---|
450 | if( (cmpstr(av_type,"Sector")==0) || (cmpstr(av_type,"Rectangular")==0)) |
---|
451 | if( (cmpstr(side,"left")==0) || (cmpstr(side,"both")==0) ) |
---|
452 | //draw the phi line on the left side |
---|
453 | //make sure x1,y1 is on the edge of the graph |
---|
454 | rr = 0 |
---|
455 | gg = 65535 |
---|
456 | bb = 0 |
---|
457 | DrawALineLeft(x0,y0,phi,rr,gg,bb,thick) |
---|
458 | Endif |
---|
459 | if( (cmpstr(side,"right")==0) || (cmpstr(side,"both")==0) ) |
---|
460 | //Draw the phi line on the right side |
---|
461 | //make sure x1,y1 is on the edge of the graph |
---|
462 | rr = 0 |
---|
463 | gg = 65535 |
---|
464 | bb = 0 |
---|
465 | DrawALineRight(x0,y0,phi,rr,gg,bb,thick) |
---|
466 | Endif |
---|
467 | Endif |
---|
468 | |
---|
469 | //if Sector, draw the +/- dphi lines |
---|
470 | if (cmpstr(av_type,"Sector")==0) |
---|
471 | if( (cmpstr(side,"left")==0) || (cmpstr(side,"both")==0) ) |
---|
472 | //draw the deltaPhi lines +/- lines |
---|
473 | if (dphi != 0) |
---|
474 | rr=0 |
---|
475 | gg = 0 |
---|
476 | bb = 50000 |
---|
477 | if (phi < 0 ) |
---|
478 | DrawALineLeft(x0,y0,phi+ dphi,rr,gg,bb,thick) |
---|
479 | if ( (abs(phi)+dphi) <= 90) |
---|
480 | DrawALineLeft(x0,y0,phi- dphi,rr,gg,bb,thick) |
---|
481 | else |
---|
482 | DrawALineRight(x0,y0,phi- dphi,rr,gg,bb,thick) |
---|
483 | Endif |
---|
484 | else |
---|
485 | if((phi+dphi) > 90) |
---|
486 | DrawALineRight(x0,y0,phi+ dphi,rr,gg,bb,thick) |
---|
487 | else |
---|
488 | DrawALineLeft(x0,y0,phi+ dphi,rr,gg,bb,thick) |
---|
489 | Endif |
---|
490 | DrawALineLeft(x0,y0,phi- dphi,rr,gg,bb,thick) |
---|
491 | Endif //phi<0 |
---|
492 | Endif //dphi !=0 |
---|
493 | Endif //left or both |
---|
494 | if( (cmpstr(side,"right")==0) || (cmpstr(side,"both")==0) ) |
---|
495 | //draw the deltaPhi lines +/- lines |
---|
496 | if (dphi != 0) |
---|
497 | rr = 0 |
---|
498 | gg = 0 |
---|
499 | bb = 50000 |
---|
500 | if (phi < 0 ) |
---|
501 | DrawALineRight(x0,y0,phi+ dphi,rr,gg,bb,thick) |
---|
502 | if ( (abs(phi)+dphi) <= 90) |
---|
503 | DrawALineRight(x0,y0,phi- dphi,rr,gg,bb,thick) |
---|
504 | else |
---|
505 | DrawALineLeft(x0,y0,phi- dphi,rr,gg,bb,thick) |
---|
506 | Endif |
---|
507 | else |
---|
508 | if((phi+dphi) > 90) |
---|
509 | DrawALineLeft(x0,y0,phi+ dphi,rr,gg,bb,thick) |
---|
510 | else |
---|
511 | DrawALineRight(x0,y0,phi+ dphi,rr,gg,bb,thick) |
---|
512 | Endif |
---|
513 | DrawALineRight(x0,y0,phi- dphi,rr,gg,bb,thick) |
---|
514 | Endif //phi<0 |
---|
515 | Endif //dphi !=0 |
---|
516 | Endif //right or both |
---|
517 | Endif //if sector, draw dphi lines |
---|
518 | |
---|
519 | //if rectangular, draw the parallel rectangle lines |
---|
520 | Variable xOffset,yOffset,beta |
---|
521 | if (cmpstr(av_type,"Rectangular")==0) |
---|
522 | beta = (90-phi)*Pi/180 |
---|
523 | xOffset = (width/2)*cos(beta) //need phi in radians |
---|
524 | yOffset = (width/2)*sin(beta) |
---|
525 | if (phi == 0) |
---|
526 | xOffset = 0 |
---|
527 | yOffset = width/2 |
---|
528 | Endif |
---|
529 | if( (cmpstr(side,"left")==0) || (cmpstr(side,"both")==0) ) |
---|
530 | rr = 0 |
---|
531 | gg = 0 |
---|
532 | bb = 50000 |
---|
533 | DrawALineLeft(x0-xOffset,y0+yOffset,phi,rr,gg,bb,thick) |
---|
534 | DrawALineLeft(x0+xOffset,y0-yOffset,phi,rr,gg,bb,thick) |
---|
535 | Endif |
---|
536 | if( (cmpstr(side,"right")==0) || (cmpstr(side,"both")==0) ) |
---|
537 | rr=0 |
---|
538 | gg=0 |
---|
539 | bb=50000 |
---|
540 | DrawALineRight(x0-xOffset,y0+yOffset,phi,rr,gg,bb,thick) |
---|
541 | DrawALineRight(x0+xOffset,y0-yOffset,phi,rr,gg,bb,thick) |
---|
542 | Endif |
---|
543 | Endif |
---|
544 | |
---|
545 | //go back to the average panel |
---|
546 | DoWindow/F Average_Panel |
---|
547 | |
---|
548 | Return 0 |
---|
549 | End |
---|
550 | |
---|
551 | //given beamcenter (x0,y0) and equation of line [slope and intercept] |
---|
552 | //return the point x1 where line leaves the detector image [0,127] on the left side |
---|
553 | Function FindXLeft(x0,y0,slope,intcp) |
---|
554 | Variable x0,y0,slope,intcp |
---|
555 | |
---|
556 | Variable x1=0,yat0 |
---|
557 | NVAR pixelsX = root:myGlobals:gNPixelsX |
---|
558 | NVAR pixelsY = root:myGlobals:gNPixelsY |
---|
559 | |
---|
560 | if (slope == 0) |
---|
561 | x1 = 0 |
---|
562 | return x1 |
---|
563 | endif |
---|
564 | if ((slope == Inf) || (slope == -Inf)) |
---|
565 | x1 = x0 |
---|
566 | return x1 |
---|
567 | Endif |
---|
568 | //else we have to do some math |
---|
569 | //at x=0, what is the y-axis value? |
---|
570 | yat0 = trunc(intcp) |
---|
571 | if( (yat0 >= 0) && (yat0 <=(pixelsY-1)) ) |
---|
572 | //crosses y axis, so x1 = 0 |
---|
573 | x1 = 0 |
---|
574 | else |
---|
575 | //need crossing value |
---|
576 | if (slope > 0) |
---|
577 | x1 = trunc((0-intcp)/slope) |
---|
578 | else |
---|
579 | x1 = trunc((pixelsY-1-intcp)/slope) |
---|
580 | Endif |
---|
581 | Endif |
---|
582 | return x1 |
---|
583 | End |
---|
584 | |
---|
585 | //given beamcenter (x0,y0) and equation of line [slope and intercept] |
---|
586 | //return the point y1 where line leaves the detector image [0,127] on the left side |
---|
587 | Function FindYLeft(x0,y0,slope,intcp) |
---|
588 | Variable x0,y0,slope,intcp |
---|
589 | |
---|
590 | Variable y1=0,yat0 |
---|
591 | |
---|
592 | NVAR pixelsX = root:myGlobals:gNPixelsX |
---|
593 | NVAR pixelsY = root:myGlobals:gNPixelsY |
---|
594 | |
---|
595 | if (slope == 0) |
---|
596 | y1 = y0 |
---|
597 | return y1 |
---|
598 | endif |
---|
599 | if (slope == Inf) |
---|
600 | y1 = 0 |
---|
601 | return y1 |
---|
602 | Endif |
---|
603 | If(slope == -Inf) |
---|
604 | y1 = pixelsY-1 |
---|
605 | return y1 |
---|
606 | Endif |
---|
607 | |
---|
608 | //else we have to do some math |
---|
609 | //at x=0, what is the y-axis value? |
---|
610 | yat0 = trunc(intcp) |
---|
611 | if( (yat0 >= 0) && (yat0 <=(pixelsY-1)) ) |
---|
612 | //crosses y axis, so return y1 |
---|
613 | y1 = yat0 |
---|
614 | else |
---|
615 | //need crossing value |
---|
616 | if (yat0 < 0) |
---|
617 | y1 = 0 |
---|
618 | else |
---|
619 | y1 = pixelsY-1 |
---|
620 | Endif |
---|
621 | Endif |
---|
622 | return y1 |
---|
623 | End |
---|
624 | |
---|
625 | //given beamcenter (x0,y0) and equation of line [slope and intercept] |
---|
626 | //return the point x1 where line leaves the detector image [0,127] on the right side |
---|
627 | Function FindXRight(x0,y0,slope,intcp) |
---|
628 | Variable x0,y0,slope,intcp |
---|
629 | |
---|
630 | Variable x1=0,yat127 |
---|
631 | |
---|
632 | NVAR pixelsX = root:myGlobals:gNPixelsX |
---|
633 | NVAR pixelsY = root:myGlobals:gNPixelsY |
---|
634 | |
---|
635 | if (slope == 0) |
---|
636 | x1 = pixelsX-1 |
---|
637 | return x1 |
---|
638 | endif |
---|
639 | if ((slope == Inf) || (slope == -Inf)) |
---|
640 | x1 = x0 |
---|
641 | return x1 |
---|
642 | Endif |
---|
643 | //else we have to do some math |
---|
644 | //at x=127, what is the y-axis value? |
---|
645 | yat127 = trunc(slope*(pixelsX-1)+intcp) |
---|
646 | if( (yat127 >= 0) && (yat127 <=(pixelsY-1)) ) |
---|
647 | //crosses y=127 edge, so x1 = 127 |
---|
648 | x1 = pixelsX-1 |
---|
649 | else |
---|
650 | //need crossing value |
---|
651 | if (slope > 0) |
---|
652 | x1 = trunc((pixelsX-1-intcp)/slope) |
---|
653 | else |
---|
654 | x1 = trunc((0-intcp)/slope) |
---|
655 | Endif |
---|
656 | Endif |
---|
657 | return x1 |
---|
658 | End |
---|
659 | |
---|
660 | //given beamcenter (x0,y0) and equation of line [slope and intercept] |
---|
661 | //return the point y1 where line leaves the detector image [0,127] on the right side |
---|
662 | Function FindYRight(x0,y0,slope,intcp) |
---|
663 | Variable x0,y0,slope,intcp |
---|
664 | |
---|
665 | Variable y1=0,yat127 |
---|
666 | NVAR pixelsX = root:myGlobals:gNPixelsX |
---|
667 | NVAR pixelsY = root:myGlobals:gNPixelsY |
---|
668 | |
---|
669 | if (slope == 0) |
---|
670 | y1 = y0 |
---|
671 | return y1 |
---|
672 | endif |
---|
673 | if (slope == Inf) |
---|
674 | y1 = pixelsY-1 |
---|
675 | return y1 |
---|
676 | Endif |
---|
677 | If(slope == -Inf) |
---|
678 | y1 = 0 |
---|
679 | return y1 |
---|
680 | Endif |
---|
681 | |
---|
682 | //else we have to do some math |
---|
683 | //at x=127, what is the y-axis value? |
---|
684 | yat127 = trunc(slope*(pixelsX-1)+intcp) |
---|
685 | if( (yat127 >= 0) && (yat127 <=(pixelsY-1)) ) |
---|
686 | //crosses y axis, so return y1 |
---|
687 | y1 = yat127 |
---|
688 | else |
---|
689 | //need crossing value |
---|
690 | if (yat127 < 0) |
---|
691 | y1 = 0 |
---|
692 | else |
---|
693 | y1 = pixelsY-1 |
---|
694 | Endif |
---|
695 | Endif |
---|
696 | return y1 |
---|
697 | End |
---|
698 | |
---|
699 | //draws a circle of radius rad, centered at (x0,y0) |
---|
700 | //line thickness is thick |
---|
701 | // color is (rr,gg,bb) |
---|
702 | Function DrawACircle(x0,y0,rad,rr,gg,bb,thick) |
---|
703 | Variable x0,y0,rad,rr,gg,bb,thick |
---|
704 | |
---|
705 | DoWindow/F SANS_Data |
---|
706 | SetDrawLayer UserFront |
---|
707 | SetDrawEnv xcoord= bottom,ycoord= left,linefgc= (rr,gg,bb),linethick= (thick),fillpat=0 |
---|
708 | DrawOval x0-rad,y0+rad,x0+rad,y0-rad //left,top,right,bottom |
---|
709 | End |
---|
710 | |
---|
711 | //draws a line to the left of the beamcenter (x0,y0) |
---|
712 | //angle is phi |
---|
713 | //thickness is thick |
---|
714 | //color is (rr,gg,bb) |
---|
715 | // function determines where the line will cross the edge of the image, and stops the line there. |
---|
716 | Function DrawALineLeft(x0,y0,phi,rr,gg,bb,thick) |
---|
717 | Variable x0,y0,phi,rr,gg,bb,thick |
---|
718 | |
---|
719 | Variable slope,intcp,x1,y1 |
---|
720 | |
---|
721 | slope = tan(phi*Pi/180) //need arg in radians, not degrees |
---|
722 | if ( phi == 90 ) |
---|
723 | slope = Inf |
---|
724 | Endif |
---|
725 | If (phi == -90) |
---|
726 | slope = -Inf |
---|
727 | Endif |
---|
728 | intcp = y0 - slope * x0 |
---|
729 | x1 = FindXLeft(x0,y0,slope,intcp) |
---|
730 | y1 = FindYLeft(x0,y0,slope,intcp) |
---|
731 | |
---|
732 | DoWindow/F SANS_Data |
---|
733 | SetDrawLayer UserFront |
---|
734 | SetDrawEnv xcoord= bottom,ycoord= left,linefgc= (rr,gg,bb),linethick= (thick) |
---|
735 | DrawLine x0,y0, x1,y1 |
---|
736 | End |
---|
737 | |
---|
738 | //draws a line to the right of the beamcenter (x0,y0) |
---|
739 | //angle is phi |
---|
740 | //thickness is thick |
---|
741 | //color is (rr,gg,bb) |
---|
742 | // function determines where the line will cross the edge of the image, and stops the line there. |
---|
743 | Function DrawALineRight(x0,y0,phi,rr,gg,bb,thick) |
---|
744 | Variable x0,y0,phi,rr,gg,bb,thick |
---|
745 | |
---|
746 | Variable slope,intcp,x1,y1 |
---|
747 | |
---|
748 | slope = tan(phi*Pi/180) //need arg in radians, not degrees |
---|
749 | if ( phi == 90 ) |
---|
750 | slope = Inf |
---|
751 | Endif |
---|
752 | If (phi == -90) |
---|
753 | slope = -Inf |
---|
754 | Endif |
---|
755 | intcp = y0 - slope * x0 |
---|
756 | x1 = FindXRight(x0,y0,slope,intcp) |
---|
757 | y1 = FindYRight(x0,y0,slope,intcp) |
---|
758 | |
---|
759 | DoWindow/F SANS_Data |
---|
760 | SetDrawLayer UserFront |
---|
761 | SetDrawEnv xcoord= bottom,ycoord= left,linefgc= (rr,gg,bb),linethick= (thick) |
---|
762 | DrawLine x0,y0, x1,y1 |
---|
763 | End |
---|
764 | |
---|
765 | //reads the value from the panel and updates the global string |
---|
766 | // redraws the appropriate line on the image |
---|
767 | Function DeltaPhiSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl |
---|
768 | String ctrlName |
---|
769 | Variable varNum |
---|
770 | String varStr |
---|
771 | String varName |
---|
772 | |
---|
773 | ControlInfo/W=Average_Panel dphi_p |
---|
774 | Variable dphi = V_Value |
---|
775 | SVAR tempStr = root:myGlobals:Drawing:gDrawInfoStr |
---|
776 | String newStr = ReplaceNumberByKey("DPHI", tempStr, dphi, "=", ";") |
---|
777 | |
---|
778 | String/G root:myGlobals:Drawing:gDrawInfoStr = newStr |
---|
779 | |
---|
780 | //redraw the angles |
---|
781 | MasterAngleDraw() |
---|
782 | End |
---|
783 | |
---|
784 | //reads the value from the panel and updates the global string |
---|
785 | // redraws the appropriate line on the image |
---|
786 | Function QDeltaSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl |
---|
787 | String ctrlName |
---|
788 | Variable varNum |
---|
789 | String varStr |
---|
790 | String varName |
---|
791 | |
---|
792 | ControlInfo/W=Average_Panel QDelta_p |
---|
793 | Variable dq = V_Value |
---|
794 | SVAR tempStr = root:myGlobals:Drawing:gDrawInfoStr |
---|
795 | String newStr = ReplaceNumberByKey("QDELTA", tempStr, dq, "=", ";") |
---|
796 | |
---|
797 | String/G root:myGlobals:Drawing:gDrawInfoStr = newStr |
---|
798 | |
---|
799 | //redraw the angles |
---|
800 | MasterAngleDraw() |
---|
801 | End |
---|
802 | |
---|
803 | //reads the value from the panel and updates the global string |
---|
804 | // redraws the appropriate line on the image |
---|
805 | Function QctrSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl |
---|
806 | String ctrlName |
---|
807 | Variable varNum |
---|
808 | String varStr |
---|
809 | String varName |
---|
810 | |
---|
811 | ControlInfo/W=Average_Panel QCtr_p |
---|
812 | Variable ctr = V_Value |
---|
813 | SVAR tempStr = root:myGlobals:Drawing:gDrawInfoStr |
---|
814 | String newStr = ReplaceNumberByKey("QCENTER", tempStr, ctr, "=", ";") |
---|
815 | |
---|
816 | String/G root:myGlobals:Drawing:gDrawInfoStr = newStr |
---|
817 | |
---|
818 | //redraw the angles |
---|
819 | MasterAngleDraw() |
---|
820 | End |
---|
821 | |
---|
822 | //reads the value from the panel and updates the global string |
---|
823 | // redraws the appropriate line on the image |
---|
824 | Function WidthSetVarProc(ctrlName,varNum,varStr,varName) : SetVariableControl |
---|
825 | String ctrlName |
---|
826 | Variable varNum |
---|
827 | String varStr |
---|
828 | String varName |
---|
829 | |
---|
830 | ControlInfo/W=Average_Panel width_p |
---|
831 | Variable val = V_Value |
---|
832 | SVAR tempStr = root:myGlobals:Drawing:gDrawInfoStr |
---|
833 | String newStr = ReplaceNumberByKey("WIDTH", tempStr, val, "=", ";") |
---|
834 | |
---|
835 | String/G root:myGlobals:Drawing:gDrawInfoStr = newStr |
---|
836 | |
---|
837 | //redraw the angles |
---|
838 | MasterAngleDraw() |
---|
839 | End |
---|
840 | |
---|
841 | //function is called directly by averaging routines to display the averaged data |
---|
842 | //copies the newly averaged data (finds the data folder from the parameter waves) |
---|
843 | //the the copied data can be rescaled without disturbing the original data |
---|
844 | // |
---|
845 | // brings the plot_1d to the front |
---|
846 | // if no window, create the folder and globals |
---|
847 | // update the data |
---|
848 | // |
---|
849 | //there is a separate function for annular averages (I vs phi) |
---|
850 | Function Avg_1D_Graph(aveint,qval,sigave) |
---|
851 | Wave aveint,qval,sigave |
---|
852 | |
---|
853 | if(! DataFolderExists("root:myGlobals:plot_1d")) |
---|
854 | Init_Plot1d() |
---|
855 | endif |
---|
856 | |
---|
857 | // String curPath = GetWavesDataFolder(aveint,1) |
---|
858 | String CurPath="root:myGlobals:Plot_1D:" |
---|
859 | |
---|
860 | Duplicate/O aveint $(curPath+"yAxisWave") |
---|
861 | Duplicate/O sigave $(curPath+"yErrWave") |
---|
862 | Duplicate/O qval $(curPath+"xAxisWave") |
---|
863 | Wave yAxisWave=$(curPath+"yAxisWave") |
---|
864 | Wave xAxisWave=$(curPath+"xAxisWave") |
---|
865 | Wave yErrWave=$(curPath+"yErrWave") |
---|
866 | |
---|
867 | Variable/G root:myGlobals:Plot_1d:isPhiAve=0 //0 signifies (normal) x=qvals |
---|
868 | //make a completely new graph |
---|
869 | Draw_Plot1D(xAxisWave,yAxisWave,YErrWave) |
---|
870 | |
---|
871 | return(0) |
---|
872 | End |
---|
873 | |
---|
874 | //function is called directly by averaging routines to display the averaged data |
---|
875 | //copies the newly averaged data (finds the data folder from the parameter waves) |
---|
876 | //the the copied data can be rescaled without disturbing the original data |
---|
877 | // |
---|
878 | // brings the plot_1d to the front |
---|
879 | // if no window, create the folder and globals |
---|
880 | // update the data |
---|
881 | // |
---|
882 | Function Ann_1D_Graph(aveint,phival,sigave) |
---|
883 | Wave aveint,phival,sigave |
---|
884 | |
---|
885 | if(! DataFolderExists("root:myGlobals:plot_1d")) |
---|
886 | Init_Plot1d() |
---|
887 | endif |
---|
888 | // String curPath = GetWavesDataFolder(aveint,1) |
---|
889 | String CurPath="root:myGlobals:Plot_1D:" |
---|
890 | |
---|
891 | Duplicate/O aveint $(curPath+"yAxisWave") |
---|
892 | Duplicate/O sigave $(curPath+"yErrWave") |
---|
893 | Duplicate/O phival $(curPath+"xAxisWave") |
---|
894 | Wave yAxisWave=$(curPath+"yAxisWave") |
---|
895 | Wave xAxisWave=$(curPath+"xAxisWave") |
---|
896 | Wave yErrWave=$(curPath+"yErrWave") |
---|
897 | |
---|
898 | Variable/G root:myGlobals:Plot_1d:isPhiAve=1 //1 signifies x=phival |
---|
899 | //make a completely new graph |
---|
900 | Draw_Plot1D(xAxisWave,yAxisWave,YErrWave) |
---|
901 | |
---|
902 | return(0) |
---|
903 | End |
---|
904 | |
---|
905 | //initializes the scaling exponents and x-axis flag used in the control bar of the |
---|
906 | //plot_1d graph |
---|
907 | // ! keep the user-defined values when re-creating the graph, so don't re-initialize the globals |
---|
908 | Function Init_Plot1d() |
---|
909 | NewDataFolder/O/S root:myGlobals:Plot_1d |
---|
910 | NVAR/Z gExpA=gExpA |
---|
911 | NVAR/Z gExpB=gExpB |
---|
912 | NVAR/Z gExpC=gExpC |
---|
913 | NVAR/Z gXMode=gXMode |
---|
914 | NVAR/Z gYMode=gYMode |
---|
915 | if(!NVAR_Exists(gExpA)) |
---|
916 | Variable/G gExpA=1 |
---|
917 | endif |
---|
918 | if(!NVAR_Exists(gExpB)) |
---|
919 | Variable/G gExpB=1 |
---|
920 | endif |
---|
921 | if(!NVAR_Exists(gExpC)) |
---|
922 | Variable/G gExpC=1 |
---|
923 | endif |
---|
924 | //keep preferences of the display mode (axis scaling) |
---|
925 | if(!NVAR_Exists(gXMode)) |
---|
926 | Variable/G gXMode=1 |
---|
927 | endif |
---|
928 | if(!NVAR_Exists(gYMode)) |
---|
929 | Variable/G gYMode=1 |
---|
930 | endif |
---|
931 | Variable/G isPhiAve=0 //0= vs Q, 1= vs phi, alway set properly as needed by the Avg_ or Ann_1D_Graph() |
---|
932 | SetDataFolder root: |
---|
933 | End |
---|
934 | |
---|
935 | //function responsible for drawing the 1D plot, given the three necessary waves |
---|
936 | // x-axis label is determined from global "isPhiAve" switch |
---|
937 | // |
---|
938 | // plot type is recalled through globals |
---|
939 | // |
---|
940 | Function Draw_Plot1D(xw,yw,ew) |
---|
941 | Wave xw,yw,ew |
---|
942 | |
---|
943 | if(! DataFolderExists("root:myGlobals:plot_1d")) |
---|
944 | Init_Plot1d() |
---|
945 | endif |
---|
946 | DoWindow/F Plot_1d |
---|
947 | if(V_flag==1) |
---|
948 | //do nothing |
---|
949 | else |
---|
950 | Display /W=(476,96,850,429) /K=1 yw vs xw |
---|
951 | DoWindow/C Plot_1d |
---|
952 | DoWindow/T Plot_1d,"Averaged Data" |
---|
953 | ModifyGraph marker=19 |
---|
954 | ModifyGraph mode=3,msize=2,rgb=(65535,0,0) |
---|
955 | // |
---|
956 | String list=TraceNameList("",";", 1) |
---|
957 | String yname=StringFromList(0, list,";") |
---|
958 | ErrorBars/T=0 $yname Y,wave=(ew,ew) |
---|
959 | ModifyGraph grid=1 |
---|
960 | ModifyGraph log=0 |
---|
961 | ModifyGraph mirror=2 |
---|
962 | ModifyGraph standoff=0 |
---|
963 | ModifyGraph tickUnit=1 |
---|
964 | ControlBar 70 |
---|
965 | PopupMenu ymodel,pos={16,5},size={71,20},title="y-axis" |
---|
966 | PopupMenu ymodel,help={"This popup selects how the y-axis will be linearized based on the chosen data"} |
---|
967 | PopupMenu ymodel,value= #"\"I;log(I);ln(I);1/I;I^a;Iq^a;I^a q^b;1/sqrt(I);ln(Iq);ln(Iq^2)\"" |
---|
968 | PopupMenu ymodel,mode=NumVarOrDefault("root:myGlobals:Plot_1d:gYMode", 1 ),proc=YMode_PopMenuProc |
---|
969 | Button Rescale,pos={281,4},size={70,20},proc=Rescale_Plot_1D_ButtonProc,title="Rescale" |
---|
970 | Button Rescale,help={"Rescale the x and y-axes of the data"},disable=1 |
---|
971 | Button AllQ,pos={281,28},size={70,20},proc=AllQ_Plot_1D_ButtonProc,title="All Q" |
---|
972 | Button AllQ,help={"Show the full q-range of the dataset"} |
---|
973 | SetVariable expa,pos={28,28},size={80,15},title="pow \"a\"" |
---|
974 | SetVariable expa,help={"This sets the exponent \"a\" for some y-axis formats. The value is ignored if the model does not use an adjustable exponent"} |
---|
975 | SetVariable expa,limits={-2,10,0},value= root:myGlobals:Plot_1d:gExpA |
---|
976 | SetVariable expb,pos={27,46},size={80,15},title="pow \"b\"" |
---|
977 | SetVariable expb,help={"This sets the exponent \"b\" for some x-axis formats. The value is ignored if the model does not use an adjustable exponent"} |
---|
978 | SetVariable expb,limits={0,10,0},value= root:myGlobals:Plot_1d:gExpB |
---|
979 | PopupMenu xmodel,pos={150,5},size={74,20},title="x-axis" |
---|
980 | PopupMenu xmodel,help={"This popup selects how the x-axis will be linearized given the chosen data"} |
---|
981 | PopupMenu xmodel,value= #"\"q;log(q);q^2;q^c\"" |
---|
982 | PopupMenu xmodel,mode=NumVarOrDefault("root:myGlobals:Plot_1d:gXMode", 1 ),proc=XMode_PopMenuProc |
---|
983 | SetVariable expc,pos={167,28},size={80,15},title="pow \"c\"" |
---|
984 | SetVariable expc,help={"This sets the exponent \"c\" for some x-axis formats. The value is ignored if the model does not use \"c\" as an adjustable exponent"} |
---|
985 | SetVariable expc,limits={-10,10,0},value= root:myGlobals:Plot_1d:gExpC |
---|
986 | |
---|
987 | endif |
---|
988 | NVAR isPhiAve= root:myGlobals:Plot_1d:isPhiAve //0 signifies (normal) x=qvals |
---|
989 | Label left "I(q)" |
---|
990 | if(isPhiAve) |
---|
991 | Label bottom "Angle (deg)" |
---|
992 | else |
---|
993 | SVAR angst = root:myGlobals:gAngstStr |
---|
994 | Label bottom "q ("+angst+"\\S-1\\M)" |
---|
995 | Endif |
---|
996 | //force a rescale to get something other than I vs. q |
---|
997 | Rescale_Plot_1D_ButtonProc("") |
---|
998 | End |
---|
999 | |
---|
1000 | //function to set the popItem (mode) of the graph, to re-create the graph based on user preferences |
---|
1001 | Function YMode_PopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl |
---|
1002 | String ctrlName |
---|
1003 | Variable popNum |
---|
1004 | String popStr |
---|
1005 | |
---|
1006 | Variable/G root:myGlobals:Plot_1d:gYMode=popNum |
---|
1007 | Rescale_Plot_1D_ButtonProc("") |
---|
1008 | End |
---|
1009 | |
---|
1010 | //function to set the popItem (mode) of the graph, to re-create the graph based on user preferences |
---|
1011 | Function XMode_PopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl |
---|
1012 | String ctrlName |
---|
1013 | Variable popNum |
---|
1014 | String popStr |
---|
1015 | |
---|
1016 | Variable/G root:myGlobals:Plot_1d:gXMode=popNum |
---|
1017 | Rescale_Plot_1D_ButtonProc("") |
---|
1018 | End |
---|
1019 | |
---|
1020 | //function to restore the graph axes to full scale, undoing any zooming |
---|
1021 | Function AllQ_Plot_1D_ButtonProc(ctrlName) : ButtonControl |
---|
1022 | String ctrlName |
---|
1023 | |
---|
1024 | DoWindow/F Plot_1d |
---|
1025 | SetAxis/A |
---|
1026 | End |
---|
1027 | |
---|
1028 | //function to rescale the axes of the graph as selected from the popups and the |
---|
1029 | // entered values of the exponents |
---|
1030 | //** assumes the current waves are unknown, so it goes and gets a "fresh" copy from |
---|
1031 | //the data folder specified by the waves on the graph, which is the same folder that |
---|
1032 | //contains the "fresh" copy of the 1D data |
---|
1033 | // |
---|
1034 | // for log(10) scaling, simply modify the axes, not the data - gives better plots |
---|
1035 | // |
---|
1036 | Function Rescale_Plot_1D_ButtonProc(ctrlName) : ButtonControl |
---|
1037 | String ctrlName |
---|
1038 | |
---|
1039 | DoWindow/F Plot_1d |
---|
1040 | //Scaling exponents and background value |
---|
1041 | Variable pow_a,pow_b,pow_c |
---|
1042 | ControlInfo expa |
---|
1043 | pow_a = V_value |
---|
1044 | ControlInfo expb |
---|
1045 | pow_b = V_value |
---|
1046 | ControlInfo expc |
---|
1047 | pow_c = V_value |
---|
1048 | |
---|
1049 | //check for physical limits on exponent values, abort if bad values found |
---|
1050 | if((pow_a < -2) || (pow_a > 10)) |
---|
1051 | Abort "Exponent a must be in the range (-2,10)" |
---|
1052 | endif |
---|
1053 | if((pow_b < 0) || (pow_b > 10)) |
---|
1054 | Abort "Exponent b must be in the range (0,10)" |
---|
1055 | endif |
---|
1056 | //if q^c is the x-scaling, c must be be within limits and also non-zero |
---|
1057 | ControlInfo xModel |
---|
1058 | If (cmpstr("q^c",S_Value) == 0) |
---|
1059 | if(pow_c == 0) |
---|
1060 | Abort "Exponent c must be non-zero, q^0 = 1" |
---|
1061 | endif |
---|
1062 | if((pow_c < -10) || (pow_c > 10)) |
---|
1063 | Abort "Exponent c must be in the range (-10,10)" |
---|
1064 | endif |
---|
1065 | endif //check q^c exponent |
---|
1066 | |
---|
1067 | // get the current experimental q, I, and std dev. waves |
---|
1068 | |
---|
1069 | //!! get the wave path from the window and construct the necessary wave |
---|
1070 | //references to the unmodified, averaged data (qval, aveint) |
---|
1071 | //and use these to modify the (xAxisWave,YAxisWave) that are on the graph |
---|
1072 | String dfSav = GetDataFolder(1) |
---|
1073 | //String curPath = GetWavesDataFolder(WaveRefIndexed("",0,1),1) //path for the first y-wave on the graph |
---|
1074 | SVAR curFolder=root:myGlobals:gDataDisplayType |
---|
1075 | |
---|
1076 | // SetDataFolder curPath |
---|
1077 | //get the untarnished data, so we can rescale it freshly here |
---|
1078 | Wave yw = $("root:Packages:NIST:"+curFolder+":aveint") |
---|
1079 | Wave ew = $("root:Packages:NIST:"+curFolder+":sigave") |
---|
1080 | //get the correct x values |
---|
1081 | NVAR isPhiAve= root:myGlobals:Plot_1d:isPhiAve //0 signifies (normal) x=qvals |
---|
1082 | if(isPhiAve) |
---|
1083 | //x is angle |
---|
1084 | Wave xw=$("root:Packages:NIST:"+curFolder+":phival") |
---|
1085 | else |
---|
1086 | //x is q-values |
---|
1087 | Wave xw=$("root:Packages:NIST:"+curFolder+":qval") |
---|
1088 | endif |
---|
1089 | Wave yAxisWave=root:myGlobals:Plot_1d:yAxisWave //refs to waves to be modified, hard-wired positions |
---|
1090 | Wave xAxisWave=root:myGlobals:Plot_1d:xAxisWave |
---|
1091 | Wave yErrWave=root:myGlobals:Plot_1d:yErrWave |
---|
1092 | |
---|
1093 | //variables set for each model to control look of graph |
---|
1094 | String xlabel,ylabel,xstr,ystr |
---|
1095 | Variable logLeft=0,logBottom=0 |
---|
1096 | //check for proper y-scaling selection, make the necessary waves |
---|
1097 | ControlInfo yModel |
---|
1098 | ystr = S_Value |
---|
1099 | do |
---|
1100 | If (cmpstr("I",S_Value) == 0) |
---|
1101 | SetScale d 0,0,"1/cm",yAxisWave |
---|
1102 | yErrWave = ew |
---|
1103 | yAxisWave = yw |
---|
1104 | ylabel = "I(q)" |
---|
1105 | break |
---|
1106 | endif |
---|
1107 | If (cmpstr("ln(I)",S_Value) == 0) |
---|
1108 | SetScale d 0,0,"",yAxisWave |
---|
1109 | yErrWave = ew/yw |
---|
1110 | yAxisWave = ln(yw) |
---|
1111 | ylabel = "ln(I)" |
---|
1112 | break |
---|
1113 | endif |
---|
1114 | If (cmpstr("log(I)",S_Value) == 0) |
---|
1115 | SetScale d 0,0,"",yAxisWave |
---|
1116 | yAxisWave = yw |
---|
1117 | yErrWave = ew |
---|
1118 | logLeft=1 //scale the axis, not the wave |
---|
1119 | ylabel = "I(q)" |
---|
1120 | // yErrWave = ew/(2.30*yw) |
---|
1121 | // yAxisWave = log(yw) |
---|
1122 | // ylabel = "log(I)" |
---|
1123 | break |
---|
1124 | endif |
---|
1125 | If (cmpstr("1/I",S_Value) == 0) |
---|
1126 | SetScale d 0,0,"",yAxisWave |
---|
1127 | yErrWave = ew/yw^2 |
---|
1128 | yAxisWave = 1/yw |
---|
1129 | ylabel = "1/I" |
---|
1130 | break |
---|
1131 | endif |
---|
1132 | If (cmpstr("I^a",S_Value) == 0) |
---|
1133 | SetScale d 0,0,"",yAxisWave |
---|
1134 | yErrWave = ew*abs(pow_a*(yw^(pow_a-1))) |
---|
1135 | yAxisWave = yw^pow_a |
---|
1136 | ylabel = "I^"+num2str(pow_a) |
---|
1137 | break |
---|
1138 | endif |
---|
1139 | If (cmpstr("Iq^a",S_Value) == 0) |
---|
1140 | SetScale d 0,0,"",yAxisWave |
---|
1141 | yErrWave = ew*xw^pow_a |
---|
1142 | yAxisWave = yw*xw^pow_a |
---|
1143 | ylabel = "I*q^"+num2str(pow_a) |
---|
1144 | break |
---|
1145 | endif |
---|
1146 | If (cmpstr("I^a q^b",S_Value) == 0) |
---|
1147 | SetScale d 0,0,"",yAxisWave |
---|
1148 | yErrWave = ew*abs(pow_a*(yw^(pow_a-1)))*xw^pow_b |
---|
1149 | yAxisWave = yw^pow_a*xw^pow_b |
---|
1150 | ylabel = "I^" + num2str(pow_a) + "q^"+num2str(pow_b) |
---|
1151 | break |
---|
1152 | endif |
---|
1153 | If (cmpstr("1/sqrt(I)",S_Value) == 0) |
---|
1154 | SetScale d 0,0,"",yAxisWave |
---|
1155 | yErrWave = 0.5*ew*yw^(-1.5) |
---|
1156 | yAxisWave = 1/sqrt(yw) |
---|
1157 | ylabel = "1/sqrt(I)" |
---|
1158 | break |
---|
1159 | endif |
---|
1160 | If (cmpstr("ln(Iq)",S_Value) == 0) |
---|
1161 | SetScale d 0,0,"",yAxisWave |
---|
1162 | yErrWave =ew/yw |
---|
1163 | yAxisWave = ln(xw*yw) |
---|
1164 | ylabel = "ln(q*I)" |
---|
1165 | break |
---|
1166 | endif |
---|
1167 | If (cmpstr("ln(Iq^2)",S_Value) == 0) |
---|
1168 | SetScale d 0,0,"",yAxisWave |
---|
1169 | yErrWave = ew/yw |
---|
1170 | yAxisWave = ln(xw*xw*yw) |
---|
1171 | ylabel = "ln(I*q^2)" |
---|
1172 | break |
---|
1173 | endif |
---|
1174 | //more ifs for each case as they are added |
---|
1175 | |
---|
1176 | // if selection not found, abort |
---|
1177 | DoAlert 0,"Y-axis scaling incorrect. Aborting" |
---|
1178 | Abort |
---|
1179 | while(0) //end of "case" statement for y-axis scaling |
---|
1180 | |
---|
1181 | //check for proper x-scaling selection |
---|
1182 | SVAR angst = root:myGlobals:gAngstStr |
---|
1183 | String dum |
---|
1184 | |
---|
1185 | ControlInfo xModel |
---|
1186 | xstr = S_Value |
---|
1187 | do |
---|
1188 | If (cmpstr("q",S_Value) == 0) |
---|
1189 | SetScale d 0,0,"",xAxisWave |
---|
1190 | xAxisWave = xw |
---|
1191 | if(isPhiAve) |
---|
1192 | xlabel="Angle (deg)" |
---|
1193 | else |
---|
1194 | xlabel = "q ("+angst+"\\S-1\\M)" |
---|
1195 | endif |
---|
1196 | break |
---|
1197 | endif |
---|
1198 | If (cmpstr("q^2",S_Value) == 0) |
---|
1199 | SetScale d 0,0,"",xAxisWave |
---|
1200 | xAxisWave = xw*xw |
---|
1201 | if(isPhiAve) |
---|
1202 | xlabel="(Angle (deg) )^2" |
---|
1203 | else |
---|
1204 | xlabel = "q^2 ("+angst+"\\S-2\\M)" |
---|
1205 | endif |
---|
1206 | break |
---|
1207 | endif |
---|
1208 | If (cmpstr("log(q)",S_Value) == 0) |
---|
1209 | SetScale d 0,0,"",xAxisWave |
---|
1210 | xAxisWave = xw //scale the axis, not the wave |
---|
1211 | //xAxisWave = log(xw) |
---|
1212 | logBottom=1 |
---|
1213 | if(isPhiAve) |
---|
1214 | //xlabel="log(Angle (deg))" |
---|
1215 | xlabel="Angle (deg)" |
---|
1216 | else |
---|
1217 | //xlabel = "log(q)" |
---|
1218 | xlabel = "q ("+angst+"\\S-1\\M)" |
---|
1219 | endif |
---|
1220 | break |
---|
1221 | endif |
---|
1222 | If (cmpstr("q^c",S_Value) == 0) |
---|
1223 | SetScale d 0,0,"",xAxisWave |
---|
1224 | xAxisWave = xw^pow_c |
---|
1225 | dum = num2str(pow_c) |
---|
1226 | if(isPhiAve) |
---|
1227 | xlabel="Angle^"+dum |
---|
1228 | else |
---|
1229 | xlabel = "q^"+dum+" ("+angst+"\\S-"+dum+"\\M)" |
---|
1230 | endif |
---|
1231 | break |
---|
1232 | endif |
---|
1233 | |
---|
1234 | //more ifs for each case |
---|
1235 | |
---|
1236 | // if selection not found, abort |
---|
1237 | DoAlert 0,"X-axis scaling incorrect. Aborting" |
---|
1238 | Abort |
---|
1239 | while(0) //end of "case" statement for x-axis scaling |
---|
1240 | |
---|
1241 | Label left ylabel |
---|
1242 | Label bottom xlabel //E denotes "scaling" - may want to use "units" instead |
---|
1243 | ModifyGraph log(left)=(logLeft) |
---|
1244 | ModifyGraph log(bottom)=(logBottom) |
---|
1245 | |
---|
1246 | End |
---|