source: sans/SANSReduction/branches/kline_29MAR07/Put in User Procedures/SANS_Reduction_v5.00/NCNR_Utils.ipf @ 82

Last change on this file since 82 was 82, checked in by srkline, 15 years ago
  • Documentation of what parameters are passed to some "Generic" functions. There are only a few of these, like AttenuationFactor?, and they are passed a set parameter list that is always taken from the R/T/I waves that are loaded with the data. If filled properly from the loader, all will work, or the accessor can be fudged to work.
  • A new initialization global was added for beamstop XTol for isTransFile()
  • A new initialization global was added for sample aperture offset (apOff)
File size: 35.2 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=5.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        Variable/G root:myGlobals:PixelResNG3_ILL = 1.0         //pixel resolution in cm
27        Variable/G root:myGlobals:PixelResNG5_ILL = 1.0
28        Variable/G root:myGlobals:PixelResNG7_ILL = 1.0
29        Variable/G root:myGlobals:PixelResNG3_ORNL = 0.5
30        Variable/G root:myGlobals:PixelResNG5_ORNL = 0.5
31        Variable/G root:myGlobals:PixelResNG7_ORNL = 0.5
32        Variable/G root:myGlobals:PixelResDefault = 0.5
33       
34        Variable/G root:myGlobals:DeadtimeNG3_ILL = 3.0e-6              //deadtime in seconds
35        Variable/G root:myGlobals:DeadtimeNG5_ILL = 3.0e-6
36        Variable/G root:myGlobals:DeadtimeNG7_ILL = 3.0e-6
37        Variable/G root:myGlobals:DeadtimeNG3_ORNL = 3.4e-6
38        Variable/G root:myGlobals:DeadtimeNG5_ORNL = 0.6e-6             //as of 9 MAY 2002
39        Variable/G root:myGlobals:DeadtimeNG7_ORNL = 3.4e-6
40        Variable/G root:myGlobals:DeadtimeDefault = 3.4e-6
41       
42        //new 11APR07
43        Variable/G root:myGlobals:BeamstopXTol = -5                     // (cm) is BS Xpos is -5 cm or less, it's a trans measurement
44        // sample aperture offset is NOT stored in the VAX header, but it should be
45        // - when it is, remove the global and write an accessor AND make a place for
46        // it in the RealsRead
47        Variable/G root:myGlobals:apOff = 5.0                           // (cm) distance from sample aperture to sample position
48
49End
50
51
52//**********************
53// Resolution calculation - used by the averaging routines
54// to calculate the resolution function at each q-value
55// - the return value is not used
56//
57// equivalent to John's routine on the VAX Q_SIGMA_AVE.FOR
58// Incorporates eqn. 3-15 from J. Appl. Cryst. (1995) v. 28 p105-114
59//
60// - 21 MAR 07 uses projected BS diameter on the detector
61// - APR 07 still need to add resolution with lenses. currently there is no flag in the
62//          raw data header to indicate the presence of lenses.
63//
64// - called by CircSectAvg.ipf and RectAnnulAvg.ipf
65//
66// passed values are read from RealsRead
67// except DDet and apOff, which are set from globals before passing
68//
69Function/S getResolution(inQ,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,SigmaQ,QBar,fSubS)
70        Variable inQ, lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r
71        Variable &fSubS, &QBar, &SigmaQ         //these are the output quantities at the input Q value
72       
73        //lots of calculation variables
74        Variable a2, q_small, lp, v_lambda, v_b, v_d, vz, yg, v_g
75        Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r
76
77        //Constants
78        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
79        Variable g = 981.0                              //gravity acceleration [cm/s^2]
80
81        String results
82        results ="Failure"
83
84        S1 *= 0.5*0.1                   //convert to radius and [cm]
85        S2 *= 0.5*0.1
86
87        L1 *= 100.0                     // [cm]
88        L1 -= apOff                             //correct the distance
89
90        L2 *= 100.0
91        L2 += apOff
92        del_r *= 0.1                            //width of annulus, convert mm to [cm]
93       
94        BS *= 0.5*0.1                   //nominal BS diameter passed in, convert to radius and [cm]
95        // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture
96        Variable LB
97        LB = 20.1 + 1.61*BS                     //distance in cm from beamstop to anode plane (empirical)
98        BS = bs + bs*lb/(l2-lb)         //adjusted diameter of shadow from parallax
99       
100        //Start resolution calculation
101        a2 = S1*L2/L1 + S2*(L1+L2)/L1
102        q_small = 2.0*Pi*(BS-a2)*(1.0-lambdaWidth)/(lambda*L2)
103        lp = 1.0/( 1.0/L1 + 1.0/L2)
104
105        v_lambda = lambdaWidth^2/6.0
106        v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2
107        v_d = (DDet/2.3548)^2 + del_r^2/12.0
108        vz = vz_1 / lambda
109        yg = 0.5*g*L2*(L1+L2)/vz^2
110        v_g = 2.0*yg^2*v_lambda
111
112        r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) ))
113        delta = 0.5*(BS - r0)^2/v_d
114
115        if (r0 < BS)
116                inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta))
117        else
118                inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta))
119        endif
120
121        fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) )
122        if (fSubS <= 0.0)
123                fSubS = 1.e-10
124        endif
125        fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi))
126        fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d
127
128        rmd = fr*r0
129        v_r1 = v_b + fv*v_d +v_g
130
131        rm = rmd + 0.5*v_r1/rmd
132        v_r = v_r1 - 0.5*(v_r1/rmd)^2
133        if (v_r < 0.0)
134                v_r = 0.0
135        endif
136        QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2))
137        SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda)
138
139        results = "success"
140        Return results
141End
142
143
144//Utility function that returns the detector resolution (in cm)
145//Global values are set in the Initialize procedure
146//
147//
148// - called by CircSectAvg.ipf, RectAnnulAvg.ipf, and ProtocolAsPanel.ipf
149//
150// fileStr is passed as TextRead[3]
151// detStr is passed as TextRead[9]
152//
153Function DetectorPixelResolution(fileStr,detStr)
154        String fileStr,detStr
155       
156        Variable DDet
157        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
158       
159        NVAR PixelResNG3_ILL = root:myGlobals:PixelResNG3_ILL           //pixel resolution in cm
160        NVAR PixelResNG5_ILL = root:myGlobals:PixelResNG5_ILL
161        NVAR PixelResNG7_ILL = root:myGlobals:PixelResNG7_ILL
162        NVAR PixelResNG3_ORNL = root:myGlobals:PixelResNG3_ORNL
163        NVAR PixelResNG5_ORNL = root:myGlobals:PixelResNG5_ORNL
164        NVAR PixelResNG7_ORNL = root:myGlobals:PixelResNG7_ORNL
165        NVAR PixelResDefault = root:myGlobals:PixelResDefault
166       
167        strswitch(instr)
168                case "NG3":
169                        if(cmpstr(detStr, "ILL   ") == 0 )
170                                DDet= PixelResNG3_ILL
171                        else
172                                DDet = PixelResNG3_ORNL //detector is ordella-type
173                        endif
174                        break
175                case "NG5":
176                        if(cmpstr(detStr, "ILL   ") == 0 )
177                                DDet= PixelResNG5_ILL
178                        else
179                                DDet = PixelResNG5_ORNL //detector is ordella-type
180                        endif
181                        break
182                case "NG7":
183                        if(cmpstr(detStr, "ILL   ") == 0 )
184                                DDet= PixelResNG7_ILL
185                        else
186                                DDet = PixelResNG7_ORNL //detector is ordella-type
187                        endif
188                        break
189                default:                                                       
190                        //return error?
191                        DDet = PixelResDefault  //0.5 cm, typical for new ORNL detectors
192        endswitch
193       
194        return(DDet)
195End
196
197//Utility function that returns the detector deadtime (in seconds)
198//Global values are set in the Initialize procedure
199//
200// - called by WorkFileUtils.ipf
201//
202// fileStr is passed as TextRead[3]
203// detStr is passed as TextRead[9]
204//
205Function DetectorDeadtime(fileStr,detStr)
206        String fileStr,detStr
207       
208        Variable deadtime
209        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
210       
211        NVAR DeadtimeNG3_ILL = root:myGlobals:DeadtimeNG3_ILL           //pixel resolution in cm
212        NVAR DeadtimeNG5_ILL = root:myGlobals:DeadtimeNG5_ILL
213        NVAR DeadtimeNG7_ILL = root:myGlobals:DeadtimeNG7_ILL
214        NVAR DeadtimeNG3_ORNL = root:myGlobals:DeadtimeNG3_ORNL
215        NVAR DeadtimeNG5_ORNL = root:myGlobals:DeadtimeNG5_ORNL
216        NVAR DeadtimeNG7_ORNL = root:myGlobals:DeadtimeNG7_ORNL
217        NVAR DeadtimeDefault = root:myGlobals:DeadtimeDefault
218       
219        strswitch(instr)
220                case "NG3":
221                        if(cmpstr(detStr, "ILL   ") == 0 )
222                                deadtime= DeadtimeNG3_ILL
223                        else
224                                deadtime = DeadtimeNG3_ORNL     //detector is ordella-type
225                        endif
226                        break
227                case "NG5":
228                        if(cmpstr(detStr, "ILL   ") == 0 )
229                                deadtime= DeadtimeNG5_ILL
230                        else
231                                deadtime = DeadtimeNG5_ORNL     //detector is ordella-type
232                        endif
233                        break
234                case "NG7":
235                        if(cmpstr(detStr, "ILL   ") == 0 )
236                                deadtime= DeadtimeNG7_ILL
237                        else
238                                deadtime = DeadtimeNG7_ORNL     //detector is ordella-type
239                        endif
240                        break
241                default:                                                       
242                        //return error?
243                        deadtime = DeadtimeDefault      //1e-6 seconds, typical for new ORNL detectors
244        endswitch
245       
246        return(deadtime)
247End
248
249
250/////VAX filename/Run number parsing utilities
251//
252// a collection of uilities for processing vax filenames
253//and processing lists (especially for display in popup menus)
254//
255//required to correctly account for VAX supplied version numbers, which
256//may or may not be removed by the ftp utility
257//
258// - parses lists of run numbers into real filenames
259// - selects proper detector constants
260//
261//**************************
262//
263//given a filename of a SANS data filename of the form
264//TTTTTnnn.SAn_TTT_Txxx
265//returns the run number "nnn" as a number
266//returns -1 as an invalid file number
267//
268// called by several ipfs
269//
270//
271Function GetRunNumFromFile(item)
272        String item
273        Variable invalid = -1   //negative numbers are invalid
274        Variable num=-1
275       
276        //find the "dot"
277        String runStr=""
278        Variable pos = strsearch(item,".",0)
279        if(pos == -1)
280                //"dot" not found
281                return (invalid)
282        else
283                //found, get the three characters preceeding it
284                if (pos <=2)
285                        //not enough characters
286                        return (invalid)
287                else
288                        runStr = item[pos-3,pos-1]
289                        //convert to a number
290                        num = str2num(runStr)
291                        //if valid, return it
292                        if (num == NaN)
293                                //3 characters were not a number
294                                return (invalid)
295                        else
296                                //run was OK
297                                return (num)
298                        Endif
299                Endif
300        Endif
301End
302
303//given a filename of a SANS data filename of the form
304//TTTTTnnn.SAn_TTT_Txxx
305//returns the run number "nnn" as a STRING of THREE characters
306//returns "ABC" as an invalid file number
307//
308// local function to aid in locating files by run number
309//
310Function/S GetRunNumStrFromFile(item)
311        String item
312        String invalid = "ABC"  //"ABC" is not a valid run number, since it's text
313        Variable num=-1
314       
315        //find the "dot"
316        String runStr=""
317        Variable pos = strsearch(item,".",0)
318        if(pos == -1)
319                //"dot" not found
320                return (invalid)
321        else
322                //found, get the three characters preceeding it
323                if (pos <=2)
324                        //not enough characters
325                        return (invalid)
326                else
327                        runStr = item[pos-3,pos-1]
328                        return (runStr)
329                Endif
330        Endif
331End
332
333//returns a string containing the full path to the file containing the
334//run number "num". The null string is returned if no valid file can be found
335//the path "catPathName" used and is hard-wired, will abort if this path does not exist
336//the file returned will be a RAW SANS data file, other types of files are
337//filtered out.
338//
339// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
340//
341Function/S FindFileFromRunNumber(num)
342        Variable num
343       
344        String fullName="",partialName="",item=""
345        //get list of raw data files in folder that match "num" (add leading zeros)
346        if( (num>999) || (num<=0) )
347                //Print "error in  FindFileFromRunNumber(num), file number too large or too small"
348                Return ("")
349        Endif
350        //make a three character string of the run number
351        String numStr=""
352        if(num<10)
353                numStr = "00"+num2str(num)
354        else
355                if(num<100)
356                        numStr = "0"+num2str(num)
357                else
358                        numStr = num2str(num)
359                Endif
360        Endif
361        //Print "numstr = ",numstr
362       
363        //make sure that path exists
364        PathInfo catPathName
365        String path = S_path
366        if (V_flag == 0)
367                Abort "folder path does not exist - use Pick Path button"
368        Endif
369        String list="",newList="",testStr=""
370       
371        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
372        //find (the) one with the number in the run # location in the name
373        Variable numItems,ii,runFound,isRAW
374        numItems = ItemsInList(list,";")                //get the new number of items in the list
375        ii=0
376        do
377                //parse through the list in this order:
378                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
379                // 2 - exclude by isRaw? (to minimize disk access)
380                item = StringFromList(ii, list  ,";" )
381                if(strlen(item) != 0)
382                        //find the run number, if it exists as a three character string
383                        testStr = GetRunNumStrFromFile(item)
384                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
385                        if(runFound == 0)
386                                //the run Number was found
387                                //build valid filename
388                                partialName = FindValidFileName(item)
389                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
390                                        fullName = path + partialName
391                                        //check if RAW, if so,this must be the file!
392                                        isRAW = CheckIfRawData(fullName)
393                                        if(isRaw)
394                                                //stop here
395                                                return(fullname)
396                                        Endif
397                                Endif
398                        Endif
399                Endif
400                ii+=1
401        while(ii<numItems)              //process all items in list
402        Return ("")     //null return if file not found in list
403End
404
405//function to test a binary file to see if it is a RAW binary SANS file
406//first checks the total bytes in the file (which for raw data is 33316 bytes)
407//**note that the "DIV" file will also show up as a raw file by the run field
408//should be listed in CAT/SHORT and in patch windows
409//
410//Function then checks the file fname (full path:file) for "RAW" run.type field
411//if not found, the data is not raw data and zero is returned
412//
413// called by many procedures (both external and local)
414//
415Function CheckIfRawData(fname)
416        String fname
417       
418        Variable refnum,totalBytes
419        String testStr=""
420       
421        Open/R/T="????TEXT" refNum as fname
422        //get the total number of bytes in the file
423        FStatus refNum
424        totalBytes = V_logEOF
425        //Print totalBytes
426        FSetPos refNum,75
427        FReadLine/N=3 refNum,testStr
428        Close refNum
429       
430        if(totalBytes == 33316 && cmpstr(testStr,"RAW")==0)
431                //true, is raw data file
432                Return(1)
433        else
434                //some other file
435                Return(0)
436        Endif
437End
438
439//function to check the header of a raw data file (full path specified by fname)
440//checks the field of the x-position of the beamstop during data collection
441//if the x-position is more negative (farther to the left) than xTol(input)
442//the the beamstop is "out" and the file is a transmission run and not a scattering run
443//xtol typically set at -5 (cm) - trans runs have bs(x) at -10 to -15 cm
444// function returns 1 if beamstop is out, 0 if beamstop is in
445//
446// tolerance is set as a global value "root:myGlobals:BeamstopXTol"
447//
448// called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf
449//
450Function isTransFile(fName)
451        String fname
452       
453        Variable refnum,xpos
454        NVAR xTol = root:myGlobals:BeamstopXTol
455       
456        //pos = 369, read one real value
457       
458        SetDataFolder root:
459        String GBLoadStr="GBLoadWave/O/N=tempGBwave/T={2,2}/J=2/W=1/Q"
460        String strToExecute=""
461        // 1 R*4 value
462        strToExecute = GBLoadStr + "/S=368/U=1" + "\"" + fname + "\""
463        Execute strToExecute
464        Wave w=$"root:tempGBWave0"
465        xPos = w[0]
466        KillWaves/Z w
467        //Print "xPos = ",xpos
468       
469        if(xpos<=xTol)
470                //xpos is farther left (more negative) than xtol (currently -5 cm)
471                Return(1)
472        else
473                //some other file
474                Return(0)
475        Endif
476End
477
478
479//function to remove all spaces from names when searching for filenames
480//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
481//but the text field in the header WILL, if less than 3 characters were used for the
482//user's initials, and can have leading spaces if prefix was less than 5 characters
483//
484//returns a string identical to the original string, except with the interior spaces removed
485//
486// local function for file name manipulation
487//
488Function/S RemoveAllSpaces(str)
489        String str
490       
491        String tempstr = str
492        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
493        ii=0
494        do
495                len = strlen(tempStr)
496                spc = strsearch(tempStr," ",0)          //is the last character a space?
497                if (spc == -1)
498                        break           //no more spaces found, get out
499                endif
500                str = tempstr
501                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
502        While(1)        //should never be more than 2 or 3
503       
504        If(strlen(tempStr) < 1)
505                tempStr = ""            //be sure to return a null string if problem found
506        Endif
507       
508        //Print strlen(tempstr)
509       
510        Return(tempStr)
511               
512End
513
514
515//Function attempts to find valid filename from partial name by checking for
516// the existence of the file on disk.
517// - checks as is
518// - adds ";vers" for possible VAX files
519// - strips spaces
520// - permutations of upper/lowercase
521//
522// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
523// since from marquee, the filename field (textread[0]) must be used, and can be a mix of
524// upper/lowercase letters, while the filename on the server (should) be all caps
525// now makes repeated calls to ValidFileString()
526//
527// returns a valid filename (No path prepended) or a null string
528//
529// called by any functions, both external and local
530//
531Function/S FindValidFilename(partialName)
532        String PartialName
533       
534        String retStr=""
535       
536        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
537        retStr = ValidFileString(partialName)
538        if(cmpstr(retStr,"") !=0)
539                //non-null return
540                return(retStr)
541        Endif
542       
543        //if the partial name is derived from the file header, there can be spaces at the beginning
544        //or in the middle of the filename - depending on the prefix and initials used
545        //
546        //remove any leading spaces from the name before starting
547        partialName = RemoveAllSpaces(partialName)
548       
549        //try name with no spaces
550        retStr = ValidFileString(partialName)
551        if(cmpstr(retStr,"") !=0)
552                //non-null return
553                return(retStr)
554        Endif
555       
556        //try all UPPERCASE
557        partialName = UpperStr(partialName)
558        retStr = ValidFileString(partialName)
559        if(cmpstr(retStr,"") !=0)
560                //non-null return
561                return(retStr)
562        Endif
563       
564        //try all lowercase (ret null if failure)
565        partialName = LowerStr(partialName)
566        retStr = ValidFileString(partialName)
567        if(cmpstr(retStr,"") !=0)
568                //non-null return
569                return(retStr)
570        else
571                return(retStr)
572        Endif
573End
574
575// Function checks for the existence of a file
576// partialName;vers (to account for VAX filenaming conventions)
577// The partial name is tried first with no version number
578//
579// *** the PATH is hard-wired to catPathName (which is assumed to exist)
580// version numers up to ;10 are tried
581// only the "name;vers" is returned if successful. The path is not prepended
582//
583// local function
584//
585Function/S ValidFileString(partialName)
586        String partialName
587       
588        String tempName = "",msg=""
589        Variable ii,refnum
590       
591        ii=0
592        do
593                if(ii==0)
594                        //first pass, try the partialName
595                        tempName = partialName
596                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
597                        if(V_flag == 0)
598                                //file exists
599                                Close refnum            //YES needed,
600                                break
601                        endif
602                else
603                        tempName = partialName + ";" + num2str(ii)
604                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
605                        if(V_flag == 0)
606                                //file exists
607                                Close refnum
608                                break
609                        endif
610                Endif
611                ii+=1
612                //print "ii=",ii
613        while(ii<11)
614        //go get the selected bits of information, using tempName, which exists
615        if(ii>=11)
616                //msg = partialName + " not found. is version number > 11?"
617                //DoAlert 0, msg
618                //PathInfo catPathName
619                //Print S_Path
620                Return ("")             //use null string as error condition
621        Endif
622       
623        Return (tempName)
624End
625
626//returns a string containing filename (WITHOUT the ;vers)
627//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
628//with the folders separated by colons
629//
630// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
631//
632Function/S GetFileNameFromPathNoSemi(fullPath)
633        String fullPath
634       
635        Variable offset1,offset2
636        String filename=""
637        //String PartialPath
638        offset1 = 0
639        do
640                offset2 = StrSearch(fullPath, ":", offset1)
641                if (offset2 == -1)                              // no more colons ?
642                        fileName = FullPath[offset1,strlen(FullPath) ]
643                        //PartialPath = FullPath[0, offset1-1]
644                        break
645                endif
646                offset1 = offset2+1
647        while (1)
648       
649        //remove version number from name, if it's there - format should be: filename;N
650        filename =  StringFromList(0,filename,";")              //returns null if error
651       
652        Return filename
653End
654
655//returns a string containing filename (INCLUDING the ;vers)
656//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
657//with the folders separated by colons
658//
659// local, currently unused
660//
661Function/S GetFileNameFromPathKeepSemi(fullPath)
662        String fullPath
663       
664        Variable offset1,offset2
665        String filename
666        //String PartialPath
667        offset1 = 0
668        do
669                offset2 = StrSearch(fullPath, ":", offset1)
670                if (offset2 == -1)                              // no more colons ?
671                        fileName = FullPath[offset1,strlen(FullPath) ]
672                        //PartialPath = FullPath[0, offset1-1]
673                        break
674                endif
675                offset1 = offset2+1
676        while (1)
677       
678        //keep version number from name, if it's there - format should be: filename;N
679       
680        Return filename
681End
682
683//given the full path and filename (fullPath), strips the data path
684//(Mac-style, separated by colons) and returns this path
685//this partial path is the same string that would be returned from PathInfo, for example
686//
687// - allows the user to save to a different path than catPathName
688//
689// called by WriteQIS.ipf
690//
691Function/S GetPathStrFromfullName(fullPath)
692        String fullPath
693       
694        Variable offset1,offset2
695        //String filename
696        String PartialPath
697        offset1 = 0
698        do
699                offset2 = StrSearch(fullPath, ":", offset1)
700                if (offset2 == -1)                              // no more colons ?
701                        //fileName = FullPath[offset1,strlen(FullPath) ]
702                        PartialPath = FullPath[0, offset1-1]
703                        break
704                endif
705                offset1 = offset2+1
706        while (1)
707       
708        Return PartialPath
709End
710
711//given the VAX filename, pull off the first 8 characters to make a valid
712//file string that can be used for naming averaged 1-d files
713//
714// called by ProtocolAsPanel.ipf and Tile_2D.ipf
715//
716Function/S GetNameFromHeader(fullName)
717        String fullName
718        String temp, newName = ""
719        Variable spc,ii=0
720       
721        //filename is 20 characters NNNNNxxx.SAn_NNN_NNN
722        //want the first 8 characters, NNNNNxxx, then strip off any spaces at the beginning
723        //NNNNN was entered as less than 5 characters
724        //returns a null string if no name can be found
725        do
726                temp = fullname[ii,7]           //characters ii,7 of the name
727                spc = strsearch(temp," ",0)
728                if (spc == -1)
729                        break           //no more spaces found
730                endif
731                ii+=1
732        While(ii<8)
733       
734        If(strlen(temp) < 1)
735                newName = ""            //be sure to return a null string if problem found
736        else
737                newName = temp
738        Endif
739       
740        Return(newName)
741End
742
743//list (input) is a list, typically returned from IndexedFile()
744//which is semicolon-delimited, and may contain filenames from the VAX
745//that contain version numbers, where the version number appears as a separate list item
746//(and also as a non-existent file)
747//these numbers must be purged from the list, especially for display in a popup
748//or list processing of filenames
749//the function returns the list, cleaned of version numbers (up to 11)
750//raw data files will typically never have a version number other than 1.
751//
752// if there are no version numbers in the list, the input list is returned
753//
754// called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf
755//
756Function/S RemoveVersNumsFromList(list)
757        String list
758       
759        //get rid of version numbers first (up to 11)
760        Variable ii,num
761        String item
762        num = ItemsInList(list,";")
763        ii=1
764        do
765                item = num2str(ii)
766                list = RemoveFromList(item, list ,";" )
767                ii+=1
768        while(ii<12)
769       
770        return (list)
771End
772
773//input is a list of run numbers, and output is a list of filenames (not the full path)
774//*** input list must be COMMA delimited***
775//output is equivalent to selecting from the CAT table
776//if some or all of the list items are valid filenames, keep them...
777//if an error is encountered, notify of the offending element and return a null list
778//
779//output is COMMA delimited
780//
781// this routine is expecting that the "ask", "none" special cases are handled elsewhere
782//and not passed here
783//
784// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
785//
786Function/S ParseRunNumberList(list)
787        String list
788       
789        String newList="",item="",tempStr=""
790        Variable num,ii,runNum
791       
792        //expand number ranges, if any
793        list = ExpandNumRanges(list)
794       
795        num=itemsinlist(list,",")
796       
797        for(ii=0;ii<num;ii+=1)
798                //get the item
799                item = StringFromList(ii,list,",")
800                //is it already a valid filename?
801                tempStr=FindValidFilename(item) //returns filename if good, null if error
802                if(strlen(tempstr)!=0)
803                        //valid name, add to list
804                        //Print "it's a file"
805                        newList += tempStr + ","
806                else
807                        //not a valid name
808                        //is it a number?
809                        runNum=str2num(item)
810                        //print runnum
811                        if(numtype(runNum) != 0)
812                                //not a number -  maybe an error                       
813                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
814                                return("")
815                        else
816                                //a run number or an error
817                                tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) )
818                                if(strlen(tempstr)==0)
819                                        //file not found, error
820                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
821                                        return("")
822                                else
823                                        newList += tempStr + ","
824                                endif
825                        endif
826                endif
827        endfor          //loop over all items in list
828       
829        return(newList)
830End
831
832//takes a comma delimited list that MAY contain number range, and
833//expands any range of run numbers into a comma-delimited list...
834//and returns the new list - if not a range, return unchanged
835//
836// local function
837//
838Function/S ExpandNumRanges(list)
839        String list
840       
841        String newList="",dash="-",item,str
842        Variable num,ii,hasDash
843       
844        num=itemsinlist(list,",")
845//      print num
846        for(ii=0;ii<num;ii+=1)
847                //get the item
848                item = StringFromList(ii,list,",")
849                //does it contain a dash?
850                hasDash = strsearch(item,dash,0)                //-1 if no dash found
851                if(hasDash == -1)
852                        //not a range, keep it in the list
853                        newList += item + ","
854                else
855                        //has a dash (so it's a range), expand (or add null)
856                        newList += ListFromDash(item)           
857                endif
858        endfor
859       
860        return newList
861End
862
863//be sure to add a trailing comma to the return string...
864//
865// local function
866//
867Function/S ListFromDash(item)
868        String item
869       
870        String numList="",loStr="",hiStr=""
871        Variable lo,hi,ii
872       
873        loStr=StringFromList(0,item,"-")        //treat the range as a list
874        hiStr=StringFromList(1,item,"-")
875        lo=str2num(loStr)
876        hi=str2num(hiStr)
877        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
878                numList=""
879                return numList
880        endif
881        for(ii=lo;ii<=hi;ii+=1)
882                numList += num2str(ii) + ","
883        endfor
884       
885        Return numList
886End
887
888
889////////Transmission
890//******************
891//lookup tables for attenuator transmissions
892//NG3 and NG7 attenuators are physically different, so the transmissions are slightly different
893//NG1 - (8m SANS) is not supported
894//
895// local function
896//
897Proc MakeNG3AttenTable()
898
899        NewDataFolder/O root:myGlobals:Attenuators
900        //do explicitly to avoid data folder problems, redundant, but it must work without fail
901        Make/O/N=9 root:myGlobals:Attenuators:ng3att0
902        Make/O/N=9 root:myGlobals:Attenuators:ng3att1
903        Make/O/N=9 root:myGlobals:Attenuators:ng3att2
904        Make/O/N=9 root:myGlobals:Attenuators:ng3att3
905        Make/O/N=9 root:myGlobals:Attenuators:ng3att4
906        Make/O/N=9 root:myGlobals:Attenuators:ng3att5
907        Make/O/N=9 root:myGlobals:Attenuators:ng3att6
908        Make/O/N=9 root:myGlobals:Attenuators:ng3att7
909        Make/O/N=9 root:myGlobals:Attenuators:ng3att8
910        Make/O/N=9 root:myGlobals:Attenuators:ng3att9
911        Make/O/N=9 root:myGlobals:Attenuators:ng3att10
912       
913        //each wave has 8 elements, the transmission of att# at the wavelengths
914        //lambda = 5,6,7,8,10,12,14,17
915        Make/O/N=9 root:myGlobals:Attenuators:ng3lambda={5,6,7,8,10,12,14,17,20}
916        root:myGlobals:Attenuators:ng3att0 = {1, 1, 1, 1, 1, 1, 1, 1,1 }
917        root:myGlobals:Attenuators:ng3att1 = {0.421, 0.394, 0.371, 0.349, 0.316, 0.293, 0.274, 0.245,0.220}
918        root:myGlobals:Attenuators:ng3att2 = {0.187, 0.164, 0.145, 0.130, 0.106, 0.0916, 0.0808, 0.0651,0.0531}
919        root:myGlobals:Attenuators:ng3att3 = {0.0777, 0.0636, 0.0534, 0.0446, 0.0330, 0.0262, 0.0217, 0.0157 ,0.0116}
920        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}
921        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}
922        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}
923        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}
924        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}
925        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}
926        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}
927
928End
929
930Proc MakeNG7AttenTable()
931
932        NewDataFolder/O root:myGlobals:Attenuators
933       
934        Make/O/N=9 root:myGlobals:Attenuators:ng7att0
935        Make/O/N=9 root:myGlobals:Attenuators:ng7att1
936        Make/O/N=9 root:myGlobals:Attenuators:ng7att2
937        Make/O/N=9 root:myGlobals:Attenuators:ng7att3
938        Make/O/N=9 root:myGlobals:Attenuators:ng7att4
939        Make/O/N=9 root:myGlobals:Attenuators:ng7att5
940        Make/O/N=9 root:myGlobals:Attenuators:ng7att6
941        Make/O/N=9 root:myGlobals:Attenuators:ng7att7
942        Make/O/N=9 root:myGlobals:Attenuators:ng7att8
943        Make/O/N=9 root:myGlobals:Attenuators:ng7att9
944        Make/O/N=9 root:myGlobals:Attenuators:ng7att10
945       
946        //each wave has 8 elements, the transmission of att# at the wavelengths
947        //lambda = 5,6,7,8,10,12,14,17
948        Make/O/N=9 root:myGlobals:Attenuators:ng7lambda={5,6,7,8,10,12,14,17,20}
949        root:myGlobals:Attenuators:ng7att0 = {1, 1, 1, 1, 1, 1, 1, 1 ,1}
950        root:myGlobals:Attenuators:ng7att1 = {0.418, 0.393, 0.369, 0.347, 0.313, 0.291, 0.271, 0.244, 0.219 }
951        root:myGlobals:Attenuators:ng7att2 = {0.189, 0.167, 0.148, 0.132, 0.109, 0.0945, 0.0830, 0.0681, 0.0560}
952        root:myGlobals:Attenuators:ng7att3 = {0.0784, 0.0651, 0.0541, 0.0456, 0.0340, 0.0273, 0.0223, 0.0164 , 0.0121}
953        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}
954        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}
955        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}
956        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}
957        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}
958        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}
959        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}
960       
961End
962
963//returns the transmission of the attenuator (at NG3) given the attenuator number
964//which must be an integer(to select the wave) and given the wavelength.
965//the wavelength may be any value between 5 and 20 (A), and is interpolated
966//between calibrated wavelengths for a given attenuator
967//
968// local function
969//
970Function LookupAttenNG3(lambda,attenNo)
971        Variable lambda, attenNo
972       
973        Variable trans
974        String attStr="root:myGlobals:Attenuators:ng3att"+num2str(trunc(attenNo))
975        String lamStr = "root:myGlobals:Attenuators:ng3lambda"
976       
977        if(attenNo == 0)
978                return (1)              //no attenuation, return trans == 1
979        endif
980       
981        if( (lambda < 5) || (lambda > 20 ) )
982                Abort "Wavelength out of calibration range (5,20). You must manually enter the absolute parameters"
983        Endif
984       
985        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
986                Execute "MakeNG3AttenTable()"
987        Endif
988        //just in case creating the tables fails....
989        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
990                Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters"
991        Endif
992       
993        //lookup the value by interpolating the wavelength
994        //the attenuator must always be an integer
995        Wave att = $attStr
996        Wave lam = $lamstr
997        trans = interp(lambda,lam,att)
998       
999//      Print "trans = ",trans
1000       
1001        return trans
1002End
1003
1004//returns the transmission of the attenuator (at NG7) given the attenuator number
1005//which must be an integer(to select the wave) and given the wavelength.
1006//the wavelength may be any value between 5 and 20 (A), and is interpolated
1007//between calibrated wavelengths for a given attenuator
1008//
1009// this set of tables is also used for NG5 (NG1) SANS instrument - as the attenuator has yet to be calibrated
1010//
1011// local function
1012//
1013Function LookupAttenNG7(lambda,attenNo)
1014        Variable lambda, attenNo
1015       
1016        Variable trans
1017        String attStr="root:myGlobals:Attenuators:ng7att"+num2str(trunc(attenNo))
1018        String lamStr = "root:myGlobals:Attenuators:ng7lambda"
1019       
1020        if(attenNo == 0)
1021                return (1)              //no attenuation, return trans == 1
1022        endif
1023       
1024        if( (lambda < 5) || (lambda > 20 ) )
1025                Abort "Wavelength out of calibration range (5,20). You must manually enter the absolute parameters"
1026        Endif
1027       
1028        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
1029                Execute "MakeNG7AttenTable()"
1030        Endif
1031        //just in case creating the tables fails....
1032        if(!(WaveExists($attStr)) || !(WaveExists($lamStr)) )
1033                Abort "Attenuator lookup waves could not be found. You must manually enter the absolute parameters"
1034        Endif
1035       
1036        //lookup the value by interpolating the wavelength
1037        //the attenuator must always be an integer
1038        Wave att = $attStr
1039        Wave lam = $lamstr
1040        trans = interp(lambda,lam,att)
1041       
1042        //Print "trans = ",trans
1043       
1044        return trans
1045
1046End
1047
1048//returns the proper attenuation factor based on the instrument (NG3, NG5, or NG7)
1049//NG5 values are taken from the NG7 tables (there is very little difference in the
1050//values, and NG5 attenuators have not been calibrated (as of 8/01)
1051//
1052// filestr is passed from TextRead[3] = the default directory
1053// lam is passed from RealsRead[26]
1054// AttenNo is passed from ReaslRead[3]
1055//
1056// Attenuation factor as defined here is <= 1
1057//
1058// ORNL can pass ("",1,attenuationFactor) and have this function simply
1059// spit back the attenuationFactor (that was read into rw[3])
1060//
1061// called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf
1062//
1063Function AttenuationFactor(fileStr,lam,attenNo)
1064        String fileStr
1065        Variable lam,attenNo
1066       
1067        Variable attenFactor=1,loc
1068        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
1069       
1070        strswitch(instr)
1071                case "NG3":
1072                        attenFactor = LookupAttenNG3(lam,attenNo)
1073                        break
1074                case "NG5":
1075                        //using NG7 lookup Table
1076                        attenFactor = LookupAttenNG7(lam,attenNo)
1077                        break
1078                case "NG7":
1079                        attenFactor = LookupAttenNG7(lam,attenNo)
1080                        break
1081                default:                                                       
1082                        //return error?
1083                        attenFactor=1
1084        endswitch
1085//      print "instr, lambda, attenNo,attenFactor = ",instr,lam,attenNo,attenFactor
1086        return(attenFactor)
1087End
1088
1089//function called by the popups to get a file list of data that can be sorted
1090// this procedure simply removes the raw data files from the string - there
1091//can be lots of other junk present, but this is very fast...
1092//
1093// could also use the alternate procedure of keeping only file with the proper extension
1094//
1095// another possibility is to get a listing of the text files, but is unreliable on
1096// Windows, where the data file must be .txt (and possibly OSX)
1097//
1098// called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf
1099//
1100Function/S ReducedDataFileList(ctrlName)
1101        String ctrlName
1102
1103        String list="",newList="",item=""
1104        Variable num,ii
1105       
1106        //check for the path
1107        PathInfo catPathName
1108        if(V_Flag==0)
1109                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
1110                Return("")
1111        Endif
1112       
1113        list = IndexedFile(catpathName,-1,"????")
1114        num=ItemsInList(list,";")
1115        //print "num = ",num
1116        for(ii=(num-1);ii>=0;ii-=1)
1117                item = StringFromList(ii, list  ,";")
1118                //simply remove all that are not raw data files (SA1 SA2 SA3)
1119                if( !stringmatch(item,"*.SA1*") && !stringmatch(item,"*.SA2*") && !stringmatch(item,"*.SA3*") )
1120                        if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
1121                                newlist += item + ";"
1122                        endif
1123                endif
1124        endfor
1125        //remove VAX version numbers
1126        newList = RemoveVersNumsFromList(newList)
1127        //sort
1128        newList = SortList(newList,";",0)
1129
1130        return newlist
1131End
1132
1133// returns a list of raw data files in the catPathName directory on disk
1134// - list is SEMICOLON-delimited
1135//
1136// does it the "cheap" way, simply finding the ".SAn" in the file name
1137// = does not check for proper byte length.
1138//
1139// called by PatchFiles.ipf, Tile_2D.ipf
1140//
1141Function/S GetRawDataFileList()
1142       
1143        //make sure that path exists
1144        PathInfo catPathName
1145        if (V_flag == 0)
1146                Abort "Folder path does not exist - use Pick Path button on Main Panel"
1147        Endif
1148       
1149        String list=IndexedFile(catPathName,-1,"????")
1150        String newList="",item=""
1151        Variable num=ItemsInList(list,";"),ii
1152        for(ii=0;ii<num;ii+=1)
1153                item = StringFromList(ii, list  ,";")
1154                if( stringmatch(item,"*.sa1*") )
1155                        newlist += item + ";"
1156                endif
1157                if( stringmatch(item,"*.sa2*") )
1158                        newlist += item + ";"
1159                endif
1160                if( stringmatch(item,"*.sa3*") )
1161                        newlist += item + ";"
1162                endif
1163                //print "ii=",ii
1164        endfor
1165        newList = SortList(newList,";",0)
1166        return(newList)
1167End
Note: See TracBrowser for help on using the repository browser.