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

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

Add an ellipse drawing tool that (mostly) works, and start on the elliptical averaging algorithm.

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