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

Last change on this file since 477 was 419, checked in by ajj, 14 years ago

Moving files

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