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

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

minor changes and comments

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