source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/NCNR_Utils.ipf @ 708

Last change on this file since 708 was 708, checked in by srkline, 12 years ago

SA_Includes_v410 : now include Smear_2D

PeakGauss_2D, Sphere_2D : included threaded resolution smearing calculations for testing

DataSetHandling? : Included a quick and dirty batch converter for XML->6-col. See the top
of the file for the command to run

GaussUtils? : re-define the ResSemear_2D_AAOStruct. Relocated q-value and phi calculations from
RawWindowHook? to this file so they would be available for reduction and analysis

Smear_2D : now has a generic (non-threaded) smearing routine. Threading must be done in
individual functions since FUNCREF can't be passed to threads (plus a few other issues)

PlotUtils_2D : updated loader for new QxQy? columns. Fixes to Wrapper_2D to enable smeared fits

RawWindowHook? : removed Q-value calculation functions and moved these to GaussUtils?

WriteQIS : now writes out 8-columns for QxQy? data, defining the resolution
function in terms of directions parallel and perpendicular to Q. TEMPORARILY in the data
file an error in intensity is generated that is SQRT(I), being careful to
replace any NaN, inf, or zero with an average error value

MultiScatter_MonteCarlo_2D : 4-processor aware

NCNR_Utils : 2D resolution calculation is now in terms of parallel and perpendicular
rather than x and y. Gravity is included in the y-component

