source: sans/Dev/trunk/NCNR_User_Procedures/Common/Packages/PlotManager/PlotUtils2D_v40.ipf @ 670

Last change on this file since 670 was 665, checked in by srkline, 13 years ago

Made preferences a common panel (moved to PlotUtilsMacro?.ipf and globals to root:Packages:NIST:) and added menu items for all packages. Many files had to be modified so that the preferences could be properly accessed

File Open dialog now is set to "All files" so that XML can be selected. I think that all open access that doesn't already have the full path go through this common function.

File size: 26.6 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=4.00
3#pragma IgorVersion=6.1
4
5//
6// WARNING: there are a lot of assumptions that went into this code at the first pass
7// that will need to be made generic before a release to the wild
8//
9//
10// - some manipulations assume a square matrix
11// - naming schemes are assumed (to be documented)
12//
13//
14
15
16//
17// changed May 2009 to read in the resolution information (now 7 columns)
18// -- subject to change --
19//
20Proc LoadQxQy()
21
22        LoadWave/G/D/W/A
23        String fileName = S_fileName
24        String path = S_Path
25        Variable numCols = V_flag
26
27        String w0,w1,w2,n0,n1,n2
28        String w3,w4,w5,w6,n3,n4,n5,n6
29               
30        // put the names of the three loaded waves into local names
31        n0 = StringFromList(0, S_waveNames ,";" )
32        n1 = StringFromList(1, S_waveNames ,";" )
33        n2 = StringFromList(2, S_waveNames ,";" )
34        n3 = StringFromList(3, S_waveNames ,";" )
35        n4 = StringFromList(4, S_waveNames ,";" )
36        n5 = StringFromList(5, S_waveNames ,";" )
37        n6 = StringFromList(6, S_waveNames ,";" )
38       
39        //remove the semicolon AND period from files from the VAX
40        w0 = CleanupName((S_fileName + "_qx"),0)
41        w1 = CleanupName((S_fileName + "_qy"),0)
42        w2 = CleanupName((S_fileName + "_i"),0)
43        w3 = CleanupName((S_fileName + "_qz"),0)
44        w4 = CleanupName((S_fileName + "_sigQx"),0)
45        w5 = CleanupName((S_fileName + "_sigQy"),0)
46        w6 = CleanupName((S_fileName + "_fs"),0)
47
48        String baseStr=w1[0,strlen(w1)-4]
49        if(DataFolderExists("root:"+baseStr))
50                        DoAlert 1,"The file "+S_filename+" has already been loaded. Do you want to load the new data file, overwriting the data in memory?"
51                        if(V_flag==2)   //user selected No, don't load the data
52                                SetDataFolder root:
53                                KillWaves $n0,$n1,$n2,$n3,$n4,$n5,$n6           // kill the default waveX that were loaded
54                                return          //quits the macro
55                        endif
56                        SetDataFolder $("root:"+baseStr)
57        else
58                NewDataFolder/S $("root:"+baseStr)
59        endif
60       
61        //read in the 18 lines of header (18th line starts w/ ASCII... 19th line is blank)
62        Make/O/T/N=18 header
63        Variable refnum,ii
64        string tmpStr=""
65        Open/R refNum  as (path+filename)
66        ii=0
67        do
68                tmpStr = ""
69                FReadLine refNum, tmpStr
70                header[ii] = tmpStr
71                ii+=1
72        while(ii < 18)         
73        Close refnum
74       
75        // ? parse to get nice variable names? put these in a structure just for fun?
76       
77       
78        ////overwrite the existing data, if it exists
79        Duplicate/O $("root:"+n0), $w0
80        Duplicate/O $("root:"+n1), $w1
81        Duplicate/O $("root:"+n2), $w2
82        Duplicate/O $("root:"+n3), $w3
83        Duplicate/O $("root:"+n4), $w4
84        Duplicate/O $("root:"+n5), $w5
85        Duplicate/O $("root:"+n6), $w6
86       
87        Variable/G gIsLogScale = 0
88       
89        Variable num=numpnts($w0)
90        // assume that the Q-grid is "uniform enough" for DISPLAY ONLY
91        // use the 3 original waves for all of the fitting...
92        ConvertQxQy2Mat($w0,$w1,$w2,baseStr+"_mat")
93        Duplicate/O $(baseStr+"_mat"),$(baseStr+"_lin")                 //keep a linear-scaled version of the data
94       
95        PlotQxQy(baseStr)               //this sets the data folder back to root:!!
96       
97        //don't create the triplet - not really of much use
98//      Make/D/O/N=(num,3) $(baseStr+"_tri")
99//      $(baseStr+"_tri")[][0] = $w0[p]         // Qx
100//      $(baseStr+"_tri")[][1] = $w1[p]         // Qy
101//      $(baseStr+"_tri")[][2] = $w2[p]         // Intensity
102
103        //clean up             
104        SetDataFolder root:
105        KillWaves/Z $n0,$n1,$n2,$n3,$n4,$n5,$n6
106EndMacro
107
108//does not seem to need to be flipped at all from the standard QxQy output
109//
110// plots the data, as surface0, YellowHot color table
111//
112Proc PlotQxQy(str)
113        String str
114        Prompt str,"Pick the data folder containing 2D data",popup,getAList(4)
115
116        PauseUpdate; Silent 1   // Building Gizmo 6 window...
117
118        // Do nothing if the Gizmo XOP is not available.
119        if(exists("NewGizmo")!=4)
120                DoAlert 0, "Gizmo XOP must be installed"
121                return
122        endif
123
124        String data = "root:"+str+":"+str+"_mat"
125       
126        NewGizmo/N=$str/T=str /W=(169,44,495,359)
127        ModifyGizmo startRecMacro
128        AppendToGizmo Surface=$data,name=surface0
129
130        // for constant color (data is a blue color, lighter on the bottom)
131//      ModifyGizmo ModifyObject=surface0 property={ surfaceColorType,1}
132//      ModifyGizmo ModifyObject=surface0 property={ srcMode,0}
133//      ModifyGizmo ModifyObject=surface0 property={ frontColor,0.749996,0.811093,1,1}
134//      ModifyGizmo ModifyObject=surface0 property={ backColor,0.250019,0.433326,1,1}
135        //e constant color
136       
137        //for color table       
138        ModifyGizmo ModifyObject=surface0 property={ srcMode,0}
139//      ModifyGizmo ModifyObject=surface0 property={ surfaceCTab,Blue}
140        ModifyGizmo ModifyObject=surface0 property={ surfaceCTab,ColdWarm}
141        ModifyGizmo ModifyObject=surface0 property={ SurfaceCTABScaling,4}
142        //e color table
143       
144        AppendToGizmo Axes=boxAxes,name=axes0
145        ModifyGizmo ModifyObject=axes0,property={0,axisRange,-1,-1,-1,1,-1,-1}
146        ModifyGizmo ModifyObject=axes0,property={1,axisRange,-1,-1,-1,-1,1,-1}
147        ModifyGizmo ModifyObject=axes0,property={2,axisRange,-1,-1,-1,-1,-1,1}
148        ModifyGizmo ModifyObject=axes0,property={3,axisRange,-1,1,-1,-1,1,1}
149        ModifyGizmo ModifyObject=axes0,property={4,axisRange,1,1,-1,1,1,1}
150        ModifyGizmo ModifyObject=axes0,property={5,axisRange,1,-1,-1,1,-1,1}
151        ModifyGizmo ModifyObject=axes0,property={6,axisRange,-1,-1,1,-1,1,1}
152        ModifyGizmo ModifyObject=axes0,property={7,axisRange,1,-1,1,1,1,1}
153        ModifyGizmo ModifyObject=axes0,property={8,axisRange,1,-1,-1,1,1,-1}
154        ModifyGizmo ModifyObject=axes0,property={9,axisRange,-1,1,-1,1,1,-1}
155        ModifyGizmo ModifyObject=axes0,property={10,axisRange,-1,1,1,1,1,1}
156        ModifyGizmo ModifyObject=axes0,property={11,axisRange,-1,-1,1,1,-1,1}
157        ModifyGizmo ModifyObject=axes0,property={-1,axisScalingMode,1}
158        ModifyGizmo ModifyObject=axes0,property={-1,axisColor,0,0,0,1}
159        ModifyGizmo ModifyObject=axes0,property={0,ticks,3}
160        ModifyGizmo ModifyObject=axes0,property={1,ticks,3}
161        ModifyGizmo ModifyObject=axes0,property={2,ticks,3}
162        ModifyGizmo ModifyObject=axes0,property={0,fontScaleFactor,1.5}
163        ModifyGizmo ModifyObject=axes0,property={1,fontScaleFactor,1.5}
164        ModifyGizmo ModifyObject=axes0,property={2,fontScaleFactor,1.5}
165        AppendToGizmo freeAxesCue={0,0,0,1.5},name=freeAxesCue0
166        ModifyGizmo setDisplayList=0, opName=clearColor0, operation=clearColor, data={1,0.917,0.75,1}
167        ModifyGizmo setDisplayList=1, object=surface0
168        ModifyGizmo setDisplayList=2, object=axes0
169        ModifyGizmo setDisplayList=3, object=freeAxesCue0
170        ModifyGizmo SETQUATERNION={0.521287,-0.097088,-0.138769,0.836408}
171        ModifyGizmo autoscaling=1
172        ModifyGizmo currentGroupObject=""
173        ModifyGizmo compile
174
175        ModifyGizmo NamedHook={GizmoContours,WMGizmoContoursNamedHook}
176        ModifyGizmo endRecMacro
177       
178// don't bother with the flat image plot right now
179       
180//      Display $yw vs $xw
181//      modifygraph log=0
182//      ModifyGraph mode=3,marker=16,zColor($yw)={$zw,*,*,YellowHot,0}
183//      ModifyGraph standoff=0
184//      ModifyGraph width={Aspect,1}
185//      ModifyGraph lowTrip=0.001
186
187End
188
189Proc FakeQxQy(minQx,maxQx,minQy,maxQy,numPix,dataFolder)
190        Variable minQx=-0.1,maxQx=0.1,minQy=-0.1,maxQy=0.1
191        Variable numPix=64
192        String dataFolder="fake2DData"
193
194        String baseStr=dataFolder
195       
196
197        if(DataFolderExists("root:"+baseStr))
198                        DoAlert 1,"Fake data "+baseStr+" has already been created. Do you want to overwrite this fake data set?"
199                        if(V_flag==2)   //user selected No, don't load the data
200                                SetDataFolder root:
201                                return          //quits the macro
202                        endif
203                        SetDataFolder $("root:"+baseStr)
204        else
205                NewDataFolder/S $("root:"+baseStr)
206        endif
207
208        Make/O/D/N=(numPix*numPix) $(baseStr+"_qx"),$(baseStr+"_qy"),$(baseStr+"_i")
209       
210        $(baseStr+"_i") = 1
211       
212        Make/O/D/N=(numPix) tmpX,tmpY
213       
214        variable delX,delY
215        delX = (maxQx - minQx)/numPix
216        delY = (maxQy - minQy)/numPix
217        tmpX = minQx + x*delX
218        tmpY = minQy + x*delY
219       
220        // get rid of Q=0 values in the waves (may be a bad actor in model calculations)
221        //
222        tmpX = (tmpX == 0) ? 1e-6 : tmpX
223        tmpY = (tmpY == 0) ? 1e-6 : tmpY
224       
225        // X wave varies more rapidly
226        // Y wave is blocks of values
227        Variable ii=0
228        do
229                $(baseStr+"_qy")[ii*numPix,(ii+1)*numPix] = tmpY[ii]
230                ii+=1
231        while(ii<numPix)
232       
233        $(baseStr+"_qx") = tmpX[mod(p,numPix)]
234       
235        Variable/G gIsLogScale = 0
236       
237        // assume that the Q-grid is "uniform enough" for DISPLAY ONLY
238        // use the 3 original waves for all of the fitting...
239        ConvertQxQy2Mat($(baseStr+"_qx"),$(baseStr+"_qy"),$(baseStr+"_i"),baseStr+"_mat")
240        Duplicate/O $(baseStr+"_mat"),$(baseStr+"_lin")                 //keep a linear-scaled version of the data
241       
242        PlotQxQy(baseStr)               //this sets the data folder back to root:!!
243
244        //clean up             
245        SetDataFolder root:
246       
247EndMacro
248
249// this assumes that:
250// --QxQy data was written out in the format specified by the Igor macros, that is the x varies most rapidly
251// --the matrix is square!
252//
253// probably some other stuff...
254//
255Function UpdateQxQy2Mat(Qx,Qy,inten,linMat,mat)
256        Wave Qx,Qy,inten,linMat,mat
257       
258        Variable xrows=DimSize(mat, 0 )                 //assumes square matrix!!
259       
260        String folderStr=GetWavesDataFolder(Qx,1)
261        NVAR gIsLogScale=$(folderStr+"gIsLogScale")
262       
263        linMat = inten[q*xrows+p]
264       
265        if(gIsLogScale)
266                mat = log(linMat)
267        else
268                mat = linMat
269        endif
270       
271        return(0)
272End
273
274// this assumes that:
275// --QxQy data was written out in the format specified by the Igor macros, that is the x varies most rapidly
276// --the matrix is square!
277//
278// probably some other stuff...
279//
280Function ConvertQxQy2Mat(Qx,Qy,inten,matStr)
281        Wave Qx,Qy,inten
282        String matStr
283       
284        String folderStr=GetWavesDataFolder(Qx,1)
285       
286        Variable num=sqrt(numpnts(Qx))          //assumes square matrix, Qx = num x num points long
287        Make/O/D/N=(num,num) $(folderStr + matStr)
288        Wave mat=$matStr
289       
290        WaveStats/Q Qx
291        SetScale/I x, V_min, V_max, "", mat
292        WaveStats/Q Qy
293        SetScale/I y, V_min, V_max, "", mat
294       
295        Variable xrows=num
296       
297        mat = inten[q*xrows+p]
298       
299        return(0)
300End
301
302
303//str is the full path to the surface to append
304Proc AppendSurfaceToGizmo(str)
305        String str
306       
307        PauseUpdate; Silent 1   // Building Gizmo 6 window...
308
309        AppendToGizmo/Z Surface=$str,name=surface1
310       
311        // for a constant color (model is darker on top, lighter on the bottom)
312        //need these two lines, plus a color
313        ModifyGizmo ModifyObject=surface1 property={ surfaceColorType,1}
314        ModifyGizmo ModifyObject=surface1 property={ srcMode,0}
315        //green
316        ModifyGizmo ModifyObject=surface1 property={ frontColor,0.528923,0.882353,0.321584,1}
317        ModifyGizmo ModifyObject=surface1 property={ backColor,0.300221,0.6,1.5259e-05,1}
318        //red
319//      ModifyGizmo ModifyObject=surface1 property={ frontColor,1,0.749996,0.749996,1}
320//      ModifyGizmo ModifyObject=surface1 property={ backColor,1,0.250019,0.250019,1}
321
322        ModifyGizmo ModifyObject=surface1 property={ SurfaceCTABScaling,4}
323       
324        // for a color table (maybe not a good choice for vizualization if data uses a color table)
325//      ModifyGizmo ModifyObject=surface1 property={ srcMode,0}
326//      ModifyGizmo ModifyObject=surface1 property={ surfaceCTab,Red}
327       
328//      ModifyGizmo setDisplayList=0, object=surface0
329//      ModifyGizmo setDisplayList=1, object=axes0
330// object 3 is the axisCue
331        ModifyGizmo setDisplayList=4, object=surface1
332        ModifyGizmo SETQUATERNION={0.565517,-0.103105,-0.139134,0.806350}
333//      ModifyGizmo autoscaling=1
334//      ModifyGizmo currentGroupObject=""
335        ModifyGizmo compile
336
337//      ModifyGizmo endRecMacro
338End
339
340// would be nice, but I can't get this to work...
341//
342//Macro AdjustColorTables()
343//
344//      ModifyGizmo ModifyObject=surface1 property={ srcMode,0}
345//      ModifyGizmo ModifyObject=surface1 property={ surfaceCTab,Rainbow}
346//      ModifyGizmo setDisplayList=3, object=surface1
347////    ModifyGizmo SETQUATERNION={0.565517,-0.103105,-0.139134,0.806350}
348//      ModifyGizmo autoscaling=1
349//      ModifyGizmo currentGroupObject=""
350//      ModifyGizmo compile
351//     
352//end
353
354Function LogToggle2DButtonProc(ba) : ButtonControl
355        STRUCT WMButtonAction &ba
356
357        switch( ba.eventCode )
358                case 2: // mouse up
359                        // click code here
360                        String winStr=TopGizmoWindow()
361                        if(strlen(winstr)==0)
362                                Print "no gizmo window"
363                                break
364                        endif
365                        // the winStr is also the data folder
366                        // toggle everything in the data folder
367                        ToggleFolderScaling(winStr)             
368                        break
369        endswitch
370
371        return 0
372End
373
374Function Plot2DButtonProc(ba) : ButtonControl
375        STRUCT WMButtonAction &ba
376
377        switch( ba.eventCode )
378                case 2: // mouse up
379                        // click code here
380                        Execute "PlotQxQy()"
381                        break
382        endswitch
383
384        return 0
385End
386
387Function Append2DModelButtonProc(ba) : ButtonControl
388        STRUCT WMButtonAction &ba
389
390        switch( ba.eventCode )
391                case 2: // mouse up
392                        // click code here
393                        //str is the full path to the surface to append
394                        String DF=TopGizmoWindow()
395                        String str,funcStr,suffix
396                        ControlInfo/W=WrapperPanel popup_1
397                        funcStr = S_Value
398                        suffix = getModelSuffix(funcStr)
399                        if(stringmatch(funcStr, "smear*") == 1)
400                                suffix = "sm_"+suffix
401                        endif
402                        str = "root:"+DF+":"+suffix+"_mat"
403                       
404                        Execute "AppendSurfaceToGizmo(\""+str+"\")"
405//                      Print str
406                        break
407        endswitch
408
409        return 0
410End
411
412// toggle the scaling of every matrix in the folder
413Function ToggleFolderScaling(DF)
414        String DF
415
416        // look for waves DF+"_mat" (the data)
417        // and models prefix + "_mat"
418        SetDataFolder $("root:"+DF)
419        //check the global to see the state of the data
420        NVAR gIsLogScale = gIsLogScale
421       
422        String matrixList=WaveList("*_mat",";",""),item
423        Variable ii=0,num=itemsinlist(matrixlist,";"),len
424       
425        for(ii=0;ii<num;ii+=1)
426                        item = StringFromList(ii,matrixList,";")
427                        len = strlen(item)
428                        Wave w = $item
429                        Wave linW = $(item[0,len-5]+"_lin")
430                        if(gisLogScale)
431                                //make linear
432                                w=linW
433                        else   
434                                //make log scale
435                                w=log(linW)
436                                w = w[p][q] == -inf ? NaN : w[p][q]             //remove the -inf for display
437                        endif
438        endfor 
439       
440        // toggle the global
441        gIsLogScale = !gIsLogScale
442       
443        SetDataFolder root:
444        return(0)
445End
446
447
448Function Load2DDataButtonProc(ba) : ButtonControl
449        STRUCT WMButtonAction &ba
450
451        switch( ba.eventCode )
452                case 2: // mouse up
453                        // click code here
454                        Execute "LoadQxQy()"
455                        break
456        endswitch
457
458        return 0
459End
460
461
462// dispatch the fit
463Function Do2DFitButtonProc(ba) : ButtonControl
464        STRUCT WMButtonAction &ba
465
466        String folderStr,funcStr,coefStr
467        Variable useCursors,useEps,useConstr
468       
469        switch( ba.eventCode )
470                case 2: // mouse up
471                        ControlInfo/W=WrapperPanel popup_0
472                        folderStr=S_Value
473                       
474                        ControlInfo/W=WrapperPanel popup_1
475                        funcStr=S_Value
476                       
477                        ControlInfo/W=WrapperPanel popup_2
478                        coefStr=S_Value
479                       
480                        ControlInfo/W=WrapperPanel check_0
481                        useCursors=V_Value
482                        //
483                        // NO CURSORS for 2D waves - force to zero
484                        //
485                        useCursors = 0
486                        //
487                        ControlInfo/W=WrapperPanel check_1
488                        useEps=V_Value
489                        ControlInfo/W=WrapperPanel check_2
490                        useConstr=V_Value
491                       
492                        if(!CheckFunctionAndCoef(funcStr,coefStr))
493                                DoAlert 0,"The coefficients and function type do not match. Please correct the selections in the popup menus."
494                                break
495                        endif
496                       
497                        FitWrapper2D(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
498                       
499                        //      DoUpdate (does not work!)
500                        //?? why do I need to force an update ??
501                        if(!exists("root:"+folderStr+":"+coefStr))
502                                Wave w=$coefStr
503                        else
504                                Wave w=$("root:"+folderStr+":"+coefStr) //smeared coefs in data folder
505                        endif
506                        w[0] += 1e-6
507                        w[0] -= 1e-6
508       
509                        break
510        endswitch
511
512        return 0
513End
514
515// wrapper to do the desired fit, pretty much a clone of FitWrapper, the 1D version
516//
517// folderStr is the data folder for the desired data set
518//
519// Currently the limitations are:
520// - I have no error waves for the intensity
521// - There is no smeared model
522// - Cursors can't be used
523// - the report *probably* won't work
524Function FitWrapper2D(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
525        String folderStr,funcStr,coefStr
526        Variable useCursors,useEps,useConstr
527
528        String suffix=getModelSuffix(funcStr)
529       
530        SetDataFolder $("root:"+folderStr)
531        if(!exists(coefStr))
532                // must be unsmeared model, work in the root folder
533                SetDataFolder root:                             
534                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
535                        DoAlert 0,"the coefficient and data sets do not match"
536                        return 0
537                endif
538        endif
539               
540        WAVE cw=$(coefStr)     
541        Wave hold=$("Hold_"+suffix)
542        Wave/T lolim=$("LoLim_"+suffix)
543        Wave/T hilim=$("HiLim_"+suffix)
544        Wave eps=$("epsilon_"+suffix)
545       
546// fill a struct instance whether I need one or not
547        String DF="root:"+folderStr+":"
548       
549        Struct ResSmearAAOStruct fs
550//      WAVE resW = $(DF+folderStr+"_res")             
551//      WAVE fs.resW =  resW
552        WAVE inten=$(DF+folderStr+"_i")
553        WAVE Qx=$(DF+folderStr+"_qx")
554        WAVE Qy=$(DF+folderStr+"_qy")
555//      Wave fs.coefW = cw
556//      Wave fs.yW = yw
557//      Wave fs.xW = xw
558       
559        // generate my own error wave for I(qx,qy)
560        Duplicate/O inten sw
561        sw = sqrt(sw)           //assumes Poisson statistics for each cell (counter)
562//      sw = 0.05*sw            // uniform 5% error? tends to favor the low intensity too strongly
563
564        // generate my own mask wave - as a matrix first, then redimension to N*N vector
565        // default mask is two pixels all the way around, (0 is excluded, 1 is included)
566        WAVE DataMat=$(DF+folderStr+"_lin")
567        if(exists(DF+"mask") == 0)
568                Duplicate/O dataMat mask
569                Variable bsRadius=8             //pixels?
570                MakeBSMask(mask,bsRadius)
571        Endif
572       
573
574       
575//      Duplicate/O yw $(DF+"FitYw")
576//      WAVE fitYw = $(DF+"FitYw")
577//      fitYw = NaN
578
579        //for now, use res will always be 0 for 2D functions   
580        Variable useRes=0
581        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
582                useRes=1
583        endif
584       
585        // do not construct constraints for any of the coefficients that are being held
586        // -- this will generate an "unknown error" from the curve fitting
587        Make/O/T/N=0 constr
588        if(useConstr)
589                String constraintExpression
590                Variable i, nPnts=DimSize(lolim, 0),nextRow=0
591                for (i=0; i < nPnts; i += 1)
592                        if (strlen(lolim[i]) > 0 && hold[i] == 0)
593                                InsertPoints nextRow, 1, constr
594                                sprintf constraintExpression, "K%d > %s", i, lolim[i]
595                                constr[nextRow] = constraintExpression
596                                nextRow += 1
597                        endif
598                        if (strlen(hilim[i]) > 0 && hold[i] == 0)
599                                InsertPoints nextRow, 1, constr
600                                sprintf constraintExpression, "K%d < %s", i, hilim[i]
601                                constr[nextRow] = constraintExpression
602                                nextRow += 1
603                        endif
604                endfor
605        endif
606
607///// NO CURSORS for 2D waves
608        //if useCursors, and the data is USANS, need to feed a (reassigned) trimmed matrix to the fit
609//      Variable pt1,pt2,newN
610//      if(useCursors && (dimsize(resW,1) > 4) )
611//              if(pcsr(A) > pcsr(B))
612//                      pt1 = pcsr(B)
613//                      pt2 = pcsr(A)
614//              else
615//                      pt1 = pcsr(A)
616//                      pt2 = pcsr(B)
617//              endif
618//              newN = pt2 - pt1 + 1            // +1 includes both cursors in the fit
619//              Make/O/D/N=(newN,newN) $(DF+"crsrResW")
620//              WAVE crsrResW = $(DF+"crsrResW")
621//              crsrResW = resW[p+pt1][q+pt1]
622//              //assign to the struct
623//              WAVE fs.resW =  crsrResW               
624//      endif
625
626// create these variables so that FuncFit will set them on exit
627        Variable/G V_FitError=0                         //0=no err, 1=error,(2^1+2^0)=3=singular matrix
628        Variable/G V_FitQuitReason=0            //0=ok,1=maxiter,2=user stop,3=no chisq decrease
629       
630// don't use the auto-destination with no flag, it doesn't appear to work correctly
631// dispatch the fit
632        //      FuncFit/H="11110111111"/NTHR=0 Cylinder2D_D :cyl2d_c_txt:coef_Cyl2D_D  :cyl2d_c_txt:cyl2d_c_txt_i /X={:cyl2d_c_txt:cyl2d_c_txt_qy,:cyl2d_c_txt:cyl2d_c_txt_qx} /W=:cyl2d_c_txt:sw /I=1 /M=:cyl2d_c_txt:mask /D
633
634        do
635                if(useRes && useEps && useCursors && useConstr)         //do it all
636                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten[pcsr(A),pcsr(B)] /X={Qx,Qy} /M=mask /W=sw /I=1 /D /E=eps /C=constr
637                        break
638                endif
639               
640                if(useRes && useEps && useCursors)              //no constr
641                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten[pcsr(A),pcsr(B)] /X={Qx,Qy} /M=mask /W=sw /I=1 /D /E=eps
642                        break
643                endif
644               
645                if(useRes && useEps && useConstr)               //no crsr
646                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten /X={Qx,Qy} /M=mask /W=sw /I=1 /D /E=eps /C=constr
647                        break
648                endif
649               
650                if(useRes && useCursors && useConstr)           //no eps
651                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten[pcsr(A),pcsr(B)] /X={Qx,Qy} /M=mask /W=sw /I=1 /D /C=constr
652                        break
653                endif
654               
655                if(useRes && useCursors)                //no eps, no constr
656                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten[pcsr(A),pcsr(B)] /X={Qx,Qy} /M=mask /W=sw /I=1 /D
657                        break
658                endif
659               
660                if(useRes && useEps)            //no crsr, no constr
661                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten /X={Qx,Qy} /M=mask /W=sw /I=1 /D /E=eps
662                        break
663                endif
664       
665                if(useRes && useConstr)         //no crsr, no eps
666                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten /X={Qx,Qy} /M=mask /W=sw /I=1 /D /C=constr
667                        break
668                endif
669               
670                if(useRes)              //just res
671                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten /X={Qx,Qy} /M=mask /W=sw /I=1 /D
672                        break
673                endif
674               
675/////   same as above, but all without useRes (no /STRC flag)
676                if(useEps && useCursors && useConstr)           //do it all
677                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten[pcsr(A),pcsr(B)] /X={Qx,Qy} /M=mask /W=sw /I=1 /D /E=eps /C=constr
678                        break
679                endif
680               
681                if(useEps && useCursors)                //no constr
682                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten[pcsr(A),pcsr(B)] /X={Qx,Qy} /M=mask /W=sw /I=1 /D /E=eps
683                        break
684                endif
685               
686               
687                if(useEps && useConstr)         //no crsr
688                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten /X={Qx,Qy} /M=mask /W=sw /I=1 /D /E=eps /C=constr
689                        break
690                endif
691               
692                if(useCursors && useConstr)             //no eps
693                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten[pcsr(A),pcsr(B)] /X={Qx,Qy} /M=mask /W=sw /I=1 /D /C=constr
694                        break
695                endif
696               
697                if(useCursors)          //no eps, no constr
698                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten[pcsr(A),pcsr(B)] /X={Qx,Qy} /M=mask /W=sw /I=1 /D
699                        break
700                endif
701               
702                if(useEps)              //no crsr, no constr
703                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten /X={Qx,Qy} /M=mask /W=sw /I=1 /D /E=eps
704                        break
705                endif
706       
707                if(useConstr)           //no crsr, no eps
708                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten /X={Qx,Qy} /M=mask /W=sw /I=1 /D /C=constr
709                        break
710                endif
711               
712                //just a plain vanilla fit
713                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, inten /X={Qx,Qy} /M=mask /W=sw /I=1 /D
714       
715        while(0)
716       
717        // append the fit
718        // need to manage duplicate copies
719        // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...)
720//      String traces=TraceNameList("", ";", 1 )                //"" as first parameter == look on the target graph
721//      if(strsearch(traces,"FitYw",0) == -1)
722//              AppendToGraph FitYw vs xw
723//      else
724//              RemoveFromGraph FitYw
725//              AppendToGraph FitYw vs xw
726//      endif
727//      ModifyGraph lsize(FitYw)=2,rgb(FitYw)=(0,0,0)
728       
729//      DoUpdate                //force update of table and graph with fitted values (why doesn't this work? - the table still does not update)
730       
731        // report the results (to the panel?)
732        print "V_chisq = ",V_chisq
733        print cw
734        WAVE w_sigma
735        print w_sigma
736        String resultStr=""
737               
738        //now re-write the results
739        sprintf resultStr,"Chi^2 = %g  Sqrt(X^2/N) = %g",V_chisq,sqrt(V_chisq/V_Npnts)
740        resultStr = PadString(resultStr,63,0x20)
741        GroupBox grpBox_2 title=resultStr
742        ControlUpdate/W=WrapperPanel grpBox_2
743        sprintf resultStr,"FitErr = %s : FitQuit = %s",W_ErrorMessage(V_FitError),W_QuitMessage(V_FitQuitReason)
744        resultStr = PadString(resultStr,63,0x20)
745        GroupBox grpBox_3 title=resultStr
746        ControlUpdate/W=WrapperPanel grpBox_3
747       
748        Variable yesSave=0,yesReport=0
749        ControlInfo/W=WrapperPanel check_4
750        yesReport = V_Value
751        ControlInfo/W=WrapperPanel check_5
752        yesSave = V_Value
753       
754       
755        if(yesReport)
756                String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+suffix, "", "TEXT:1," )              //this is *hopefully* one wave
757                String topGraph= TopGizmoWindow()       //this is the topmost Gizmo (XOP) window
758               
759                DoUpdate                //force an update of the graph before making a copy of it for the report
760       
761                W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph)
762        endif
763       
764        SetDataFolder root:
765        return(0)
766End
767
768
769// right now, there are only unsmeared models, but I want experimental points
770// for the QxQy of the calculation - so get the folder string
771Function Plot2DFunctionButtonProc(ba) : ButtonControl
772        STRUCT WMButtonAction &ba
773
774        String folderStr,funcStr,coefStr,cmdStr=""
775       
776        Variable killWhat=0             //kill nothing as default
777
778        switch( ba.eventCode )
779                case 2: // mouse up
780                        ControlInfo/W=WrapperPanel popup_0
781                        folderStr=S_Value
782                       
783                        ControlInfo/W=WrapperPanel popup_1
784                        funcStr=S_Value
785                       
786                        // check for smeared or smeared function
787//                      if(stringmatch(funcStr, "Smear*" )==1)
788                                //it's a smeared model
789                                // check for the special case of RPA that has an extra parameter
790//                              if(strsearch(funcStr, "RPAForm", 0 ,0) == -1)
791                                        sprintf cmdStr, "Plot%s(\"%s\")",funcStr,folderStr              //not RPA
792//                              else
793//                                      sprintf cmdStr, "Plot%s(\"%s\",)",funcStr,folderStr             //yes RPA, leave a comma for input
794//                              endif
795//                      else
796//                              // it's not,                   
797//                              sprintf cmdStr, "Plot%s()",funcStr
798//                      endif
799                       
800                        //Print cmdStr
801                        Execute cmdStr
802                       
803                        //pop the function menu to set the proper coefficients
804                        DoWindow/F WrapperPanel
805                        STRUCT WMPopupAction pa
806                        pa.popStr = funcStr
807                        pa.eventcode = 2
808                        Function_PopMenuProc(pa)
809       
810                        KillWhat = 2            //kill just the table, leave the 2d visible for now
811                        KillTopGraphAndTable(killWhat)          // crude
812
813                        break
814        endswitch
815
816        return 0
817End
818
819// unused - all of this functionality has been added to the Wrapper Panel
820Window Plot_2D_Controls()
821        PauseUpdate; Silent 1           // building window...
822        NewPanel /W=(950,44,1250,244)
823        Button button0,pos={172,37},size={70,20},proc=LogToggle2DButtonProc,title="Log/Lin"
824        Button button1,pos={146,9},size={100,20},proc=Plot2DButtonProc,title="Plot 2D Data"
825        Button button2,pos={164,118},size={120,20},proc=Append2DModelButtonProc,title="Append Model"
826        PopupMenu popup_1,pos={9,84},size={132,20},proc=Function_PopMenuProc,title="Function"
827        PopupMenu popup_1,mode=1,popvalue="Cylinder2D",value= #"W_FunctionPopupList()"
828        Button button3,pos={11,9},size={100,20},proc=Load2DDataButtonProc,title="Load 2D Data"
829        Button button4,pos={164,161},size={120,20},proc=Do2DFitButtonProc,title="Do 2D Fit"
830        Button button5,pos={164,85},size={120,20},proc=Plot2DFunctionButtonProc,title="Plot 2D Function"
831EndMacro
832
833
834Function/S TopGizmoWindow()
835        Return(StringFromList(0,WinList("*",";","WIN:4096")))
836end
837
838////
839//
840// unused proc for testing
841Proc Plot2DVsPointNumber(str)
842        String str
843        Prompt str,"Pick the data folder containing 2D data",popup,getAList(4)
844
845        PauseUpdate; Silent 1           // building window...
846        String fldrSav0= GetDataFolder(1)
847        SetDataFolder $("root:"+str)
848        Display /W=(241,352,810,842) $(str+"_i")
849        SetDataFolder fldrSav0
850        ModifyGraph mode=3
851        ModifyGraph marker=19
852        ModifyGraph lSize=2
853        ModifyGraph rgb($(str+"_i"))=(0,0,0)
854        ModifyGraph msize=1
855        ModifyGraph grid=1
856        ModifyGraph log(left)=1
857        ModifyGraph mirror=2
858        if(exists("root:"+str+":sw"))
859                ErrorBars/T=0 $(str+"_i") Y,wave=($("root:"+str+":sw"),$("root:"+str+":sw"))
860        endif
861        SetDataFolder fldrSav0
862EndMacro
863
864// testing procedure, used when I had x,y swapped and was getting nonsensical results
865//Macro CalculateChiSquared(str)
866//      String str
867//      Prompt str,"Pick the data folder containing 2D data",popup,getAList(4)
868//
869//
870//      String fldrSav0= GetDataFolder(1)
871//      SetDataFolder $("root:"+str)
872//
873//      Duplicate/O $(str+"_i") chi
874//      chi = ((zwave_cyl2D_D - $(str+"_i"))/sw )^2
875//     
876//      chi = (mask == 1) ? chi : 0
877//     
878//      Print sum(chi,-inf,inf)
879//     
880//      SetDataFolder fldrSav0
881//EndMacro
882
883
884Function MakeBSMask(mask,rad)
885        Wave mask
886        Variable rad
887
888
889// find the center based on the wave scaling
890        Variable xCtr,yCtr,Qzero=0
891        xCtr = (Qzero - DimOffset(Mask, 0))/DimDelta(Mask,0)
892        yCtr = (Qzero - DimOffset(Mask, 1))/DimDelta(Mask,1)
893
894        Print xctr,yctr
895
896//      Variable center = sqrt(numpnts(mask))/2 -0.5
897
898        mask = (sqrt((p-xCtr)^2+(q-yCtr)^2) < rad) ? 0 : 1
899
900        Variable xDim, yDim
901        xDim = DimSize(mask,0)
902        yDim = DimSize(mask,1)
903        mask[][0] = 0
904        mask[][1] = 0
905        mask[][yDim-2] = 0
906        mask[][yDim-1] = 0
907        mask[0][] = 0
908        mask[1][] = 0
909        mask[xDim-2][] = 0
910        mask[xDim-1][] = 0
911       
912        Redimension/N=(xDim*yDim) mask          //now 1D
913       
914       
915End
Note: See TracBrowser for help on using the repository browser.