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

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

Comments in attenuation factor usage regarding ORNL.

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