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

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

(1) changes to ProDiv? to get the linear scaling correct with the new panel.

(2) bug fix in NCNR_Utils in file open dialog

(3) assorted changes to SASCALC and Simulation procedures to allow 1D simulation of data collection. 2D is now hidden and will be brought back later, as needed.

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