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

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

(1) fix in ProtocolAsPanel? that correctly calculates Kappa for data taken with the Cerca detectors. In the Kappa calculation, the data is manually scaled, bypassing the normal "ADD" step where the 4x detector data is correctly renormalized. Added a flag to divide by 4 if ILL detector type found.

(2) lots of bits to try to accomodate 2D resolution smearing. Changes to the QxQy? output to have everything needed: Qz, sigX, sigY, and shadowing. So presumably, all of the information is in the reduced data, where it should be.

  • added a 2D resolution calculation based on David Mildner's notes.
  • added 2D quadrature calculation for smearing, and new structure definitions

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