File size: 44.9 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
4
5// this file contains globals and functions that are specific to a
6// particular facility or data file format
7// branched out 29MAR07 - SRK
8//
9// functions are either labeled with the procedure file that calls them,
10// or noted that they are local to this file
11
12
13// initializes globals that are specific to a particular facility
14// - number of XY pixels
15// - pixexl resolution [cm]
16// - detector deadtime constant [s]
17//
18// called by Initialize.ipf
19//
20Function InitFacilityGlobals()
21
22        //Detector -specific globals
23        Variable/G root:myGlobals:gNPixelsX=128
24        Variable/G root:myGlobals:gNPixelsY=128
25       
26        // as of Jan2008, detector pixel sizes are read directly from the file header, so they MUST
27        // be set correctly in instr.cfg
28        Variable/G root:myGlobals:PixelResNG3_ILL = 1.0         //pixel resolution in cm
29        Variable/G root:myGlobals:PixelResNG5_ILL = 1.0
30        Variable/G root:myGlobals:PixelResNG7_ILL = 1.0
31        Variable/G root:myGlobals:PixelResNG3_ORNL = 0.5
32        Variable/G root:myGlobals:PixelResNG5_ORNL = 0.5
33        Variable/G root:myGlobals:PixelResNG7_ORNL = 0.5
34        Variable/G root:myGlobals:PixelResDefault = 0.5
35       
36        Variable/G root:myGlobals:DeadtimeNG3_ILL = 3.0e-6              //deadtime in seconds
37        Variable/G root:myGlobals:DeadtimeNG5_ILL = 3.0e-6
38        Variable/G root:myGlobals:DeadtimeNG7_ILL = 3.0e-6
39        Variable/G root:myGlobals:DeadtimeNG3_ORNL = 3.4e-6
40        Variable/G root:myGlobals:DeadtimeNG5_ORNL = 0.6e-6             //as of 9 MAY 2002
41        Variable/G root:myGlobals:DeadtimeNG7_ORNL = 3.4e-6
42        Variable/G root:myGlobals:DeadtimeDefault = 3.4e-6
43       
44        //new 11APR07
45        Variable/G root:myGlobals:BeamstopXTol = -8                     // (cm) is BS Xpos is -5 cm or less, it's a trans measurement
46        // sample aperture offset is NOT stored in the VAX header, but it should be
47        // - when it is, remove the global and write an accessor AND make a place for
48        // it in the RealsRead
49        Variable/G root:myGlobals:apOff = 5.0                           // (cm) distance from sample aperture to sample position
50
51End
52
53
54//**********************
55// Resolution calculation - used by the averaging routines
56// to calculate the resolution function at each q-value
57// - the return value is not used
58//
59// equivalent to John's routine on the VAX Q_SIGMA_AVE.FOR
60// Incorporates eqn. 3-15 from J. Appl. Cryst. (1995) v. 28 p105-114
61//
62// - 21 MAR 07 uses projected BS diameter on the detector
63// - APR 07 still need to add resolution with lenses. currently there is no flag in the
64//          raw data header to indicate the presence of lenses.
65//
66// - Aug 07 - added input to switch calculation based on lenses (==1 if in)
67//
68// - called by CircSectAvg.ipf and RectAnnulAvg.ipf
69//
70// passed values are read from RealsRead
71// except DDet and apOff, which are set from globals before passing
72//
73//
74Function/S getResolution(inQ,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,SigmaQ,QBar,fSubS)
75        Variable inQ, lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses
76        Variable &fSubS, &QBar, &SigmaQ         //these are the output quantities at the input Q value
77       
78        //lots of calculation variables
79        Variable a2, q_small, lp, v_lambda, v_b, v_d, vz, yg, v_g
80        Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r
81
82        //Constants
83        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
84        Variable g = 981.0                              //gravity acceleration [cm/s^2]
85
86        String results
87        results ="Failure"
88
89        S1 *= 0.5*0.1                   //convert to radius and [cm]
90        S2 *= 0.5*0.1
91
92        L1 *= 100.0                     // [cm]
93        L1 -= apOff                             //correct the distance
94
95        L2 *= 100.0
96        L2 += apOff
97        del_r *= 0.1                            //width of annulus, convert mm to [cm]
98       
99        BS *= 0.5*0.1                   //nominal BS diameter passed in, convert to radius and [cm]
100        // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture
101        Variable LB
102        LB = 20.1 + 1.61*BS                     //distance in cm from beamstop to anode plane (empirical)
103        BS = bs + bs*lb/(l2-lb)         //adjusted diameter of shadow from parallax
104       
105        //Start resolution calculation
106        a2 = S1*L2/L1 + S2*(L1+L2)/L1
107        q_small = 2.0*Pi*(BS-a2)*(1.0-lambdaWidth)/(lambda*L2)
108        lp = 1.0/( 1.0/L1 + 1.0/L2)
109
110        v_lambda = lambdaWidth^2/6.0
111       
112//      if(usingLenses==1)                      //SRK 2007
113        if(usingLenses != 0)                    //SRK 2008 allows for the possibility of different numbers of lenses in header
114                v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2         //correction to 2nd term
115        else
116                v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2              //original form
117        endif
118       
119        v_d = (DDet/2.3548)^2 + del_r^2/12.0
120        vz = vz_1 / lambda
121        yg = 0.5*g*L2*(L1+L2)/vz^2
122        v_g = 2.0*(2.0*yg^2*v_lambda)                                   //factor of 2 correction, B. Hammouda, 2007
123
124        r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) ))
125        delta = 0.5*(BS - r0)^2/v_d
126
127        if (r0 < BS)
128                inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta))
129        else
130                inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta))
131        endif
132
133        fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) )
134        if (fSubS <= 0.0)
135                fSubS = 1.e-10
136        endif
137        fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi))
138        fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d
139
140        rmd = fr*r0
141        v_r1 = v_b + fv*v_d +v_g
142
143        rm = rmd + 0.5*v_r1/rmd
144        v_r = v_r1 - 0.5*(v_r1/rmd)^2
145        if (v_r < 0.0)
146                v_r = 0.0
147        endif
148        QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2))
149        SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda)
150
151        results = "success"
152        Return results
153End
154
155
156//
157//**********************
158// 2D resolution function calculation - ***NOT*** in terms of X and Y
159// but written in terms of Parallel and perpendicular to the Q vector at each point
160//
161// -- it must be written this way since the 2D function is an ellipse with its major
162// axis pointing in the direction of Q_parallel. Hence there is no way to properly define the
163// elliptical gaussian in terms of sigmaX and sigmaY
164//
165// based on notes from David Mildner, 2008
166//
167//
168// - 21 MAR 07 uses projected BS diameter on the detector
169// - APR 07 still need to add resolution with lenses. currently there is no flag in the
170//          raw data header to indicate the presence of lenses.
171//
172// - Aug 07 - added input to switch calculation based on lenses (==1 if in)
173//
174// passed values are read from RealsRead
175// except DDet and apOff, which are set from globals before passing
176//
177// phi is the azimuthal angle, CCW from +x axis
178// r_dist is the real-space distance from ctr of detector to QxQy pixel location
179//
180Function/S get2DResolution(inQ,phi,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,r_dist,SigmaQX,SigmaQY,fSubS)
181        Variable inQ, phi,lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses,r_dist
182        Variable &SigmaQX,&SigmaQY,&fSubS               //these are the output quantities at the input Q value
183       
184        //lots of calculation variables
185        Variable a2, lp, v_lambda, v_b, v_d, vz, yg, v_g
186        Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r
187
188        //Constants
189        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
190        Variable g = 981.0                              //gravity acceleration [cm/s^2]
191        Variable m_h    = 252.8                 // m/h [=] s/cm^2
192
193        String results
194        results ="Failure"
195
196        S1 *= 0.5*0.1                   //convert to radius and [cm]
197        S2 *= 0.5*0.1
198
199        L1 *= 100.0                     // [cm]
200        L1 -= apOff                             //correct the distance
201
202        L2 *= 100.0
203        L2 += apOff
204        del_r *= 0.1                            //width of annulus, convert mm to [cm]
205       
206        BS *= 0.5*0.1                   //nominal BS diameter passed in, convert to radius and [cm]
207        // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture
208        Variable LB
209        LB = 20.1 + 1.61*BS                     //distance in cm from beamstop to anode plane (empirical)
210        BS = bs + bs*lb/(l2-lb)         //adjusted diameter of shadow from parallax
211       
212        //Start resolution calculation
213        a2 = S1*L2/L1 + S2*(L1+L2)/L1
214        lp = 1.0/( 1.0/L1 + 1.0/L2)
215
216        v_lambda = lambdaWidth^2/6.0
217       
218//      if(usingLenses==1)                      //SRK 2007
219        if(usingLenses != 0)                    //SRK 2008 allows for the possibility of different numbers of lenses in header
220                v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2         //correction to 2nd term
221        else
222                v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2              //original form
223        endif
224       
225        v_d = (DDet/2.3548)^2 + del_r^2/12.0
226        vz = vz_1 / lambda
227        yg = 0.5*g*L2*(L1+L2)/vz^2
228        v_g = 2.0*(2.0*yg^2*v_lambda)                                   //factor of 2 correction, B. Hammouda, 2007
229
230        r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) ))
231        delta = 0.5*(BS - r0)^2/v_d
232
233        if (r0 < BS)
234                inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta))
235        else
236                inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta))
237        endif
238
239        fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) )
240        if (fSubS <= 0.0)
241                fSubS = 1.e-10
242        endif
243//      fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi))
244//      fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d
245//
246//      rmd = fr*r0
247//      v_r1 = v_b + fv*v_d +v_g
248//
249//      rm = rmd + 0.5*v_r1/rmd
250//      v_r = v_r1 - 0.5*(v_r1/rmd)^2
251//      if (v_r < 0.0)
252//              v_r = 0.0
253//      endif
254
255        Variable kap,a_val,a_val_L2
256       
257        kap = 2*pi/lambda
258        a_val = L2*(L1+L2)*g/2*(m_h)^2
259        a_val_L2 = a_val/L2*1e-16               //convert 1/cm^2 to 1/A^2
260
261
262///////// in terms of Q_parallel ("x") and Q_perp ("y") - this works, since parallel is in the direction of Q and I
263// can calculate that from the QxQy (I just need the projection)
264
265
266// for test case with no gravity, set a_val = 0
267// note that gravity has no wavelength dependence. the lambda^4 cancels out.
268//
269//      a_val = 0
270
271        // the detector pixel is square, so correct for phi
272        DDet = DDet*cos(phi) + DDet*sin(phi)
273       
274        // this is really sigma_Q_parallel
275        SigmaQX = kap*kap/12* (3*(S1/L1)^2 + 3*(S2/LP)^2 + (DDet/L2)^2 + (del_r/L2)^2 + (sin(phi))^2*8*(a_val_L2)^2*lambda^4*lambdaWidth^2)
276        SigmaQX += inQ*inQ*v_lambda
277
278        //this is really sigma_Q_perpendicular
279        SigmaQY = 3*(S1/L1)^2 + 3*(S2/LP)^2 + (DDet/L2)^2 + (del_r/L2)^2 + (cos(phi))^2*8*(a_val_L2)^2*lambda^4*lambdaWidth^2
280        SigmaQY *= kap*kap/12
281       
282        SigmaQX = sqrt(SigmaQX)
283        SigmaQy = sqrt(SigmaQY)
284       
285       
286        results = "success"
287        Return results
288End
289
290
291
292
293//Utility function that returns the detector resolution (in cm)
294//Global values are set in the Initialize procedure
295//
296//
297// - called by CircSectAvg.ipf, RectAnnulAvg.ipf, and ProtocolAsPanel.ipf
298//
299// fileStr is passed as TextRead[3]
300// detStr is passed as TextRead[9]
301//
302// *** as of Jan 2008, depricated. Now detector pixel sizes are read from the file header
303// rw[10] = x size (mm); rw[13] = y size (mm)
304//
305Function xDetectorPixelResolution(fileStr,detStr)
306        String fileStr,detStr
307       
308        Variable DDet
309        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
310       
311        NVAR PixelResNG3_ILL = root:myGlobals:PixelResNG3_ILL           //pixel resolution in cm
312        NVAR PixelResNG5_ILL = root:myGlobals:PixelResNG5_ILL
313        NVAR PixelResNG7_ILL = root:myGlobals:PixelResNG7_ILL
314        NVAR PixelResNG3_ORNL = root:myGlobals:PixelResNG3_ORNL
315        NVAR PixelResNG5_ORNL = root:myGlobals:PixelResNG5_ORNL
316        NVAR PixelResNG7_ORNL = root:myGlobals:PixelResNG7_ORNL
317        NVAR PixelResDefault = root:myGlobals:PixelResDefault
318       
319        strswitch(instr)
320                case "NG3":
321                        if(cmpstr(detStr, "ILL   ") == 0 )
322                                DDet= PixelResNG3_ILL
323                        else
324                                DDet = PixelResNG3_ORNL //detector is ordella-type
325                        endif
326                        break
327                case "NG5":
328                        if(cmpstr(detStr, "ILL   ") == 0 )
329                                DDet= PixelResNG5_ILL
330                        else
331                                DDet = PixelResNG5_ORNL //detector is ordella-type
332                        endif
333                        break
334                case "NG7":
335                        if(cmpstr(detStr, "ILL   ") == 0 )
336                                DDet= PixelResNG7_ILL
337                        else
338                                DDet = PixelResNG7_ORNL //detector is ordella-type
339                        endif
340                        break
341                default:                                                       
342                        //return error?
343                        DDet = PixelResDefault  //0.5 cm, typical for new ORNL detectors
344        endswitch
345       
346        return(DDet)
347End
348
349//Utility function that returns the detector deadtime (in seconds)
350//Global values are set in the Initialize procedure
351//
352// - called by WorkFileUtils.ipf
353//
354// fileStr is passed as TextRead[3]
355// detStr is passed as TextRead[9]
356//
357Function DetectorDeadtime(fileStr,detStr)
358        String fileStr,detStr
359       
360        Variable deadtime
361        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
362       
363        NVAR DeadtimeNG3_ILL = root:myGlobals:DeadtimeNG3_ILL           //pixel resolution in cm
364        NVAR DeadtimeNG5_ILL = root:myGlobals:DeadtimeNG5_ILL
365        NVAR DeadtimeNG7_ILL = root:myGlobals:DeadtimeNG7_ILL
366        NVAR DeadtimeNG3_ORNL = root:myGlobals:DeadtimeNG3_ORNL
367        NVAR DeadtimeNG5_ORNL = root:myGlobals:DeadtimeNG5_ORNL
368        NVAR DeadtimeNG7_ORNL = root:myGlobals:DeadtimeNG7_ORNL
369        NVAR DeadtimeDefault = root:myGlobals:DeadtimeDefault
370       
371        strswitch(instr)
372                case "NG3":
373                        if(cmpstr(detStr, "ILL   ") == 0 )
374                                deadtime= DeadtimeNG3_ILL
375                        else
376                                deadtime = DeadtimeNG3_ORNL     //detector is ordella-type
377                        endif
378                        break
379                case "NG5":
380                        if(cmpstr(detStr, "ILL   ") == 0 )
381                                deadtime= DeadtimeNG5_ILL
382                        else
383                                deadtime = DeadtimeNG5_ORNL     //detector is ordella-type
384                        endif
385                        break
386                case "NG7":
387                        if(cmpstr(detStr, "ILL   ") == 0 )
388                                deadtime= DeadtimeNG7_ILL
389                        else
390                                deadtime = DeadtimeNG7_ORNL     //detector is ordella-type
391                        endif
392                        break
393                default:                                                       
394                        //return error?
395                        deadtime = DeadtimeDefault      //1e-6 seconds, typical for new ORNL detectors
396        endswitch
397       
398        return(deadtime)
399End
400
401
402/////VAX filename/Run number parsing utilities
403//
404// a collection of uilities for processing vax filenames
405//and processing lists (especially for display in popup menus)
406//
407//required to correctly account for VAX supplied version numbers, which
408//may or may not be removed by the ftp utility
409//
410// - parses lists of run numbers into real filenames
411// - selects proper detector constants
412//
413//**************************
414//
415//given a filename of a SANS data filename of the form
416//TTTTTnnn.SAn_TTT_Txxx
417//returns the run number "nnn" as a number
418//returns -1 as an invalid file number
419//
420// called by several ipfs
421//
422//
423Function GetRunNumFromFile(item)
424        String item
425        Variable invalid = -1   //negative numbers are invalid
426        Variable num=-1
427       
428        //find the "dot"
429        String runStr=""
430        Variable pos = strsearch(item,".",0)
431        if(pos == -1)
432                //"dot" not found
433                return (invalid)
434        else
435                //found, get the three characters preceeding it
436                if (pos <=2)
437                        //not enough characters
438                        return (invalid)
439                else
440                        runStr = item[pos-3,pos-1]
441                        //convert to a number
442                        num = str2num(runStr)
443                        //if valid, return it
444                        if (num == NaN)
445                                //3 characters were not a number
446                                return (invalid)
447                        else
448                                //run was OK
449                                return (num)
450                        Endif
451                Endif
452        Endif
453End
454
455//given a filename of a SANS data filename of the form
456//TTTTTnnn.SAn_TTT_Txxx
457//returns the run number "nnn" as a STRING of THREE characters
458//returns "ABC" as an invalid file number
459//
460// local function to aid in locating files by run number
461//
462Function/S GetRunNumStrFromFile(item)
463        String item
464        String invalid = "ABC"  //"ABC" is not a valid run number, since it's text
465        Variable num=-1
466       
467        //find the "dot"
468        String runStr=""
469        Variable pos = strsearch(item,".",0)
470        if(pos == -1)
471                //"dot" not found
472                return (invalid)
473        else
474                //found, get the three characters preceeding it
475                if (pos <=2)
476                        //not enough characters
477                        return (invalid)
478                else
479                        runStr = item[pos-3,pos-1]
480                        return (runStr)
481                Endif
482        Endif
483End
484
485//returns a string containing the full path to the file containing the
486//run number "num". The null string is returned if no valid file can be found
487//the path "catPathName" used and is hard-wired, will abort if this path does not exist
488//the file returned will be a RAW SANS data file, other types of files are
489//filtered out.
490//
491// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
492//
493Function/S FindFileFromRunNumber(num)
494        Variable num
495       
496        String fullName="",partialName="",item=""
497        //get list of raw data files in folder that match "num" (add leading zeros)
498        if( (num>999) || (num<=0) )
499                //Print "error in  FindFileFromRunNumber(num), file number too large or too small"
500                Return ("")
501        Endif
502        //make a three character string of the run number
503        String numStr=""
504        if(num<10)
505                numStr = "00"+num2str(num)
506        else
507                if(num<100)
508                        numStr = "0"+num2str(num)
509                else
510                        numStr = num2str(num)
511                Endif
512        Endif
513        //Print "numstr = ",numstr
514       
515        //make sure that path exists
516        PathInfo catPathName
517        String path = S_path
518        if (V_flag == 0)
519                Abort "folder path does not exist - use Pick Path button"
520        Endif
521        String list="",newList="",testStr=""
522       
523        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
524        //find (the) one with the number in the run # location in the name
525        Variable numItems,ii,runFound,isRAW
526        numItems = ItemsInList(list,";")                //get the new number of items in the list
527        ii=0
528        do
529                //parse through the list in this order:
530                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
531                // 2 - exclude by isRaw? (to minimize disk access)
532                item = StringFromList(ii, list  ,";" )
533                if(strlen(item) != 0)
534                        //find the run number, if it exists as a three character string
535                        testStr = GetRunNumStrFromFile(item)
536                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
537                        if(runFound == 0)
538                                //the run Number was found
539                                //build valid filename
540                                partialName = FindValidFileName(item)
541                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
542                                        fullName = path + partialName
543                                        //check if RAW, if so,this must be the file!
544                                        isRAW = CheckIfRawData(fullName)
545                                        if(isRaw)
546                                                //stop here
547                                                return(fullname)
548                                        Endif
549                                Endif
550                        Endif
551                Endif
552                ii+=1
553        while(ii<numItems)              //process all items in list
554        Return ("")     //null return if file not found in list
555End
556
557//function to test a binary file to see if it is a RAW binary SANS file
558//first checks the total bytes in the file (which for raw data is 33316 bytes)
559//**note that the "DIV" file will also show up as a raw file by the run field
560//should be listed in CAT/SHORT and in patch windows
561//
562//Function then checks the file fname (full path:file) for "RAW" run.type field
563//if not found, the data is not raw data and zero is returned
564//
565// called by many procedures (both external and local)
566//
567Function CheckIfRawData(fname)
568        String fname
569       
570        Variable refnum,totalBytes
571        String testStr=""
572       
573        Open/R/T="????TEXT" refNum as fname
574        if(strlen(s_filename) == 0)     //user cancel (/Z not used, so V_flag not set)
575                return(0)
576        endif
577       
578        //get the total number of bytes in the file
579        FStatus refNum
580        totalBytes = V_logEOF
581        //Print totalBytes
582        if(totalBytes < 100)
583                Close refNum
584                return(0)               //not a raw file
585        endif
586        FSetPos refNum,75
587        FReadLine/N=3 refNum,testStr
588        Close refNum
589       
590        if(totalBytes == 33316 && ( cmpstr(testStr,"RAW")==0 ||  cmpstr(testStr,"SIM")==0))
591                //true, is raw data file
592                Return(1)
593        else
594                //some other file
595                Return(0)
596        Endif
597End
598
599//function to check the header of a raw data file (full path specified by fname)
600//checks the field of the x-position of the beamstop during data collection
601//if the x-position is more negative (farther to the left) than xTol(input)
602//the the beamstop is "out" and the file is a transmission run and not a scattering run
603//xtol typically set at -5 (cm) - trans runs have bs(x) at -10 to -15 cm
604// function returns 1 if beamstop is out, 0 if beamstop is in
605//
606// tolerance is set as a global value "root:myGlobals:BeamstopXTol"
607//
608// called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf
609//
610Function isTransFile(fName)
611        String fname
612       
613        Variable refnum,xpos
614        NVAR xTol = root:myGlobals:BeamstopXTol
615       
616        //pos = 369, read one real value
617       
618        SetDataFolder root:
619        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
620        String strToExecute=""
621        // 1 R*4 value
622        strToExecute = GBLoadStr + "/S=368/U=1" + "\"" + fname + "\""
623        Execute strToExecute
624        Wave w=$"root:tempGBWave0"
625        xPos = w[0]
626        KillWaves/Z w
627        //Print "xPos = ",xpos
628       
629        if(xpos<=xTol)
630                //xpos is farther left (more negative) than xtol (currently -5 cm)
631                Return(1)
632        else
633                //some other file
634                Return(0)
635        Endif
636End
637
638
639//function to remove all spaces from names when searching for filenames
640//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
641//but the text field in the header WILL, if less than 3 characters were used for the
642//user's initials, and can have leading spaces if prefix was less than 5 characters
643//
644//returns a string identical to the original string, except with the interior spaces removed
645//
646// local function for file name manipulation
647//
648Function/S RemoveAllSpaces(str)
649        String str
650       
651        String tempstr = str
652        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
653        ii=0
654        do
655                len = strlen(tempStr)
656                spc = strsearch(tempStr," ",0)          //is the last character a space?
657                if (spc == -1)
658                        break           //no more spaces found, get out
659                endif
660                str = tempstr
661                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
662        While(1)        //should never be more than 2 or 3
663       
664        If(strlen(tempStr) < 1)
665                tempStr = ""            //be sure to return a null string if problem found
666        Endif
667       
668        //Print strlen(tempstr)
669       
670        Return(tempStr)
671               
672End
673
674
675//Function attempts to find valid filename from partial name by checking for
676// the existence of the file on disk.
677// - checks as is
678// - adds ";vers" for possible VAX files
679// - strips spaces
680// - permutations of upper/lowercase
681//
682// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
683// since from marquee, the filename field (textread[0]) must be used, and can be a mix of
684// upper/lowercase letters, while the filename on the server (should) be all caps
685// now makes repeated calls to ValidFileString()
686//
687// returns a valid filename (No path prepended) or a null string
688//
689// called by any functions, both external and local
690//
691Function/S FindValidFilename(partialName)
692        String PartialName
693       
694        String retStr=""
695       
696        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
697        retStr = ValidFileString(partialName)
698        if(cmpstr(retStr,"") !=0)
699                //non-null return
700                return(retStr)
701        Endif
702       
703        //if the partial name is derived from the file header, there can be spaces at the beginning
704        //or in the middle of the filename - depending on the prefix and initials used
705        //
706        //remove any leading spaces from the name before starting
707        partialName = RemoveAllSpaces(partialName)
708       
709        //try name with no spaces
710        retStr = ValidFileString(partialName)
711        if(cmpstr(retStr,"") !=0)
712                //non-null return
713                return(retStr)
714        Endif
715       
716        //try all UPPERCASE
717        partialName = UpperStr(partialName)
718        retStr = ValidFileString(partialName)
719        if(cmpstr(retStr,"") !=0)
720                //non-null return
721                return(retStr)
722        Endif
723       
724        //try all lowercase (ret null if failure)
725        partialName = LowerStr(partialName)
726        retStr = ValidFileString(partialName)
727        if(cmpstr(retStr,"") !=0)
728                //non-null return
729                return(retStr)
730        else
731                return(retStr)
732        Endif
733End
734
735// Function checks for the existence of a file
736// partialName;vers (to account for VAX filenaming conventions)
737// The partial name is tried first with no version number
738//
739// *** the PATH is hard-wired to catPathName (which is assumed to exist)
740// version numers up to ;10 are tried
741// only the "name;vers" is returned if successful. The path is not prepended
742//
743// local function
744//
745Function/S ValidFileString(partialName)
746        String partialName
747       
748        String tempName = "",msg=""
749        Variable ii,refnum
750       
751        ii=0
752        do
753                if(ii==0)
754                        //first pass, try the partialName
755                        tempName = partialName
756                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
757                        if(V_flag == 0)
758                                //file exists
759                                Close refnum            //YES needed,
760                                break
761                        endif
762                else
763                        tempName = partialName + ";" + num2str(ii)
764                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
765                        if(V_flag == 0)
766                                //file exists
767                                Close refnum
768                                break
769                        endif
770                Endif
771                ii+=1
772                //print "ii=",ii
773        while(ii<11)
774        //go get the selected bits of information, using tempName, which exists
775        if(ii>=11)
776                //msg = partialName + " not found. is version number > 11?"
777                //DoAlert 0, msg
778                //PathInfo catPathName
779                //Print S_Path
780                Return ("")             //use null string as error condition
781        Endif
782       
783        Return (tempName)
784End
785
786//returns a string containing filename (WITHOUT the ;vers)
787//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
788//with the folders separated by colons
789//
790// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
791//
792Function/S GetFileNameFromPathNoSemi(fullPath)
793        String fullPath
794       
795        Variable offset1,offset2
796        String filename=""
797        //String PartialPath
798        offset1 = 0
799        do
800                offset2 = StrSearch(fullPath, ":", offset1)
801                if (offset2 == -1)                              // no more colons ?
802                        fileName = FullPath[offset1,strlen(FullPath) ]
803                        //PartialPath = FullPath[0, offset1-1]
804                        break
805                endif
806                offset1 = offset2+1
807        while (1)
808       
809        //remove version number from name, if it's there - format should be: filename;N
810        filename =  StringFromList(0,filename,";")              //returns null if error
811       
812        Return filename
813End
814
815//returns a string containing filename (INCLUDING the ;vers)
816//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
817//with the folders separated by colons
818//
819// local, currently unused
820//
821Function/S GetFileNameFromPathKeepSemi(fullPath)
822        String fullPath
823       
824        Variable offset1,offset2
825        String filename
826        //String PartialPath
827        offset1 = 0
828        do
829                offset2 = StrSearch(fullPath, ":", offset1)
830                if (offset2 == -1)                              // no more colons ?
831                        fileName = FullPath[offset1,strlen(FullPath) ]
832                        //PartialPath = FullPath[0, offset1-1]
833                        break
834                endif
835                offset1 = offset2+1
836        while (1)
837       
838        //keep version number from name, if it's there - format should be: filename;N
839       
840        Return filename
841End
842
843//given the full path and filename (fullPath), strips the data path
844//(Mac-style, separated by colons) and returns this path
845//this partial path is the same string that would be returned from PathInfo, for example
846//
847// - allows the user to save to a different path than catPathName
848//
849// called by WriteQIS.ipf
850//
851Function/S GetPathStrFromfullName(fullPath)
852        String fullPath
853       
854        Variable offset1,offset2
855        //String filename
856        String PartialPath
857        offset1 = 0
858        do
859                offset2 = StrSearch(fullPath, ":", offset1)
860                if (offset2 == -1)                              // no more colons ?
861                        //fileName = FullPath[offset1,strlen(FullPath) ]
862                        PartialPath = FullPath[0, offset1-1]
863                        break
864                endif
865                offset1 = offset2+1
866        while (1)
867       
868        Return PartialPath
869End
870
871//given the VAX filename, pull off the first 8 characters to make a valid
872//file string that can be used for naming averaged 1-d files
873//
874// called by ProtocolAsPanel.ipf and Tile_2D.ipf
875//
876Function/S GetNameFromHeader(fullName)
877        String fullName
878        String temp, newName = ""
879        Variable spc,ii=0
880       
881        //filename is 20 characters NNNNNxxx.SAn_NNN_NNN
882        //want the first 8 characters, NNNNNxxx, then strip off any spaces at the beginning
883        //NNNNN was entered as less than 5 characters
884        //returns a null string if no name can be found
885        do
886                temp = fullname[ii,7]           //characters ii,7 of the name
887                spc = strsearch(temp," ",0)
888                if (spc == -1)
889                        break           //no more spaces found
890                endif
891                ii+=1
892        While(ii<8)
893       
894        If(strlen(temp) < 1)
895                newName = ""            //be sure to return a null string if problem found
896        else
897                newName = temp
898        Endif
899       
900        Return(newName)
901End
902
903//list (input) is a list, typically returned from IndexedFile()
904//which is semicolon-delimited, and may contain filenames from the VAX
905//that contain version numbers, where the version number appears as a separate list item
906//(and also as a non-existent file)
907//these numbers must be purged from the list, especially for display in a popup
908//or list processing of filenames
909//the function returns the list, cleaned of version numbers (up to 11)
910//raw data files will typically never have a version number other than 1.
911//
912// if there are no version numbers in the list, the input list is returned
913//
914// called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf
915//
916Function/S RemoveVersNumsFromList(list)
917        String list
918       
919        //get rid of version numbers first (up to 11)
920        Variable ii,num
921        String item
922        num = ItemsInList(list,";")
923        ii=1
924        do
925                item = num2str(ii)
926                list = RemoveFromList(item, list ,";" )
927                ii+=1
928        while(ii<12)
929       
930        return (list)
931End
932
933//input is a list of run numbers, and output is a list of filenames (not the full path)
934//*** input list must be COMMA delimited***
935//output is equivalent to selecting from the CAT table
936//if some or all of the list items are valid filenames, keep them...
937//if an error is encountered, notify of the offending element and return a null list
938//
939//output is COMMA delimited
940//
941// this routine is expecting that the "ask", "none" special cases are handled elsewhere
942//and not passed here
943//
944// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
945//
946Function/S ParseRunNumberList(list)
947        String list
948       
949        String newList="",item="",tempStr=""
950        Variable num,ii,runNum
951       
952        //expand number ranges, if any
953        list = ExpandNumRanges(list)
954       
955        num=itemsinlist(list,",")
956       
957        for(ii=0;ii<num;ii+=1)
958                //get the item
959                item = StringFromList(ii,list,",")
960                //is it already a valid filename?
961                tempStr=FindValidFilename(item) //returns filename if good, null if error
962                if(strlen(tempstr)!=0)
963                        //valid name, add to list
964                        //Print "it's a file"
965                        newList += tempStr + ","
966                else
967                        //not a valid name
968                        //is it a number?
969                        runNum=str2num(item)
970                        //print runnum
971                        if(numtype(runNum) != 0)
972                                //not a number -  maybe an error                       
973                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
974                                return("")
975                        else
976                                //a run number or an error
977                                tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) )
978                                if(strlen(tempstr)==0)
979                                        //file not found, error
980                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
981                                        return("")
982                                else
983                                        newList += tempStr + ","
984                                endif
985                        endif
986                endif
987        endfor          //loop over all items in list
988       
989        return(newList)
990End
991
992//takes a comma delimited list that MAY contain number range, and
993//expands any range of run numbers into a comma-delimited list...
994//and returns the new list - if not a range, return unchanged
995//
996// local function
997//
998Function/S ExpandNumRanges(list)
999        String list
1000       
1001        String newList="",dash="-",item,str
1002        Variable num,ii,hasDash
1003       
1004        num=itemsinlist(list,",")
1005//      print num
1006        for(ii=0;ii<num;ii+=1)
1007                //get the item
1008                item = StringFromList(ii,list,",")
1009                //does it contain a dash?
1010                hasDash = strsearch(item,dash,0)                //-1 if no dash found
1011                if(hasDash == -1)
1012                        //not a range, keep it in the list
1013                        newList += item + ","
1014                else
1015                        //has a dash (so it's a range), expand (or add null)
1016                        newList += ListFromDash(item)           
1017                endif
1018        endfor
1019       
1020        return newList
1021End
1022
1023//be sure to add a trailing comma to the return string...
1024//
1025// local function
1026//
1027Function/S ListFromDash(item)
1028        String item
1029       
1030        String numList="",loStr="",hiStr=""
1031        Variable lo,hi,ii
1032       
1033        loStr=StringFromList(0,item,"-")        //treat the range as a list
1034        hiStr=StringFromList(1,item,"-")
1035        lo=str2num(loStr)
1036        hi=str2num(hiStr)
1037        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
1038                numList=""
1039                return numList
1040        endif
1041        for(ii=lo;ii<=hi;ii+=1)
1042                numList += num2str(ii) + ","
1043        endfor
1044       
1045        Return numList
1046End
1047
1048
1049////////Transmission
1050//******************
1051//lookup tables for attenuator transmissions
1052//NG3 and NG7 attenuators are physically different, so the transmissions are slightly different
1053//NG1 - (8m SANS) is not supported
1054//
1055// new calibration done June 2007, John Barker
1056//
1057Proc MakeNG3AttenTable()
1058
1059        NewDataFolder/O root:myGlobals:Attenuators
1060        //do explicitly to avoid data folder problems, redundant, but it must work without fail
1061        Variable num=10         //10 needed for tables after June 2007
1062
1063        Make/O/N=(num) root:myGlobals:Attenuators:ng3att0
1064        Make/O/N=(num) root:myGlobals:Attenuators:ng3att1
1065        Make/O/N=(num) root:myGlobals:Attenuators:ng3att2
1066        Make/O/N=(num) root:myGlobals:Attenuators:ng3att3
1067        Make/O/N=(num) root:myGlobals:Attenuators:ng3att4
1068        Make/O/N=(num) root:myGlobals:Attenuators:ng3att5
1069        Make/O/N=(num) root:myGlobals:Attenuators:ng3att6
1070        Make/O/N=(num) root:myGlobals:Attenuators:ng3att7
1071        Make/O/N=(num) root:myGlobals:Attenuators:ng3att8
1072        Make/O/N=(num) root:myGlobals:Attenuators:ng3att9
1073        Make/O/N=(num) root:myGlobals:Attenuators:ng3att10
1074       
1075        //each wave has 10 elements, the transmission of att# at the wavelengths
1076        //lambda = 4,5,6,7,8,10,12,14,17,20 (4 A and 20 A are extrapolated values)
1077        Make/O/N=(num) root:myGlobals:Attenuators:ng3lambda={4,5,6,7,8,10,12,14,17,20}
1078       
1079        // new calibration done June 2007, John Barker
1080        root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
1081        root:myGlobals:Attenuators:ng3att1 = {0.444784,0.419,0.3935,0.3682,0.3492,0.3132,0.2936,0.2767,0.2477,0.22404}
1082        root:myGlobals:Attenuators:ng3att2 = {0.207506,0.1848,0.1629,0.1447,0.1292,0.1056,0.09263,0.08171,0.06656,0.0546552}
1083        root:myGlobals:Attenuators:ng3att3 = {0.092412,0.07746,0.06422,0.05379,0.04512,0.03321,0.02707,0.02237,0.01643,0.0121969}
1084        root:myGlobals:Attenuators:ng3att4 = {0.0417722,0.03302,0.02567,0.02036,0.01604,0.01067,0.00812,0.006316,0.00419,0.00282411}
1085        root:myGlobals:Attenuators:ng3att5 = {0.0187129,0.01397,0.01017,0.007591,0.005668,0.003377,0.002423,0.001771,0.001064,0.000651257}
1086        root:myGlobals:Attenuators:ng3att6 = {0.00851048,0.005984,0.004104,0.002888,0.002029,0.001098,0.0007419,0.0005141,0.000272833,0.000150624}
1087        root:myGlobals:Attenuators:ng3att7 = {0.00170757,0.001084,0.0006469,0.0004142,0.0002607,0.0001201,7.664e-05,4.06624e-05,1.77379e-05,7.30624e-06}
1088        root:myGlobals:Attenuators:ng3att8 = {0.000320057,0.0001918,0.0001025,6.085e-05,3.681e-05,1.835e-05,6.74002e-06,3.25288e-06,1.15321e-06,3.98173e-07}
1089        root:myGlobals:Attenuators:ng3att9 = {6.27682e-05,3.69e-05,1.908e-05,1.196e-05,8.738e-06,6.996e-06,6.2901e-07,2.60221e-07,7.49748e-08,2.08029e-08}
1090        root:myGlobals:Attenuators:ng3att10 = {1.40323e-05,8.51e-06,5.161e-06,4.4e-06,4.273e-06,1.88799e-07,5.87021e-08,2.08169e-08,4.8744e-09,1.08687e-09}
1091 
1092  //old tables, pre-June 2007
1093//      Make/O/N=9 root:myGlobals:Attenuators:ng3lambda={5,6,7,8,10,12,14,17,20}
1094//      root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1,1 }
1095//      root:myGlobals:Attenuators:ng3att1 = {0.421, 0.394, 0.371, 0.349, 0.316, 0.293, 0.274, 0.245,0.220}
1096//      root:myGlobals:Attenuators:ng3att2 = {0.187, 0.164, 0.145, 0.130, 0.106, 0.0916, 0.0808, 0.0651,0.0531}
1097//      root:myGlobals:Attenuators:ng3att3 = {0.0777, 0.0636, 0.0534, 0.0446, 0.0330, 0.0262, 0.0217, 0.0157 ,0.0116}
1098//      root:myGlobals:Attenuators:ng3att4 = {0.0328, 0.0252, 0.0195, 0.0156, 0.0104, 7.68e-3, 5.98e-3, 3.91e-3,0.00262}
1099//      root:myGlobals:Attenuators:ng3att5 = {0.0139, 9.94e-3, 7.34e-3, 5.44e-3, 3.29e-3, 2.25e-3, 1.66e-3, 9.95e-4, 6.12e-4}
1100//      root:myGlobals:Attenuators:ng3att6 = {5.95e-3, 3.97e-3, 2.77e-3, 1.95e-3, 1.06e-3, 6.81e-4, 4.71e-4, 2.59e-4 , 1.45e-4}
1101//      root:myGlobals:Attenuators:ng3att7 = {1.07e-3, 6.24e-4, 3.90e-4, 2.44e-4, 1.14e-4, 6.55e-5, 4.10e-5, 1.64e-5 , 7.26e-6}
1102//      root:myGlobals:Attenuators:ng3att8 = {1.90e-4, 9.84e-5, 5.60e-5, 3.25e-5, 1.55e-5, 6.60e-6, 3.42e-6, 1.04e-6 , 3.48e-7}
1103//      root:myGlobals:Attenuators:ng3att9 = {3.61e-5, 1.74e-5, 9.90e-6, 6.45e-6, 2.35e-6, 6.35e-7, 2.86e-7, 6.61e-8 , 1.73e-8}
1104//      root:myGlobals:Attenuators:ng3att10 = {7.60e-6, 3.99e-6, 2.96e-6, 2.03e-6, 3.34e-7, 6.11e-8, 2.39e-8, 4.19e-9 , 8.60e-10}
1105
1106End
1107
1108// new calibration done June 2007, John Barker
1109Proc MakeNG7AttenTable()
1110
1111        NewDataFolder/O root:myGlobals:Attenuators
1112       
1113        Variable num=10         //10 needed for tables after June 2007
1114       
1115        Make/O/N=(num) root:myGlobals:Attenuators:ng7att0
1116        Make/O/N=(num) root:myGlobals:Attenuators:ng7att1
1117        Make/O/N=(num) root:myGlobals:Attenuators:ng7att2
1118        Make/O/N=(num) root:myGlobals:Attenuators:ng7att3
1119        Make/O/N=(num) root:myGlobals:Attenuators:ng7att4
1120        Make/O/N=(num) root:myGlobals:Attenuators:ng7att5
1121        Make/O/N=(num) root:myGlobals:Attenuators:ng7att6
1122        Make/O/N=(num) root:myGlobals:Attenuators:ng7att7
1123        Make/O/N=(num) root:myGlobals:Attenuators:ng7att8
1124        Make/O/N=(num) root:myGlobals:Attenuators:ng7att9
1125        Make/O/N=(num) root:myGlobals:Attenuators:ng7att10
1126       
1127        //NG7 wave has 10 elements, the transmission of att# at the wavelengths
1128        //lambda =4, 5,6,7,8,10,12,14,17,20
1129        // note that some of the higher attenuations and ALL of the 4 A and 20A data is interpolated
1130        // none of these values are expected to be used in reality since the flux would be too low in practice
1131        Make/O/N=(num) root:myGlobals:Attenuators:ng7lambda={4,5,6,7,8,10,12,14,17,20}
1132
1133// New calibration, June 2007, John Barker
1134        root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1,1}     
1135        root:myGlobals:Attenuators:ng7att1 = {0.448656,0.4192,0.3925,0.3661,0.3458,0.3098,0.2922,0.2738,0.2544,0.251352}
1136        root:myGlobals:Attenuators:ng7att2 = {0.217193,0.1898,0.1682,0.148,0.1321,0.1076,0.0957,0.08485,0.07479,0.0735965}
1137        root:myGlobals:Attenuators:ng7att3 = {0.098019,0.07877,0.06611,0.05429,0.04548,0.03318,0.02798,0.0234,0.02004,0.0202492}
1138        root:myGlobals:Attenuators:ng7att4 = {0.0426904,0.03302,0.02617,0.02026,0.0158,0.01052,0.008327,0.006665,0.005745,0.00524807}
1139        root:myGlobals:Attenuators:ng7att5 = {0.0194353,0.01398,0.01037,0.0075496,0.005542,0.003339,0.002505,0.001936,0.001765,0.00165959}
1140        root:myGlobals:Attenuators:ng7att6 = {0.00971666,0.005979,0.004136,0.002848,0.001946,0.001079,0.0007717,0.000588,0.000487337,0.000447713}
1141        root:myGlobals:Attenuators:ng7att7 = {0.00207332,0.001054,0.0006462,0.0003957,0.0002368,0.0001111,7.642e-05,4.83076e-05,3.99401e-05,3.54814e-05}
1142        root:myGlobals:Attenuators:ng7att8 = {0.000397173,0.0001911,0.0001044,5.844e-05,3.236e-05,1.471e-05,6.88523e-06,4.06541e-06,3.27333e-06,2.81838e-06}
1143        root:myGlobals:Attenuators:ng7att9 = {9.43625e-05,3.557e-05,1.833e-05,1.014e-05,6.153e-06,1.64816e-06,6.42353e-07,3.42132e-07,2.68269e-07,2.2182e-07}
1144        root:myGlobals:Attenuators:ng7att10 = {2.1607e-05,7.521e-06,2.91221e-06,1.45252e-06,7.93451e-07,1.92309e-07,5.99279e-08,2.87928e-08,2.19862e-08,1.7559e-08}
1145
1146// Pre-June 2007 calibration values - do not use these anymore 
1147////    root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1}
1148////    root:myGlobals:Attenuators:ng7att1 = {0.418, 0.393, 0.369, 0.347, 0.313, 0.291, 0.271, 0.244, 0.219 }
1149////    root:myGlobals:Attenuators:ng7att2 = {0.189, 0.167, 0.148, 0.132, 0.109, 0.0945, 0.0830, 0.0681, 0.0560}
1150////    root:myGlobals:Attenuators:ng7att3 = {0.0784, 0.0651, 0.0541, 0.0456, 0.0340, 0.0273, 0.0223, 0.0164 , 0.0121}
1151////    root:myGlobals:Attenuators:ng7att4 = {0.0328, 0.0256, 0.0200, 0.0159, 0.0107, 7.98e-3, 6.14e-3, 4.09e-3 , 0.00274}
1152////    root:myGlobals:Attenuators:ng7att5 = {0.0139, 0.0101, 7.43e-3, 5.58e-3, 3.42e-3, 2.36e-3, 1.70e-3, 1.03e-3 , 6.27e-4}
1153////    root:myGlobals:Attenuators:ng7att6 = {5.90e-3, 4.07e-3, 2.79e-3, 1.99e-3, 1.11e-3, 7.13e-4, 4.91e-4, 2.59e-4 , 1.42e-4}
1154////    root:myGlobals:Attenuators:ng7att7 = {1.04e-3, 6.37e-4, 3.85e-4, 2.46e-4, 1.16e-4, 6.86e-5, 4.10e-5, 1.64e-5 ,7.02e-6}
1155////    root:myGlobals:Attenuators:ng7att8 = {1.90e-4, 1.03e-4, 5.71e-5, 3.44e-5, 1.65e-5, 6.60e-6, 3.42e-6, 1.04e-6 , 3.48e-7}
1156////    root:myGlobals:Attenuators:ng7att9 = {3.58e-5, 1.87e-5, 1.05e-5, 7.00e-6, 2.35e-6, 6.35e-7, 2.86e-7, 6.61e-8 , 1.73e-8}
1157////    root:myGlobals:Attenuators:ng7att10 = {7.76e-6, 4.56e-6, 3.25e-6, 2.03e-6, 3.34e-7, 6.11e-8, 2.39e-8, 4.19e-9, 8.60e-10}
1158End
1159
1160//returns the transmission of the attenuator (at NG3) given the attenuator number
1161//which must be an integer(to select the wave) and given the wavelength.
1162//the wavelength may be any value between 4 and 20 (A), and is interpolated
1163//between calibrated wavelengths for a given attenuator
1164//
1165// Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0"
1166Function LookupAttenNG3(lambda,attenNo)
1167        Variable lambda, attenNo
1168       
1169        Variable trans
1170        String attStr="root:myGlobals:Attenuators:ng3att"+num2str(trunc(abs(attenNo)))
1171        String lamStr = "root:myGlobals:Attenuators:ng3lambda"
1172       
1173        if(attenNo == 0)
1174                return (1)              //no attenuation, return trans == 1
1175        endif
1176       
1177        if( (lambda < 4) || (lambda > 20 ) )
1178                Abort "Wavelength out of calibration range (4,20). You must manually enter the absolute parameters"
1179        Endif
1180       
1181        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
1182                Execute "MakeNG3AttenTable()"
1183        Endif
1184        //just in case creating the tables fails....
1185        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
1186                Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters"
1187        Endif
1188       
1189        //lookup the value by interpolating the wavelength
1190        //the attenuator must always be an integer
1191        Wave att = $attStr
1192        Wave lam = $lamstr
1193        trans = interp(lambda,lam,att)
1194       
1195//      Print "trans = ",trans
1196       
1197        return trans
1198End
1199
1200//returns the transmission of the attenuator (at NG7) given the attenuator number
1201//which must be an integer(to select the wave) and given the wavelength.
1202//the wavelength may be any value between 4 and 20 (A), and is interpolated
1203//between calibrated wavelengths for a given attenuator
1204//
1205// this set of tables is also used for NG5 (NG1) SANS instrument - as the attenuator has never been calibrated
1206//
1207// local function
1208//
1209// Mar 2010 - abs() added to attStr to account for ICE reporting -0.0001 as an attenuator position, which truncates to "-0"
1210Function LookupAttenNG7(lambda,attenNo)
1211        Variable lambda, attenNo
1212       
1213        Variable trans
1214        String attStr="root:myGlobals:Attenuators:ng7att"+num2str(trunc(abs(attenNo)))
1215        String lamStr = "root:myGlobals:Attenuators:ng7lambda"
1216       
1217        if(attenNo == 0)
1218                return (1)              //no attenuation, return trans == 1
1219        endif
1220       
1221        if( (lambda < 4) || (lambda > 20 ) )
1222                Abort "Wavelength out of calibration range (4,20). You must manually enter the absolute parameters"
1223        Endif
1224       
1225        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
1226                Execute "MakeNG7AttenTable()"
1227        Endif
1228        //just in case creating the tables fails....
1229        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
1230                Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters"
1231        Endif
1232       
1233        //lookup the value by interpolating the wavelength
1234        //the attenuator must always be an integer
1235        Wave att = $attStr
1236        Wave lam = $lamstr
1237        trans = interp(lambda,lam,att)
1238       
1239        //Print "trans = ",trans
1240       
1241        return trans
1242
1243End
1244
1245//returns the proper attenuation factor based on the instrument (NG3, NG5, or NG7)
1246//NG5 values are taken from the NG7 tables (there is very little difference in the
1247//values, and NG5 attenuators have not been calibrated (as of 8/01)
1248//
1249// filestr is passed from TextRead[3] = the default directory
1250// lam is passed from RealsRead[26]
1251// AttenNo is passed from ReaslRead[3]
1252//
1253// Attenuation factor as defined here is <= 1
1254//
1255// ORNL can pass ("",1,attenuationFactor) and have this function simply
1256// spit back the attenuationFactor (that was read into rw[3])
1257//
1258// called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf
1259//
1260Function AttenuationFactor(fileStr,lam,attenNo)
1261        String fileStr
1262        Variable lam,attenNo
1263       
1264        Variable attenFactor=1,loc
1265        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
1266       
1267        strswitch(instr)
1268                case "NG3":
1269                        attenFactor = LookupAttenNG3(lam,attenNo)
1270                        break
1271                case "NG5":
1272                        //using NG7 lookup Table
1273                        attenFactor = LookupAttenNG7(lam,attenNo)
1274                        break
1275                case "NG7":
1276                        attenFactor = LookupAttenNG7(lam,attenNo)
1277                        break
1278                default:                                                       
1279                        //return error?
1280                        attenFactor=1
1281        endswitch
1282//      print "instr, lambda, attenNo,attenFactor = ",instr,lam,attenNo,attenFactor
1283        return(attenFactor)
1284End
1285
1286//function called by the popups to get a file list of data that can be sorted
1287// this procedure simply removes the raw data files from the string - there
1288//can be lots of other junk present, but this is very fast...
1289//
1290// could also use the alternate procedure of keeping only file with the proper extension
1291//
1292// another possibility is to get a listing of the text files, but is unreliable on
1293// Windows, where the data file must be .txt (and possibly OSX)
1294//
1295// called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf
1296//
1297Function/S ReducedDataFileList(ctrlName)
1298        String ctrlName
1299
1300        String list="",newList="",item=""
1301        Variable num,ii
1302       
1303        //check for the path
1304        PathInfo catPathName
1305        if(V_Flag==0)
1306                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
1307                Return("")
1308        Endif
1309       
1310        list = IndexedFile(catpathName,-1,"????")
1311       
1312        list = RemoveFromList(ListMatch(list,"*.SA1*",";"), list, ";", 0)
1313        list = RemoveFromList(ListMatch(list,"*.SA2*",";"), list, ";", 0)
1314        list = RemoveFromList(ListMatch(list,"*.SA3*",";"), list, ";", 0)
1315        list = RemoveFromList(ListMatch(list,".*",";"), list, ";", 0)
1316        list = RemoveFromList(ListMatch(list,"*.pxp",";"), list, ";", 0)
1317        list = RemoveFromList(ListMatch(list,"*.DIV",";"), list, ";", 0)
1318        list = RemoveFromList(ListMatch(list,"*.GSP",";"), list, ";", 0)
1319        list = RemoveFromList(ListMatch(list,"*.MASK",";"), list, ";", 0)
1320
1321        //remove VAX version numbers
1322        list = RemoveVersNumsFromList(List)
1323        //sort
1324        newList = SortList(List,";",0)
1325
1326        return newlist
1327End
1328
1329// returns a list of raw data files in the catPathName directory on disk
1330// - list is SEMICOLON-delimited
1331//
1332// does it the "cheap" way, simply finding the ".SAn" in the file name
1333// = does not check for proper byte length.
1334//
1335// called by PatchFiles.ipf, Tile_2D.ipf
1336//
1337Function/S GetRawDataFileList()
1338       
1339        //make sure that path exists
1340        PathInfo catPathName
1341        if (V_flag == 0)
1342                Abort "Folder path does not exist - use Pick Path button on Main Panel"
1343        Endif
1344       
1345        String list=IndexedFile(catPathName,-1,"????")
1346        String newList="",item=""
1347        Variable num=ItemsInList(list,";"),ii
1348        for(ii=0;ii<num;ii+=1)
1349                item = StringFromList(ii, list  ,";")
1350                if( stringmatch(item,"*.sa1*") )
1351                        newlist += item + ";"
1352                endif
1353                if( stringmatch(item,"*.sa2*") )
1354                        newlist += item + ";"
1355                endif
1356                if( stringmatch(item,"*.sa3*") )
1357                        newlist += item + ";"
1358                endif
1359                //print "ii=",ii
1360        endfor
1361        newList = SortList(newList,";",0)
1362        return(newList)
1363End
1364
1365// Return the filename that represents the previous or next file.
1366// Input is current filename and increment.
1367// Increment should be -1 or 1
1368// -1 => previous file
1369// 1 => next file
1370Function/S GetPrevNextRawFile(curfilename, prevnext)
1371        String curfilename
1372        Variable prevnext
1373
1374        String filename
1375       
1376        //get the run number
1377        Variable num = GetRunNumFromFile(curfilename)
1378               
1379        //find the next specified file by number
1380        fileName = FindFileFromRunNumber(num+prevnext)
1381
1382        if(cmpstr(fileName,"")==0)
1383                //null return, do nothing
1384                fileName = FindFileFromRunNumber(num)
1385        Endif
1386
1387//      print "in FU "+filename
1388
1389        Return filename
1390End
1391
1392
Note: See TracBrowser for help on using the repository browser.