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

Last change on this file since 74 was 74, checked in by srkline, 15 years ago

More changes to move NCNR calls from the main section of code. Transmission is the current sticking point.

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