source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/USANS/COR_Graph.ipf @ 570

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

Change (1):
In preparation for release, updated pragma IgorVersion?=6.1 in all procedures

Change (2):
As a side benefit of requiring 6.1, we can use the MultiThread? keyword to thread any model function we like. The speed benefit is only noticeable on functions that require at least one integration and at least 100 points (resolution smearing is NOT threaded, too many threadSafe issues, too little benefit). I have chosen to use the MultiThread? only on the XOP assignment. In the Igor code there are too many functions that are not explicitly declared threadsafe, making for a mess.

  • Property eol-style set to native
  • Property svn:executable set to *
File size: 17.5 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma Version=2.20
3#pragma IgorVersion=6.1
4
5////////////////////////////
6// 101001 Vers. 1
7//
8// procedures to plot the sma, emp, and cor data
9// - user interaction is through control bar on COR_Graph
10// - provides user with feedback about peak angle, transmissions
11// - asks for information about BKG and EMP levels
12// - asks for sample thickness
13// - interactively selects range of data to save (and type)
14// - dispatches to routines to determine transmissions and correct the data
15// - dispatches to save routines
16//
17/////////////////////////////
18
19
20//plot all that is available in the root:Graph folder
21// no distinction as to what the status of the data really is
22// "Clr" buttons on the USANS_Panel will clear the graph..
23//
24Function DoCORGraph()
25
26        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
27       
28        DoWindow/F COR_Graph
29        if(V_flag==0)
30                //draw the blank window and the control bar
31                Display /W=(5,42,450,550) /K=1
32                DoWindow/C COR_Graph
33                ControlBar 150
34                SetVariable gTransWide,pos={210,12},size={135,15},title="Trans - Wide",format="%5.4f"
35                SetVariable gTransWide,help={"Average counts on transmssion detector at wide angles"}
36                SetVariable gTransWide,limits={0,1,0.001},value= $(USANSFolder+":Globals:MainPanel:gTransWide")
37                SetVariable gTransRock,pos={210,27},size={135,15},title="Trans - Rock",format="%5.4f"
38                SetVariable gTransRock,help={"Transmission counts at the zero-angle peak"}
39                SetVariable gTransRock,limits={0,1,0.001},value= $(USANSFolder+":Globals:MainPanel:gTransRock")
40                SetVariable gEmpCts,pos={210,42},size={135,15},title="EMP Level",format="%7.4f"
41                SetVariable gEmpCts,limits={-Inf,Inf,0.1},value= $(USANSFolder+":Globals:MainPanel:gEmpCts")
42                SetVariable gEmpCts,help={"High q limit of empty cell scattering normalized to 1.0e6 monitor counts"}
43                SetVariable gBkgCts,pos={210,57},size={135,15},title="BKG Level",format="%7.4f"
44                SetVariable gBkgCts,limits={-Inf,Inf,0.1},value= $(USANSFolder+":Globals:MainPanel:gBkgCts")
45                SetVariable gBkgCts,help={"Background scattering level normalized to 1.0e6 monitor counts"}
46                SetVariable gThick,pos={210,72},size={135,15},title="SAM Thick(cm)",format="%5.4f"
47                SetVariable gThick,help={"Thickness of the sample in centimeters"}
48                SetVariable gThick,limits={0,5,0.01},value= $(USANSFolder+":Globals:MainPanel:gThick")
49                Button UpdateButton,pos={125,15},size={70,40},proc=UpdateButtonProc,title="Update\rTrans"
50                Button UpdateButton,help={"Updates both the wide and rocking transmission values based on the raw data files"}
51                Button CorrectButton,pos={125,60},size={70,40},proc=CorrectButtonProc,title="Correct\rData"
52                Button CorrectButton,help={"Corrects the sample data by subtracting empty cell and backgrond scattering"}
53                Button SaveDataButton,pos={355,3},size={85,20},proc=SaveButtonProc,title="Save Data..."
54                Button SaveDataButton,help={"Saves the selected data type to disk in ASCII format"}
55                CheckBox useCrsrCheck,pos={360,27},size={119,14},proc=UseCrsrCheckProc,title="Use Cursors?"
56                CheckBox useCrsrCheck,value= 0
57                CheckBox useCrsrCheck,help={"Adds cursors to the datset to select the range of data points to save"}
58                CheckBox CORCheck,pos={380,44},size={40,14},title="COR",value=1,proc=TypeToggleCheckProc,mode=1
59                CheckBox CORCheck,help={"Selects COR data as the saved type"}
60                CheckBox SAMCheck,pos={380,60},size={40,14},title="SAM",value=0,proc=TypeToggleCheckProc,mode=1
61                CheckBox SAMCheck,help={"Selects SAM data s the saved type"}
62                CheckBox EMPCheck,pos={380,76},size={40,14},title="EMP",value= 0,proc=TypeToggleCheckProc,mode=1
63                CheckBox EMPCheck,help={"Selects EMP data as the saved type"}
64                Button qpkButton,pos={12,61},size={90,20},proc=QpkButtonProc,title="Change Qpk"
65                Button qpkButton,help={"Use this to override the automatically determined peak locations in SAM or EMP datasets"}
66                ValDisplay valdispSAM,pos={10,15},size={100,14},title="Qpk SAM",format="%1.3f"
67                ValDisplay valdispSAM,limits={0,0,0},barmisc={0,1000},value=QpkFromNote("SAM")
68                ValDisplay valdispSAM,help={"Displays the peak angle the raw SAM data, determined automatically"}
69                ValDisplay valdispEMP,pos={10,36},size={100,14},title="Qpk EMP",format="%1.3f"
70                ValDisplay valdispEMP,limits={0,0,0},barmisc={0,1000},value=QpkFromNote("EMP")
71                ValDisplay valdispEMP,help={"Displays the peak angle the raw EMP data, determined automatically"}
72       
73                CheckBox check0 title="Log X-axis",proc=LogLinToggleCheckProc
74                CheckBox check0 pos={12,100},value=0,mode=0
75                SetVariable setvar0,pos={210,100},size={120,20},title="Trock/Twide",format="%5.4f"
76                SetVariable setVar0,help={"fraction of unscattered neutrons"}
77                SetVariable setVar0,limits={0,2,0},value= $(USANSFolder+":Globals:MainPanel:gTransRatio")
78               
79                Legend
80        Endif
81        // add each data type to the graph, if possible (each checks on its own)
82        //SAM
83        GraphSAM()
84        //EMP
85        GraphEMP()
86        //COR
87        GraphCOR()
88        //EMP and BKG levels
89        GraphEMPBKGLevels()
90       
91        ControlUpdate/A/W=COR_Graph
92       
93        ModifyGraph log(left)=1,mirror=2,grid=1,standoff=0
94        ModifyGraph tickUnit=1
95        Label left "(Counts/sec)/(MON*10\\S6\\M)"
96        Label bottom "q (A\\S-1\\M)"
97       
98        return(0)
99End
100
101// add SAM data to the graph if it exists and is not already on the graph
102//
103Function GraphSAM()
104
105        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
106
107        //is it already on the graph?
108        SetDataFolder $(USANSFolder+":Graph")
109        String list=""
110        list = Wavelist("DetCts_SAM*",";","WIN:COR_Graph")
111        if(strlen(list)!=0)
112                //Print "SAM already on graph"
113                return(0)
114        Endif
115        //append the data if it exists
116        If(waveExists($"DetCts_SAM")==1)
117                DoWindow/F COR_Graph
118                AppendToGraph DetCts_SAM vs Qvals_SAM
119                ModifyGraph rgb(DetCts_SAM)=(1,12815,52428)
120                ModifyGraph mode(DetCts_SAM)=3,marker(DetCts_SAM)=19,msize(DetCts_SAM)=2
121                ModifyGraph tickUnit=1
122                ErrorBars/T=0 DetCts_SAM Y,wave=(ErrDetCts_SAM,ErrDetCts_SAM)
123        endif
124        SetDataFolder root:
125End
126
127// add EMP data to the graph if it exists and is not already on the graph
128//
129Function GraphEMP()
130
131        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
132
133        SetDataFolder $(USANSFolder+":Graph")
134        String list=""
135        list = Wavelist("DetCts_EMP*",";","WIN:COR_Graph")
136        if(strlen(list)!=0)
137        //      Print "EMP already on graph"
138                return(0)
139        Endif
140        //append the data if it exists
141        If(waveExists($"DetCts_EMP")==1)
142                DoWindow/F COR_Graph
143                AppendToGraph DetCts_EMP vs Qvals_EMP
144                ModifyGraph msize(DetCts_EMP)=2,rgb(DetCts_EMP)=(1,39321,19939)
145                ModifyGraph mode(DetCts_EMP)=3,marker(DetCts_EMP)=19
146                ModifyGraph tickUnit=1
147                ErrorBars/T=0 DetCts_EMP Y,wave=(ErrDetCts_EMP,ErrDetCts_EMP)
148        endif
149        SetDataFolder root:
150        return(0)
151End
152
153// add COR data to the graph if it exists and is not already on the graph
154//
155Function GraphCOR()
156        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
157
158        SetDataFolder $(USANSFolder+":Graph")
159       
160        String list=""
161        list = Wavelist("DetCts_COR*",";","WIN:COR_Graph")
162        if(strlen(list)!=0)
163        //      Print "COR already on graph"
164                return(0)
165        Endif
166        //append the data if it exists
167        If(waveExists($"DetCts_COR")==1)
168                DoWindow/F COR_Graph
169                AppendToGraph DetCts_COR vs Qvals_COR
170                ModifyGraph msize(DetCts_COR)=2,rgb(DetCts_COR)=(52428,34958,1)
171                ModifyGraph mode(DetCts_COR)=3,marker(DetCts_COR)=19
172                ModifyGraph tickUnit=1
173                ErrorBars DetCts_COR Y,wave=(ErrDetCts_COR,ErrDetCts_COR)
174        endif
175
176        SetDataFolder root:
177        return(0)
178End
179
180// add horizoontal lines for the background and empty cell levels
181Function GraphEMPBKGLevels()
182
183        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
184
185        //if the data is on the graph, remove them and replot, to properly reset the scale
186        DoUpdate
187        String list = TraceNameList("COR_Graph",";",1)
188        //Print list
189        DoWindow/F COR_Graph
190        if(stringmatch(list,"*empLevel*")==1)
191                //remove
192                RemoveFromGraph empLevel,bkgLevel
193        Endif
194        DoUpdate
195        AppendToGraph $(USANSFolder+":EMP:EMPLevel"),$(USANSFolder+":BKG:BKGLevel")
196        ModifyGraph rgb(empLevel)=(0,0,0),lsize(bkgLevel)=2,rgb(bkgLevel)=(52428,1,1)
197        ModifyGraph lsize(empLevel)=2,offset={0,0}
198        ModifyGraph tickUnit=1
199        GetAxis/W=COR_Graph/Q bottom
200        SetScale/I x V_min,V_max,"",$(USANSFolder+":EMP:EMPLevel"),$(USANSFolder+":BKG:BKGLevel")
201        return(0)
202End
203
204// polls the control bar for proper selections of SavePath
205// checks for selected dataset from radio buttons
206// obtains the poin numbers from the cursors, if selected
207// dispatches to save routine
208//
209Function SaveButtonProc(ctrlName) : ButtonControl
210        String ctrlName
211
212        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
213       
214        PathInfo/S savePathName
215        if(V_Flag==0)
216                DoAlert 0,"Pick a \"SavePath...\"\rNo data file has been written"
217                return(1)
218        Endif
219       
220        String type=""
221        Variable useCrsrs=0,ptA=0,ptB=0
222       
223        //check for data save type (controlled by radio buttons)
224        NVAR gRadioVal=$(USANSFolder+":Globals:MainPanel:gTypeCheck")           //1=COR,2=SAM,3=EMP
225        switch(gRadioVal)
226                case 1: //COR
227                        type="COR"
228                        break                           
229                case 2: //SAM
230                        type="SAM"
231                        break
232                case 3: //EMP
233                        type="EMP"
234                        break   
235                default:
236                        DoAlert 0,"No Radio button selected\rNo data file written"
237                        return(1)
238        endswitch
239       
240        //check for data save between cursors
241        ControlInfo UseCrsrCheck
242        useCrsrs = V_Value              //1 if checked
243        //if so, read off the point range (cursors should be on the same wave as the save type)
244        if(useCrsrs)
245                Wave xwave=$(USANSFolder+":Graph:Qvals_"+type)
246                ptA=x2pnt(xwave,xcsr(A))
247                ptB=x2pnt(xwave,xcsr(B))
248                if(ptA>ptB)
249                        ptA=x2pnt(xwave,xcsr(B))
250                        ptB=x2pnt(xwave,xcsr(A))
251                endif
252                ptA=trunc(ptA)  //make sure it's integer
253                ptB=trunc(ptB)
254                //Print ptA,ptB
255        endif
256       
257        //fill in the blanks and dispatch to save routine
258        WriteUSANSWaves(type,"",ptA,ptB,1)
259       
260        return(0)
261End
262
263//show/hide cursors depending on the checkbox selection
264//put cursors on the selected save data type
265Function UseCrsrCheckProc(ctrlName,checked) : CheckBoxControl
266        String ctrlName
267        Variable checked
268       
269        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
270       
271        NVAR gRadioVal=$(USANSFolder+":Globals:MainPanel:gTypeCheck")           //1=COR,2=SAM,3=EMP
272        String type=""
273        switch(gRadioVal)
274                case 1: //COR
275                        type="COR"
276                        break                           
277                case 2: //SAM
278                        type="SAM"
279                        break
280                case 3: //EMP
281                        type="EMP"
282                        break   
283                default:
284                        DoAlert 0,"No Radio button selected\rCan't place cursors"
285                        return(1)
286        endswitch
287        if(checked)
288                //show info and cursors, if the wave in on the graph
289                String str,yname
290                str=TraceNameList("", ";", 1)
291                yname="DetCts_"+type
292                Variable ok=WhichListItem(yname, str,";",0)
293                if(ok != -1)
294                        Wave ywave=$(USANSFolder+":Graph:DetCts_"+type)
295                        Showinfo/W=COR_Graph
296                        Cursor/A=1/P/S=1 A,$yname,0
297                        Cursor/A=0/P/S=1 B,$yname,numpnts(ywave)-1
298                else
299                        //trace is not on graph
300                        CheckBox $ctrlName, value=0             //not checked
301                        HideInfo/W=COR_Graph
302                        Cursor/K/W=COR_Graph A
303                        Cursor/K/W=COR_Graph B
304                        DoAlert 0,type+" data is not on the graph"
305                endif
306        else
307                //hide info and cursors, if there are any displayed
308                HideInfo/W=COR_Graph
309                Cursor/K/W=COR_Graph A
310                Cursor/K/W=COR_Graph B
311                CheckBox useCrsrCheck,win=COR_Graph,value= 0
312        endif
313        DoUpdate
314End
315
316//radio button control of save type
317//sets global, so buttons don't need to be polled
318Function TypeToggleCheckProc(ctrlName,checked) : CheckBoxControl
319        String ctrlName
320        Variable checked
321
322        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
323
324        NVAR gRadioVal=$(USANSFolder+":Globals:MainPanel:gTypeCheck")
325       
326        strswitch(ctrlName)
327                case "CORCheck":
328                        gRadioVal=1
329                        break
330                case "SAMCheck":
331                        gRadioVal=2
332                        break
333                case "EMPCheck":
334                        gRadioVal=3
335                        break
336        endswitch
337        CheckBox CORCheck,win=COR_Graph,value= (gRadioVal==1)
338        CheckBox SAMCheck,win=COR_Graph,value= (gRadioVal==2)
339        CheckBox EMPCheck,win=COR_Graph,value= (gRadioVal==3)
340       
341        //move the cursors to the correct trace on the graph
342        ControlInfo useCrsrCheck
343        checked=V_Value
344        UseCrsrCheckProc("useCrsrCheck",V_Value)
345End
346
347//updates the trans values and the bkg/empty values on the graph, if necessary
348//calculate the T_Wide and T_Rock from the wave notes
349// if there is an error in the wave notes, "NaN" will typically be returned
350//
351Function UpdateButtonProc(ctrlName) : ButtonControl
352        String ctrlName
353
354        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
355       
356        Wave samCts=$(USANSFolder+":SAM:DetCts")
357        Wave empCts=$(USANSFolder+":EMP:DetCts")
358        if((WaveExists(samCts)==0) || (WaveExists(empCts)==0))
359                Variable/G $(USANSFolder+":Globals:MainPanel:gTransWide")=NaN           //error
360                Variable/G $(USANSFolder+":Globals:MainPanel:gTransRock")=NaN
361                return(1)
362        Endif
363        //get the wave notes, and the transCt values
364        String samNote=note(samCts),empNote=note(empCts)
365        Variable samWide,empWide,samRock,empRock
366        samWide = NumberByKey("TWIDE",samNote,":",";")
367        empWide = NumberByKey("TWIDE",empNote,":",";")
368        samRock = NumberByKey("PEAKVAL",samNote,":",";")
369        empRock = NumberByKey("PEAKVAL",empNote,":",";")
370        Variable/G $(USANSFolder+":Globals:MainPanel:gTransWide")=samWide/empWide
371        Variable/G $(USANSFolder+":Globals:MainPanel:gTransRock")=samRock/empRock
372       
373        TransRatio()            //calculate the ratio and update
374       
375        return(0)
376End
377
378// dispatches to the function to perform the data correction
379//
380Function CorrectButtonProc(ctrlName) : ButtonControl
381        String ctrlName
382       
383        DoCorrectData()
384        return(0)
385End
386
387//button to present a simple input dialog to ask the user for the data type
388// (either SAM or EMP) and the new value of the peak angle to use.
389//
390// rarely needed, but sometimes the data can fool IGOR, and no peak can be found
391// in some cases, data may not cover the primary beam. In both of these cases it
392// is necessary to manually override the peak angle
393//
394// calls RePlotWithUserAngle to "re-do" everything
395//
396Function QpkButtonProc(ctrlName) : ButtonControl
397        String ctrlName
398       
399        Variable newPkAngle=0
400        String dataSet="SAM;EMP;",type=""
401       
402        Prompt type,"Select Data Set",popup,dataSet
403        Prompt newPkAngle, "Enter new peak ANGLE, in Degrees"
404        DoPrompt "Override the peak angle",type,newPkAngle
405        //Print newPkAngle,type
406        if(V_Flag==1)           //user cancel, exit
407                return(1)
408        endif
409        //with the new information (type and angle) re-do the whole mess
410        //...as if the "plot" button was hit, except that the angle is known...
411       
412        RePlotWithUserAngle(type,newPkAngle)
413End
414
415Function TransRatio()
416        NVAR tr = root:Packages:NIST:USANS:Globals:MainPanel:gTransRock
417        NVAR tw = root:Packages:NIST:USANS:Globals:MainPanel:gTransWide
418        NVAR rat = root:Packages:NIST:USANS:Globals:MainPanel:gTransRatio
419       
420        rat = tr/tw
421        if(rat < 0.9)
422                SetVariable setVar0 labelBack=(65535,32768,32768)
423        else
424                SetVariable setVar0 labelBack=0
425        endif
426        return(0)
427End
428
429Function LogLinToggleCheckProc(cba) : CheckBoxControl
430        STRUCT WMCheckboxAction &cba
431
432        switch( cba.eventCode )
433                case 2: // mouse up
434                        Variable checked = cba.checked                 
435                        if(checked)
436                                ModifyGraph log(bottom)=1
437                        else
438                                ModifyGraph log(bottom)=0
439                        endif
440                        break
441        endswitch
442
443        return 0
444End
445
446
447//returns the peak location found (and used) for zero angle
448//displayed on the COR_Graph
449Function QpkFromNote(type)
450        String type
451
452        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
453               
454        Wave/Z detCts=$(USANSFolder+":Graph:DetCts_"+type)
455        if(!WaveExists(detCts))
456                return(NaN)
457        Endif
458        String str=note(detcts)
459        Variable val
460       
461        val=NumberByKey("PEAKANG", str,":",";")
462        return(val)
463End
464
465//nearly identical to PlotSelectedSAMButtonProc
466// - re-loads the data and goes through all the steps as it they were new datsets
467// - DOES NOT try to find the peak angle, instead uses the input zeroAngle
468// - replaces the PEAKANG:value with the input zeroAngle
469// updates the plot with the corrected angle
470//
471Function RePlotWithUserAngle(type,zeroAngle)
472        String type
473        Variable zeroAngle
474
475        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
476       
477        //SETS the wave note with the PEAKANG value
478       
479        //loads each of the data files
480        //normalizes each file to countrate immediately
481        //appends them to the individual waves in "SAM" folder
482        //sorts by angle
483        //converts to Q-values USING SUPPLIED ANGLE
484        //
485        //get selected files from listbox (everything)
486        //use the listBox wave directly
487       
488        Wave/T listW=$(USANSFolder+":Globals:MainPanel:"+type+"Wave")
489        Variable ii,num=numpnts(listW)
490        String fname="",fpath=""
491        PathInfo bt5PathName
492        fpath = S_Path
493       
494        //load, normalize, and append
495        //loop over the number of items in the list
496        for(ii=0;ii<num;ii+=1)
497                fname = fpath + listw[ii]
498                LoadBT5File(fname,"SWAP")       //overwrite what's in the SWAP folder
499                Convert2Countrate("SWAP",1)
500                if(ii==0)       //first time, overwrite
501                        NewDataWaves("SWAP",type)
502                else            //append to waves in TYPE folder
503                        AppendDataWaves("SWAP",type)
504                endif
505        endfor
506        //sort after all loaded
507        DoAngleSort(type)
508       
509        //find the peak and convert to Q-values
510        //Variable zeroAngle = FindZeroAngle("SAM")
511        //if(zeroAngle == -9999)
512                //DoAlert 0,"Couldn't find a peak - using zero as zero angle"
513        //      zeroAngle = 0
514        //Endif
515       
516        //find the peak value at the supplied angle, rather than automatic...
517        Wave tmpangle = $(USANSFolder+":"+type+":Angle")
518        Wave tmpdetCts = $(USANSFolder+":"+type+":DetCts")
519        Variable pkHt=0
520        pkHt = interp(zeroAngle,tmpangle,tmpdetcts)
521        String str=""
522        str=note(tmpDetCts)
523        str = ReplaceNumberByKey("PEAKANG",str,zeroAngle,":",";")
524        str = ReplaceNumberByKey("PEAKVAL",str,pkHt,":",";")
525        Note/K tmpDetCts
526        Note tmpdetCts,str
527       
528        ConvertAngle2Qvals(type,zeroAngle)
529        //find the Trans Cts for T_Wide
530        FindTWideCts(type)
531        //
532        //copy the data to plot to the root:Graph directory, and give clear names
533        if(WaveExists($(USANSFolder+":"+type+":Qvals")))
534                Duplicate/O $(USANSFolder+":"+type+":Qvals"),$(USANSFolder+":Graph:Qvals_"+type)
535        Endif
536        Duplicate/O $(USANSFolder+":"+type+":Angle"),$(USANSFolder+":Graph:Angle_"+type)
537        Duplicate/O $(USANSFolder+":"+type+":DetCts"),$(USANSFolder+":Graph:DetCts_"+type)
538        Duplicate/O $(USANSFolder+":"+type+":ErrDetCts"),$(USANSFolder+":Graph:ErrDetCts_"+type)
539       
540        //now plot the data (or just bring the graph to the front)
541        DoCORGraph()
542       
543        //update the valDisplays
544        ControlUpdate/A/W=COR_Graph             //overkill, does them all
545End
Note: See TracBrowser for help on using the repository browser.