source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/USANS/BT5_Loader.ipf @ 1133

Last change on this file since 1133 was 1133, checked in by srkline, 4 years ago

many changes to the VCALC procedures to add in the hard/soft shadowing to the calculation, visualization of the shadowed regions, and the actual q-values. Added a separate panel to view the shadowed regions.

simpe fix to the real time routine to allow easy updating of both the raw 2D data and 1-D average

update to the USANS package to handle the new NICE generated data where the data is collected in terms of q-values rather than angle. On startup asks user which style of data they have. Sets a preference that can be un-checked if you have old-style ICP data. (there is nothing in the data file that I can key on).

  • Property eol-style set to native
  • Property svn:executable set to *
File size: 12.6 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// functions to load and parse the ASCII ICP files generated at BT5 USANS
9// Nearly all of the important information about the data is dragged around
10// with the DetCts wave as a wave note
11//
12// - thes wave note is a string of KEY:value items
13//
14//      str = "FILE:"+filen+";"
15//      str += "TIMEPT:"+num2str(counttime)+";"
16//      str += "PEAKANG:;"              //no value yet
17//      str += "STATUS:;"               //no value yet
18//      str += "LABEL:"+fileLabel+";"
19//      str += "PEAKVAL:;"              //no value yet
20//      str += "TWIDE:0;"               //no value yet
21//
22/////////////////////////
23
24
25//given the filename, loads a single data file into a "TYPE" folder, into a
26//series of 1D waves. counting time is associated with the DetCts wave as a note
27//"blank" note entries are set up here as well, so later they can be polled/updated
28Function LoadBT5File(fname,type)
29        String fname,type
30
31        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
32       
33        Variable num=500,err=0,refnum
34        Make/O/D/N=(num) $(USANSFolder+":"+type+":Angle")
35        Make/O/D/N=(num) $(USANSFolder+":"+type+":DetCts")
36        Make/O/D/N=(num) $(USANSFolder+":"+type+":ErrDetCts")
37        Make/O/D/N=(num) $(USANSFolder+":"+type+":MonCts")
38        Make/O/D/N=(num) $(USANSFolder+":"+type+":TransCts")
39        Wave Angle = $(USANSFolder+":"+type+":Angle")
40        Wave DetCts = $(USANSFolder+":"+type+":DetCts")
41        Wave ErrDetCts = $(USANSFolder+":"+type+":ErrDetCts")
42        Wave MonCts = $(USANSFolder+":"+type+":MonCts")
43        Wave TransCts = $(USANSFolder+":"+type+":TransCts")
44       
45        Open/R refNum as fname          //if fname is "", a dialog will be presented
46        if(refnum==0)
47                return(1)               //user cancelled
48        endif
49        //read in the ASCII data line-by-line
50        Variable numLinesLoaded = 0,firstchar,countTime
51        Variable v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,ii,valuesRead
52        String buffer ="",s1,s2,s3,s4,s5,s6,s7,s8,s9,s10
53        String filen="",fileLabel="",filedt=""
54       
55        Variable MainDeadTime,TransDeadTime
56       
57        //parse the first line
58        FReadLine refnum,buffer
59        sscanf buffer, "%s%s%s%s%s%s%g%g%s%g%s",s1,s2,s3,s4,s5,s6,v1,v2,s7,v3,s8
60        ii=strlen(s1)
61        filen=s1[1,(ii-2)]                      //remove the ' from beginning and end
62        //Print "filen = ",filen,strlen(filen)
63        //v2 is the monitor prefactor. multiply monitor time by prefactor. AJJ 5 March 07
64        countTime=v1*v2
65        //Print "time (sec) = ",countTime
66       
67        //Deadtime correction
68        //Discovered significant deadtime on detectors in Oct 2010
69        //JGB and AJJ changed pre-amps during shutdown Oct 27 - Nov 7 2010
70        //Need different deadtime before and after 8th November 2010
71        filedt = s2+" "+s3+" "+s4+" "+s5
72        ii=strlen(filedt)
73        filedt = filedt[1,(ii-2)]
74               
75//      print filedt
76//      print BT5Date2Secs(filedt)
77//      print date2secs(2010,11,7)
78       
79        // as of Feb 6 2019, USANS is using NICE for data collection rather than ICP
80        // as a consequence, the data file is somewhat different. Specifically, the
81        // order of the detectors in the comma-delimited list is different, with the
82        // 5 main detectors all listed in order, rather than separated.
83        // --- I can either flag on the date, or set a global to switch
84        // I also do not know if there will be any other changes in the data file format
85       
86        Variable useNewDataFormat
87
88// test by date
89        Variable thisFileSecs
90        NVAR switchSecs = root:Packages:NIST:USANS:Globals:MainPanel:gFileSwitchSecs
91        thisFileSecs = BT5DateTime2Secs(filedt)         // could use BT5Date2Secs() to exclude HR:MIN
92        if(thisFileSecs >= switchSecs)
93                useNewDataFormat = 1
94        else
95                useNewDataFormat = 0
96        endif
97
98       
99        USANS_DetectorDeadtime(filedt,MainDeadTime,TransDeadTime)
100       
101        //skip line 2
102        FReadLine refnum,buffer
103        //the next line is the sample label, use it all, minus the terminator
104        FReadLine refnum,filelabel
105       
106        //skip the next 10 lines
107        For(ii=0;ii<10;ii+=1)
108                FReadLine refnum,buffer
109        EndFor
110       
111        //read the data until EOF - assuming always a pair or lines
112        do
113                FReadLine refNum, buffer
114                if (strlen(buffer) == 0)
115                        break                                                   // End of file
116                endif
117                firstChar = char2num(buffer[0])
118                if ( (firstChar==10) || (firstChar==13) )
119                        break                                                   // Hit blank line. End of data in the file.
120                endif
121                sscanf buffer,"%g%g%g%g%g",v1,v2,v3,v4,v5               // 5 values here now
122                angle[numlinesloaded] = v1              //[0] is the ANGLE
123               
124                FReadLine refNum,buffer //assume a 2nd line is there, w/16 values
125                sscanf buffer,"%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g",v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16
126                //valuesRead = V_flag
127                //print valuesRead
128                if(useNewDataFormat == 1)
129                // new order is MonCt, det1,det2,det3,det4,det5, Trans
130                        MonCts[numlinesloaded] = v1             //monitor
131                        v2 = v2/(1.0-v2*MainDeadTime/countTime)   // Deadtime correction
132                        v3 = v3/(1.0-v3*MainDeadTime/countTime)   // Deadtime correction
133                        v4 = v6/(1.0-v4*MainDeadTime/countTime)   // Deadtime correction
134                        v5 = v5/(1.0-v5*MainDeadTime/countTime)   // Deadtime correction
135                        v6 = v6/(1.0-v6*MainDeadTime/countTime)   // Deadtime correction
136                        DetCts[numlinesloaded] = v2 + v3 + v4 + v5 + v6         //5 detectors
137                        TransCts[numlinesloaded] = v7/(1.0-v7*TransDeadTime/countTime)          //trans detector+deadtime correction
138                        ErrDetCts[numlinesloaded] = sqrt(detCts[numlinesloaded])
139                        //values 8-16 are always zero
140                else
141                // this is the original format from ICP
142                        MonCts[numlinesloaded] = v1             //monitor
143                        v2 = v2/(1.0-v2*MainDeadTime/countTime)   // Deadtime correction
144                        v3 = v3/(1.0-v3*MainDeadTime/countTime)   // Deadtime correction
145                        v5 = v5/(1.0-v5*MainDeadTime/countTime)   // Deadtime correction
146                        v6 = v6/(1.0-v6*MainDeadTime/countTime)   // Deadtime correction
147                        v7 = v7/(1.0-v7*MainDeadTime/countTime)   // Deadtime correction
148                        DetCts[numlinesloaded] = v2 + v3 + v5 + v6 + v7         //5 detectors
149                        TransCts[numlinesloaded] = v4/(1.0-v4*TransDeadTime/countTime)          //trans detector+deadtime correction
150                        ErrDetCts[numlinesloaded] = sqrt(detCts[numlinesloaded])
151                        //values 8-16 are always zero
152                endif
153               
154                numlinesloaded += 1             //2 lines in file read, one "real" line of data
155        while(1)
156               
157        Close refNum            // Close the file.
158        //Print "numlines = ",numlinesloaded
159        //trim the waves to the correct number of points
160        Redimension/N=(numlinesloaded) Angle,MonCts,DetCts,TransCts,ErrDetCts
161       
162        //remove LF from end of filelabel
163        filelabel=fileLabel[0,(strlen(fileLabel)-2)]
164       
165        //set the wave note for the DetCts
166        String str=""
167        str = "FILE:"+filen+";"
168        str += "TIMEPT:"+num2str(counttime)+";"
169        str += "PEAKANG:;"              //no value yet
170        str += "STATUS:;"               //no value yet
171        str += "LABEL:"+fileLabel+";"
172        str += "PEAKVAL:;"              //no value yet
173        str += "TWIDE:0;"               //no value yet
174        Note DetCts,str
175       
176        String/G fileLbl = filelabel
177        return err                      // Zero signifies no error.     
178End
179
180
181//will search for peak in root:type:DetCts,  find and returns the angle
182// of the peak poistion (= q=0)
183//returns -9999 if error, appends value to wavenote
184// !can't return -1,0,1, since these may be the peak angle!
185//
186// MAR 2019
187// if the data is colleced with NICE, the "angle" is really q-values.
188// in this case the returned value is a q-value, and when this shift is applied to the
189// nominal (raw) q-values, the peak value is not converted from angle to q
190//
191//
192Function FindZeroAngle(type)
193        String type
194       
195        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder       
196       
197        Variable pkNotFound,pkPt,pkAngle,pkVal,temp
198        Wave angle = $(USANSFolder+":"+type+":Angle")
199        Wave detCts = $(USANSFolder+":"+type+":DetCts")
200
201
202        WaveStats/Q detcts
203        temp=V_Maxloc           //in points
204        FindPeak/P/Q/M=10/R=[(temp-10),(temp+10)] DetCts                //+/- 10 pts from maximum
205       
206        //FindPeak/P/Q/M=(1000) detCts          // /M=min ht -- peak must be at least 100x higher than 1st pt
207        pkNotFound=V_Flag               //V_Flag==1 if no pk found
208        pkPt = V_PeakLoc
209        pkVal = V_PeakVal               //for calc of T_rock
210        if(pkNotFound)
211                //DoAlert 0, "Peak not found"
212                Return (-9999)          //fatal error
213        Endif
214        pkAngle = Angle[pkPt]
215       
216        Print "Peak Angle = ",pkAngle
217        //update the note
218        String str=""
219        str=note(DetCts)
220        str = ReplaceNumberByKey("PEAKANG",str,pkangle,":",";")
221        str = ReplaceNumberByKey("PEAKVAL",str,pkVal,":",";")
222        Note/K DetCts
223        Note detCts,str
224       
225        return(pkAngle)
226End
227
228// given the peakAngle (q=0) and the "type" folder of scattering angle,
229// convert the angle to Q-values [degrees to (1/A)]
230// makes a new Qvals wave, duplicating the Angle wave, which is assumed to exist
231// Uses a conversion constant supplied by John Barker, and is hard-wired in
232//
233//      Mar 2019
234// if the data is collected from NICE, the data is in terms of Q, not angle since the
235// conversion factor has already been applied. In this case, the "angle" and pkAngle
236// are actually in terms of Q, and the deg2QConv value is set to == 1
237// -- then nothing needs to be changed
238//
239Function ConvertAngle2Qvals(type,pkAngle)
240        String type
241        Variable pkAngle
242
243        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
244       
245        Wave angle = $(USANSFolder+":"+type+":Angle")
246        Variable num=numpnts(angle)
247//      Variable deg2QConv=5.55e-5              //JGB -- 2/24/01
248        NVAR deg2QConv=root:Packages:NIST:USANS:Globals:MainPanel:deg2QConv
249
250       
251        Make/O/N=(num) $(USANSFolder+":"+type+":Qvals")
252        Wave qvals = $(USANSFolder+":"+type+":Qvals")   
253        Qvals = deg2QConv*(angle[p] - pkAngle)
254       
255        return(0)       //no error
256End
257
258//updates the wavenote with the average Trans det cts for calculation of T_Wide
259//  finds the average number of counts on the transmission detector at angles
260// greater than 2 deg. (per John, practical experience where the trans data levels off)
261//
262// error value of 1 is returned and wavenote not updated if level is not found
263//
264// now normalizes to the monitor counts
265//
266// 17 APR 2013 SRK - coverted the 2 degree "cutoff" to use q-values instead. Then the
267//  location is generic and can be used for either NCNR or KUSANS
268//
269Function FindTWideCts(type)
270        String type
271       
272        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
273       
274        Variable levNotFound,levPt,Cts,num,ii,sumMonCts
275       
276        Wave angle = $(USANSFolder+":"+type+":Angle")
277        Wave detCts = $(USANSFolder+":"+type+":DetCts")
278        Wave TransCts = $(USANSFolder+":"+type+":TransCts")
279        Wave monCts = $(USANSFolder+":"+type+":MonCts")
280        Wave Qvals = $(USANSFolder+":"+type+":Qvals")
281       
282        num=numpnts(TransCts)
283
284//      FindLevel/Q/P angle,2           //use angles greater than 2 deg
285//      Print "Using angle, pt = ",V_levelX
286       
287        FindLevel/Q/P Qvals,1e-4                //use angles greater than 2 deg = 2*5.55e-5 = 1e-4 (1/A)
288//      Print "Using Qval, pt = ",V_levelX
289
290        levNotFound=V_Flag              //V_Flag==1 if no pk found
291       
292        if(levNotFound)
293                //post a warning, and use just the last 4 points...
294//              DoAlert 0,"You don't have "+type+" data past 2 degrees - so Twide may not be reliable"
295                DoAlert 0,"You don't have "+type+" data past 1e-4 A-1 (~2 degrees) - so Twide may not be reliable"
296                levPt = num-4
297        else
298                levPt = trunc(V_LevelX)         // in points, force to integer
299        endif
300       
301        //average the trans cts from levPt to the end of the dataset
302        Cts=0
303        sumMonCts=0
304       
305        for(ii=levPt;ii<num;ii+=1)
306                Cts += transCts[ii]
307                sumMonCts += monCts[ii]
308        endfor
309        // get the average over that number of data points
310        sumMonCts /= (num-levPt-1)
311        Cts /= (num-levPt-1)
312       
313//      Print "cts = ",cts
314//      Print "sumMoncts = ",sumMoncts
315       
316        //normalize to the average monitor counts
317        Cts /= sumMonCts
318       
319//      Print "normalized counts = ",cts
320
321
322        //update the note
323        Wave DetCts = $(USANSFolder+":"+type+":DetCts")
324        String str,strVal
325        str=note(DetCts)
326        str = ReplaceNumberByKey("TWIDE",str,Cts,":",";")
327        Note/K DetCts
328        Note detCts,str
329
330        return(0)
331End
332
333
334Function BT5DateTime2Secs(datestring)
335        String datestring
336       
337        Variable bt5secs
338       
339        String monthnums = "Jan:1;Feb:2;Mar:3;Apr:4;May:5;Jun:6;Jul:7;Aug:8;Sep:9;Oct:10;Nov:11;Dec:12"
340               
341        Variable bt5month = str2num(StringByKey(stringfromlist(0,datestring, " "),monthnums))
342        Variable bt5day = str2num(stringfromlist(1,datestring," "))
343        Variable bt5year = str2num(stringfromlist(2,datestring," "))
344        Variable bt5hours = str2num(stringfromlist(0,stringfromlist(3,datestring," "),":"))
345        Variable bt5mins = str2num(stringfromlist(1,stringfromlist(3,datestring," "),":"))
346       
347        bt5secs = date2secs(bt5year,bt5month,bt5day) + 3600*bt5hours + 60*bt5mins
348
349        return bt5secs
350End
351
352Function BT5Date2Secs(datestring)
353        String datestring
354       
355        Variable bt5secs
356       
357        String monthnums = "Jan:1;Feb:2;Mar:3;Apr:4;May:5;Jun:6;Jul:7;Aug:8;Sep:9;Oct:10;Nov:11;Dec:12"
358               
359        Variable bt5month = str2num(StringByKey(stringfromlist(0,datestring, " "),monthnums))
360        Variable bt5day = str2num(stringfromlist(1,datestring," "))
361        Variable bt5year = str2num(stringfromlist(2,datestring," "))
362       
363        bt5secs = date2secs(bt5year,bt5month,bt5day)
364
365        return bt5secs
366End
Note: See TracBrowser for help on using the repository browser.