source: sans/Dev/branches/elliptical_averaging/NCNR_User_Procedures/Reduction/SANS/AvgGraphics.ipf @ 1212

Last change on this file since 1212 was 1212, checked in by krzywon, 3 years ago

Combine elliptical averaging with circular averaging and wrote the binning routine. Need to verify calculations and fix issues with elliptical drawing routine.

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