source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/HFIR_Utils.ipf @ 940

Last change on this file since 940 was 940, checked in by srkline, 9 years ago

Updated the reduction Read/Write? and corresponding factility stubs to accomodate detector dead time written to the VAX header. It is currently not written to the header, but may be with NICE (hopefully).

With the move of NG3 SANS to CGB(upper), the NG3 designation in the account name [NGxSANSxx] has been replaced with CGB. Folders on charlotte and radio button on SASCALC are labeled "NGB30" to be more obvious which instrument it is.

FFT routines have minor typos cleaned up.

File size: 32.5 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
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// initializes globals that are specific to a particular facility
13// - number of XY pixels
14// - pixexl resolution [cm]
15// - detector deadtime constant [s]
16//
17// called by Initialize.ipf
18//
19Function InitFacilityGlobals()
20
21        //Detector -specific globals
22        Variable/G root:myGlobals:gNPixelsX=192                                 // number of detector X and Y pixels
23        Variable/G root:myGlobals:gNPixelsY=192
24       
25        // pixel dimensions are now read directly from the file header.
26        Variable/G root:myGlobals:PixelResDefault = 0.51        //pixel resolution in cm
27        //No dead time measured for HFIR detector but the count rate is set very low. For now, set the detector perfect.
28        // This should be updated when the condition is changed.   JHC 09/02/09
29        Variable/G root:myGlobals:DeadtimeDefault =  0       //3.4e-6 (NIST value)      //deadtime in seconds
30
31        Variable/G root:myGlobals:apOff = 5.0           // (cm) distance from sample aperture to sample positio
32
33End
34
35
36//**********************
37// Resolution calculation - used by the averaging routines
38// to calculate the resolution function at each q-value
39// - the return value is not used
40//
41// equivalent to John's routine on the VAX Q_SIGMA_AVE.FOR
42// Incorporates eqn. 3-15 from J. Appl. Cryst. (1995) v. 28 p105-114
43//
44// - 21 MAR 07 uses projected BS diameter on the detector
45// - APR 07 still need to add resolution with lenses. currently there is no flag in the
46//          raw data header to indicate the presence of lenses.
47//
48// - Aug 07 - added input to switch calculation based on lenses (==1 if in)
49//
50// - called by CircSectAvg.ipf and RectAnnulAvg.ipf
51//
52// passed values are read from RealsRead
53// except DDet and apOff, which are set from globals before passing
54//
55//
56Function/S getResolution(inQ,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,SigmaQ,QBar,fSubS)
57        Variable inQ, lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses
58        Variable &fSubS, &QBar, &SigmaQ         //these are the output quantities at the input Q value
59       
60        //lots of calculation variables
61        Variable a2, q_small, lp, v_lambda, v_b, v_d, vz, yg, v_g
62        Variable r0, delta, inc_gamma, fr, fv, rmd, v_r1, rm, v_r
63
64        //Constants
65        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
66        Variable g = 981.0                              //gravity acceleration [cm/s^2]
67
68        String results
69        results ="Failure"
70
71        S1 *= 0.5*0.1                   //convert to radius and [cm]
72        S2 *= 0.5*0.1
73
74        L1 *= 100.0                     // [cm]
75        L1 -= apOff                             //correct the distance
76
77        L2 *= 100.0
78        L2 += apOff
79        del_r *= 0.1                            //width of annulus, convert mm to [cm]
80       
81        BS *= 0.5*0.1                   //nominal BS diameter passed in, convert to radius and [cm]
82        // 21 MAR 07 SRK - use the projected BS diameter, based on a point sample aperture
83        Variable LB
84        LB = 20.1 + 1.61*BS                     //distance in cm from beamstop to anode plane (empirical)
85        BS = bs + bs*lb/(l2-lb)         //adjusted diameter of shadow from parallax
86       
87        //Start resolution calculation
88        a2 = S1*L2/L1 + S2*(L1+L2)/L1
89        q_small = 2.0*Pi*(BS-a2)*(1.0-lambdaWidth)/(lambda*L2)
90        lp = 1.0/( 1.0/L1 + 1.0/L2)
91
92        v_lambda = lambdaWidth^2/6.0
93       
94//      if(usingLenses==1)                      //SRK 2007
95        if(usingLenses != 0)                    //SRK 2008 allows for the possibility of different numbers of lenses in header
96                v_b = 0.25*(S1*L2/L1)^2 +0.25*(2/3)*(lambdaWidth/lambda)^2*(S2*L2/lp)^2         //correction to 2nd term
97        else
98                v_b = 0.25*(S1*L2/L1)^2 +0.25*(S2*L2/lp)^2              //original form
99        endif
100       
101        v_d = (DDet/2.3548)^2 + del_r^2/12.0
102        vz = vz_1 / lambda
103        yg = 0.5*g*L2*(L1+L2)/vz^2
104        v_g = 2.0*(2.0*yg^2*v_lambda)                                   //factor of 2 correction, B. Hammouda, 2007
105
106        r0 = L2*tan(2.0*asin(lambda*inQ/(4.0*Pi) ))
107        delta = 0.5*(BS - r0)^2/v_d
108
109        if (r0 < BS)
110                inc_gamma=exp(gammln(1.5))*(1-gammp(1.5,delta))
111        else
112                inc_gamma=exp(gammln(1.5))*(1+gammp(1.5,delta))
113        endif
114
115        fSubS = 0.5*(1.0+erf( (r0-BS)/sqrt(2.0*v_d) ) )
116        if (fSubS <= 0.0)
117                fSubS = 1.e-10
118        endif
119        fr = 1.0 + sqrt(v_d)*exp(-1.0*delta) /(r0*fSubS*sqrt(2.0*Pi))
120        fv = inc_gamma/(fSubS*sqrt(Pi)) - r0^2*(fr-1.0)^2/v_d
121
122        rmd = fr*r0
123        v_r1 = v_b + fv*v_d +v_g
124
125        rm = rmd + 0.5*v_r1/rmd
126        v_r = v_r1 - 0.5*(v_r1/rmd)^2
127        if (v_r < 0.0)
128                v_r = 0.0
129        endif
130        QBar = (4.0*Pi/lambda)*sin(0.5*atan(rm/L2))
131        SigmaQ = QBar*sqrt(v_r/rmd^2 +v_lambda)
132
133        results = "success"
134        Return results
135End
136
137
138
139//Utility function that returns the detector resolution (in cm)
140//Global values are set in the Initialize procedure
141//
142// - called by CircSectAvg.ipf, RectAnnulAvg.ipf, and ProtocolAsPanel.ipf
143//
144// fileStr is passed as TextRead[3] and is the filename
145// detStr is passed as TextRead[9] and is an identifier for the detector
146//
147// depricated - pixel dimensions are read directly from the file header
148Function xDetectorPixelResolution(fileStr,detStr)
149        String fileStr,detStr
150       
151        Variable DDet
152        NVAR PixelResDefault = root:myGlobals:PixelResDefault
153        //your code here
154        DDet = PixelResDefault  //0.515 cm, typical for new ORNL detectors
155        return(DDet)
156End
157
158//Utility function that returns the detector deadtime (in seconds)
159//Global values are set in the Initialize procedure
160//
161// - called by WorkFileUtils.ipf
162//
163// fileStr is passed as TextRead[3] and is the filename
164// detStr is passed as TextRead[9] and is an identifier for the detector
165//
166// [dateAndTimeStr] is optional, and could be used as a switch for
167// different historical detector configurations
168Function DetectorDeadtime(fileStr,detStr,[dateAndTimeStr,dtime])
169        String fileStr,detStr,dateAndTimeStr
170        Variable dtime
171       
172        Variable deadtime
173        NVAR DeadtimeDefault = root:myGlobals:DeadtimeDefault
174       
175        deadtime = DeadtimeDefault      //3.4e-6 seconds, typical for new ORNL detectors //???????????????????????????
176        return(deadtime)
177End
178
179
180
181// item is a filename
182//
183// this function extracts some sort of number from the file
184// presumably some sort of automatically incrementing run number set by the
185// acquisition system
186//
187// this run number should be a unique identifier for the file
188//Because HFIR data format is w/ 2X 4digit number. We add them to get a unique number => This will cause the arrow button not working.
189Function GetRunNumFromFile(item)
190        String item
191        Variable invalid = -1   //negative numbers are invalid
192        Variable num=-1
193       
194        //find the "dot"
195        String runStr=""
196        Variable pos = strsearch(item,".",0)
197        if(pos == -1)
198                //"dot" not found
199                return (invalid)
200        else
201                //found, get the nine characters preceeding it
202                if (pos <=8)
203                        //not enough characters
204                        return (invalid)
205                else
206                        Variable pos_bio = strsearch( LowerStr(item),"biosans",0)
207                        //if  (pos_bio== -1)
208                                runStr  = item[pos-9,pos-6]     //first 4 numbers
209                        //else
210                                runStr  += item[pos-4,pos-1]    //add last 4 numbers
211                        //endif
212                        //convert to a number
213                        num = str2num(runStr)
214                       
215                        //if valid, return it
216                        if (num == NaN)
217                                //8 characters were not a number
218                                return (invalid)
219                        else
220                                //run was OK
221                                return (num)
222                        Endif
223                Endif
224        Endif
225       
226End
227
228
229// item is a filename
230//
231// this function extracts some sort of number from the file
232// presumably some sort of automatically incrementing run number set by the
233// acquisition system
234//
235// this run number should be a unique identifier for the file
236//
237// same as GetRunNumFromFile(0), just with a string return
238//
239// "ABC" returned as an invalid result
240// XXXXSANS_expXX._scan1234_5678.xmp ==> "12345678"
241// -- result is an 8-character string
242//
243Function/S GetRunNumStrFromFile(item)   //,numposition)
244        String item
245        Variable numposition
246       
247        String invalid = "ABC"  //"ABC" is not a valid run number, since it's text
248        String retStr
249        retStr=invalid
250
251        //find the "dot"
252        Variable pos = strsearch( LowerStr(item),".xml",0)
253        if(pos == -1)
254                //"dotxml" not found
255                return (retStr)
256        else
257                pos = strsearch( LowerStr(item),"_scan",0)
258               
259                if  (pos == -1)
260                        //not a raw data file
261                        return (retStr)
262                else
263                        //Variable pos_bio = strsearch( LowerStr(item),"biosans_",0)  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
264                        //if  (numposition == 0)
265                                //Take the first four: //HiResSANS
266                                retStr = item[pos+5,pos+8]
267                        //else 
268                                //add the last four: //BioSANS
269                                retStr += item[pos+10,pos+13]
270                        //Endif
271                        return (retStr)
272                Endif
273        Endif
274       
275End
276
277//returns a string containing the full path to the file containing the
278//run number "num". The null string is returned if no valid file can be found.
279//
280//
281// search in the path "catPathName" (hard-wired), will abort if this path does not exist
282//the file returned will be a RAW SANS data file, other types of files are
283//filtered out.
284//
285// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
286//
287Function/S FindFileFromRunNumber(num)
288        Variable num
289
290        String fullName="",partialName="",item=""
291        //get list of raw data files in folder that match "num" (add leading zeros)
292        if( (num>99999999) || (num<0) )
293                //Print "error in  FindFileFromRunNumber(num), file number too large or too small"
294                Return ("")
295        Endif
296        //make a four character string of the run number
297        String numStr=""
298       
299        if(num > 9999999 && num < 100000000)
300                numStr = num2istr(num)
301        endif
302        if(num > 999999 && num < 10000000)
303                numStr = "0"+num2istr(num)
304        endif   
305        if(num > 99999 && num < 1000000)
306                numStr = "00"+num2istr(num)
307        endif   
308        if(num > 9999 && num < 100000)
309                numStr = "000"+num2istr(num)
310        endif
311        if(num > 999 && num < 10000)
312                numStr =  "0000"+num2istr(num)
313        endif
314        if(num > 99 && num < 1000)
315                numStr = "00000"+num2istr(num)
316        endif   
317        if(num > 9 && num < 100)
318                numStr = "000000"+num2istr(num)
319        endif   
320        if(num < 10 && num >0)
321                numStr = "0000000"+num2iStr(num)
322        endif
323        if(num == 0)
324                numStr = "00000000"
325        endif
326
327        //make sure that path exists
328        PathInfo catPathName
329        String path = S_path
330        if (V_flag == 0)
331                Abort "folder path does not exist - use Pick Path button"
332        Endif
333        String list="",newList="",testStr=""
334       
335        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
336        //find (the) one with the number in the run # location in the name
337        Variable numItems,ii,runFound,isRAW
338        numItems = ItemsInList(list,";")                //get the new number of items in the list
339
340        ii=0
341        do
342                //parse through the list in this order:
343                // 1 - does item contain run number (as a string) "NAMESANS_expNN_scan####_####.xml" : Let's check the 8  nums.
344                // 2 - exclude by isRaw? (to minimize disk access)
345                item = StringFromList(ii, list  ,";" )
346               
347                if(strlen(item) != 0)
348                        //find the run number, if it exists as a 8 character string
349                        testStr = GetRunNumStrFromFile(item)    //0)
350                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
351                       
352                        if(runFound == 0)
353                                //the run Number was found
354                                //build valid filename
355                                partialName = FindValidFileName(item)
356                               
357                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
358                                        fullName = path + partialName
359                                        //check if RAW, if so,this must be the file!
360                                        isRAW = CheckIfRawData(fullName)
361                                        if(isRaw)
362                                                //stop here
363                                                return(fullname)
364                                        Endif
365                                Endif
366                        Endif
367                       
368                Endif
369                ii+=1
370        while(ii<numItems)              //process all items in list
371        print "The run number (", numStr, " +- 1 ) does not exist... (Note: The run number is defined as 12345678 if the file name is NameSANS_exp##_scan1234_5678.xml)"
372        Return ("")     //null return if file not found in list
373End
374
375
376//make an (N) character string of the run number
377//Moved to facility utils
378//
379// same scheme to get 8-character string as in GetRunNumStrFromFile(item)
380//
381Function/S RunDigitString(num)
382        Variable num
383
384        String numStr=""
385
386        //make 8 digit string from run number
387        sprintf numStr,"%08u",num
388       
389        if(strlen(numStr) > 8)
390                return("")
391        else
392                return(numstr)
393        endif
394       
395End
396
397//given a filename of a SANS data filename of the form
398//TTTTTnnn.SAn_TTT_Txxx
399//returns the prefix "TTTTT" as some number of characters
400//returns "" as an invalid file prefix
401//
402// HFIR writes out files with a "prefix" of the following -- since there is really no "prefix"
403// like in the VAX scheme:
404//                      newFileName = ReplaceString(".xml",textPath[0],"")              //removes 4 chars
405//                      newFileName = ReplaceString("SANS",newFileName,"")              //removes 4 more chars = 8
406//                      newFileName = ReplaceString("exp",newFileName,"")                       //removes 3 more chars = 11
407//                      newFileName = ReplaceString("scan",newFileName,"")              //removes 4 more chars = 15, should be enough?
408//
409//
410// -- so the raw data:          BioSANS_exp9_scan1828_0001.xml
411// -- translates to:            Bio_9_1828_0001.AVE     
412//
413//
414// NCNR-specifc, does not really belong here - it's a beta procedure used for the
415// Combine Files Panel, and I'm not sure of how I'm really going to get this to work properly
416// since the .ABS file written is not of the form that NSORT->Set3NSORTFiles(low,med,hi,pref)
417// is trying to construct
418//
419// changed (Oct 2010) the naming for HFIR from ExecuteProtocol to:
420//                      newFileName = GetPrefixStrFromFile(textPath[0])+GetRunNumStrFromFile(textPath[0])
421// -- translates to:            BioSANS18280001.AVE
422//
423Function/S GetPrefixStrFromFile(item)
424        String item
425        String invalid = ""     //"" is not a valid run prefix, since it's text
426        Variable num=-1
427       
428        //find the "dash"
429        String runStr=""
430        Variable pos = strsearch(item,"_",0)
431        if(pos == -1)
432                //"dot" not found
433                return (invalid)
434        else
435                //found
436                if (pos <=3)
437                        //not enough characters
438                        return (invalid)
439                else
440                        runStr = item[0,pos-1]
441                        return (runStr)
442                Endif
443        Endif
444End
445
446
447
448//function to test a binary file to see if it is a RAW binary SANS file
449//first checks the total bytes in the file (which for raw data is 33316 bytes)
450//**note that the "DIV" file will also show up as a raw file by the run field
451//should be listed in CAT/SHORT and in patch windows
452//
453//Function then checks the file fname (full path:file) for "RAW" run.type field
454//if not found, the data is not raw data and zero is returned
455//
456// called by many procedures (both external and local)
457//
458Function CheckIfRawData(fname)
459        String fname
460             
461        String tempheadhfir                                           
462        Variable ind=0
463        Variable refNum
464       
465        //If not have .xml extension, return 0.
466        if (stringmatch(fname,"*.xml") <1)
467                print fname+": Failed. Not a *.xml file."
468                return 0                                //Not *.xml. Do nothing...
469        endif
470        //actually open the file
471        refNum = XmlOpenFile(fname)     
472        if (refNum < 0)
473                print "==> "+ fname+ "\r  ==> Failed to load: Not a standard xml file format or broken.. Please check the file if properly written..."
474                return 0                                //Not a xml file. Do nothing...
475        endif
476       
477        // Check if  it is the SPICE version = 1.1
478        Variable  item,i,ns = 0
479        String thislocation
480        if (refNum >0)
481                ns = str2num(XMLstrFmXpath(refNum, "//SPICErack/@SPICE_version","",""))
482        endif
483        XmlCloseFile(refNum,0)
484        if (ns <1.1)
485                ns =0
486        else
487                ns =1
488        endif
489       
490        return ns
491End
492
493// for HFIR data, both DIV and RAW are determined by looking for "*.xml"
494Function CheckIfDIVData(fname)
495        String fname
496        return(CheckIfRawData(fname))
497End
498
499// function returns 1 if file is a transmission file, 0 if not
500//
501// called by Transmission.ipf, CatVSTable.ipf, NSORT.ipf
502//
503// SRK MAR 2010 - apparently from what I can see in the files, the beam stop "out"
504// position is 25 mm for all four beam stop Y POSITIONS
505// - if one is larger, (in the hundreds of mm) then it's in, and the run is not a transmission
506// - so if all four y positions are less than (tol) 30 mm, call it a trans file
507//
508// there is a field for this in the header, write "True", so I don't need to guess again.
509// -- but this field is often incorrect - for some sample data ALL FILES were "True"
510// -- better to check the physical location every time
511//
512// tol changed to 401 per Gernot's experience 6/24/10
513//
514Function isTransFile(fName)   ///  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
515        String fname
516       
517        Variable beamtrap_1y=0,beamtrap_2y=0,beamtrap_3y=0,beamtrap_4y=0,tol=401
518        //Check by key "transsmission"
519//      if (stringmatch( getIsTrans(fName),"True")>0)
520//              return (1)
521//      else
522                //Check from beam stop motor position
523        //      if(your test here)
524                beamtrap_1y=getRealValueFromHeader(fname,"//Motor_Positions/trap_y_101mm","mm")
525                beamtrap_2y=getRealValueFromHeader(fname,"//Motor_Positions/trap_y_25mm","mm")
526                beamtrap_3y=getRealValueFromHeader(fname,"//Motor_Positions/trap_y_50mm","mm")
527                beamtrap_4y=getRealValueFromHeader(fname,"//Motor_Positions/trap_y_76mm","mm")
528
529                if (beamtrap_1y < tol && beamtrap_2y < tol && beamtrap_3y < tol && beamtrap_4y < tol)   
530                        //Write the flag ON
531                        Write_isTransmissionToHeader(fName,"True")
532                        return (1)
533                else
534                        //some other file
535                        Write_isTransmissionToHeader(fName,"False")
536                        return (0)
537                endif
538               
539//      endif
540
541        return (0)
542End
543
544
545
546//function to remove all spaces from names when searching for filenames
547//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
548//but the text field in the header WILL, if less than 3 characters were used for the
549//user's initials, and can have leading spaces if prefix was less than 5 characters
550//
551//returns a string identical to the original string, except with the interior spaces removed
552//
553// local function for file name manipulation
554//
555// NO CHANGE NEEDED
556//
557Function/S RemoveAllSpaces(str)
558        String str
559       
560        String tempstr = str
561        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
562        ii=0
563        do
564                len = strlen(tempStr)
565                spc = strsearch(tempStr," ",0)          //is the last character a space?
566                if (spc == -1)
567                        break           //no more spaces found, get out
568                endif
569                str = tempstr
570                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
571        While(1)        //should never be more than 2 or 3
572       
573        If(strlen(tempStr) < 1)
574                tempStr = ""            //be sure to return a null string if problem found
575        Endif
576       
577        //Print strlen(tempstr)
578       
579        Return(tempStr)
580               
581End
582
583
584
585//Function attempts to find valid filename from partial name by checking for
586// the existence of the file on disk
587//
588// returns a valid filename (No path prepended) or a null string
589//
590// called by any functions, both external and local
591//
592Function/S FindValidFilename(partialName)
593        String PartialName
594       
595        String retStr=partialName
596
597        //your code here
598        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
599        retStr = ValidFileString(partialName)
600        if(cmpstr(retStr,"") !=0)
601                return(retStr)
602        endif
603       
604        //if the partial name is derived from the file header, there can be spaces at the beginning
605        //or in the middle of the filename - depending on the prefix and initials used
606        //
607        //remove any leading spaces from the name before starting
608        partialName = RemoveAllSpaces(partialName)
609       
610        //try name with no spaces
611        retStr = ValidFileString(partialName)
612        if(cmpstr(retStr,"") !=0)
613                //non-null return
614                return(retStr)
615        endif
616       
617        //try all UPPERCASE
618        partialName = UpperStr(partialName)
619        retStr = ValidFileString(partialName)
620        if(cmpstr(retStr,"") !=0)
621                //non-null return
622                return(retStr)
623        endif
624       
625        //try all lowercase (ret null if failure)
626        partialName = LowerStr(partialName)
627        retStr = ValidFileString(partialName)
628        if(cmpstr(retStr,"") !=0)
629                //non-null return
630                return(retStr)
631        else
632                return(retStr)
633        endif
634End
635
636// Function checks for the existence of a file
637
638// *** the PATH is hard-wired to catPathName (which is assumed to exist)
639// version numers up to ;10 are tried
640// only the "name;vers" is returned if successful. The path is not prepended
641//
642// local function
643//
644Function/S ValidFileString(partialName)
645        String partialName
646       
647        String tempName = "",msg=""
648        Variable ii,refnum
649
650        ii=0
651        do
652                if(ii==0)
653                        //first pass, try the partialName
654                        tempName = partialName
655                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
656                        if(V_flag == 0)
657                                //file exists
658                                Close refnum            //YES needed,
659                                break
660                        endif
661                else
662                        tempName = partialName + ";" + num2str(ii)
663                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
664                        if(V_flag == 0)
665                                //file exists
666                                Close refnum
667                                break
668                        endif
669                Endif
670                ii+=1
671
672        while(ii<11)
673        //go get the selected bits of information, using tempName, which exists
674        if(ii>=11)
675                //msg = partialName + " not found. is version number > 11?"
676                //DoAlert 0, msg
677                //PathInfo catPathName
678                //Print S_Path
679                Return ("")             //use null string as error condition
680        Endif
681               
682        Return (tempName)
683End
684
685
686//returns a string containing filename (WITHOUT the ;vers)
687//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
688//with the folders separated by colons
689//
690// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
691//
692// NO CHANGE NEEDED
693//
694
695Function/S GetFileNameFromPathNoSemi(fullPath)
696        String fullPath
697       
698        Variable offset1,offset2
699        String filename=""
700        //String PartialPath
701        offset1 = 0
702        do
703                offset2 = StrSearch(fullPath, ":", offset1)
704                if (offset2 == -1)                              // no more colons ?
705                        fileName = FullPath[offset1,strlen(FullPath) ]
706                        //PartialPath = FullPath[0, offset1-1]
707                        break
708                endif
709                offset1 = offset2+1
710        while (1)
711       
712        //remove version number from name, if it's there - format should be: filename;N
713        filename =  StringFromList(0,filename,";")              //returns null if error
714       
715        Return filename
716End
717
718//returns a string containing filename (INCLUDING the ;vers)
719//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
720//with the folders separated by colons
721//
722// local, currently unused
723//
724// NO CHANGE NEEDED
725//
726
727Function/S GetFileNameFromPathKeepSemi(fullPath)
728        String fullPath
729       
730        Variable offset1,offset2
731        String filename
732        //String PartialPath
733        offset1 = 0
734        do
735                offset2 = StrSearch(fullPath, ":", offset1)
736                if (offset2 == -1)                              // no more colons ?
737                        fileName = FullPath[offset1,strlen(FullPath) ]
738                        //PartialPath = FullPath[0, offset1-1]
739                        break
740                endif
741                offset1 = offset2+1
742        while (1)
743       
744        //keep version number from name, if it's there - format should be: filename;N
745       
746        Return filename
747End
748
749//given the full path and filename (fullPath), strips the data path
750//(Mac-style, separated by colons) and returns this path
751//this partial path is the same string that would be returned from PathInfo, for example
752//
753// - allows the user to save to a different path than catPathName
754//
755// called by WriteQIS.ipf
756//
757// NO CHANGE NEEDED
758//
759
760Function/S GetPathStrFromfullName(fullPath)
761        String fullPath
762       
763        Variable offset1,offset2
764        //String filename
765        String PartialPath
766        offset1 = 0
767        do
768                offset2 = StrSearch(fullPath, ":", offset1)
769                if (offset2 == -1)                              // no more colons ?
770                        //fileName = FullPath[offset1,strlen(FullPath) ]
771                        PartialPath = FullPath[0, offset1-1]
772                        break
773                endif
774                offset1 = offset2+1
775        while (1)
776       
777        Return PartialPath
778End
779
780//given the filename trim or modify the filename to get a new
781//file string that can be used for naming averaged 1-d files
782//
783// called by ProtocolAsPanel.ipf and Tile_2D.ipf
784//
785Function/S GetNameFromHeader(fName)
786        String fName
787        String temp, newName = ""
788        Variable spc,ii=0
789       
790        //filename is 31-33 characters INSTRNAMESANS_exp##_scan####_####.xml (where # : numbers)
791        //returns a null string if no name can be found
792        Variable iimax =  strlen(fName)
793        do
794                temp = fname[ii,iimax-1-4]              //characters ii,all of the name
795                spc = strsearch(temp," ",0)
796                if (spc == -1)
797                        break           //no more spaces found
798                endif
799                ii+=1
800        While(ii<iimax)
801       
802        If(strlen(temp) < 1)
803                newName = ""            //be sure to return a null string if problem found
804        else
805                newName = temp
806        Endif
807       
808        Return(newName)
809End
810
811//list (input) is a list, typically returned from IndexedFile()
812//which is semicolon-delimited, and may contain filenames from the VAX
813//that contain version numbers, where the version number appears as a separate list item
814//(and also as a non-existent file)
815//these numbers must be purged from the list, especially for display in a popup
816//or list processing of filenames
817//the function returns the list, cleaned of version numbers (up to 11)
818//raw data files will typically never have a version number other than 1.
819//
820// if there are no version numbers in the list, the input list is returned
821//
822// called by CatVSTable.ipf, NSORT.ipf, Transmission.ipf, WorkFileUtils.ipf
823//
824// NO CHANGE NEEDED
825//
826
827Function/S RemoveVersNumsFromList(list)
828        String list
829       
830        //get rid of version numbers first (up to 11)
831        Variable ii,num
832        String item
833        num = ItemsInList(list,";")
834        ii=1
835        do
836                item = num2str(ii)
837                list = RemoveFromList(item, list ,";" )
838                ii+=1
839        while(ii<12)
840       
841        return (list)
842End
843
844//input is a list of run numbers, and output is a list of filenames (not the full path)
845//*** input list must be COMMA delimited***
846//output is equivalent to selecting from the CAT table
847//if some or all of the list items are valid filenames, keep them...
848//if an error is encountered, notify of the offending element and return a null list
849//
850//output is COMMA delimited
851//
852// this routine is expecting that the "ask", "none" special cases are handled elsewhere
853//and not passed here
854//
855// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
856//
857// NO CHANGE NEEDED
858//
859
860Function/S ParseRunNumberList(list)
861        String list
862       
863        String newList="",item="",tempStr=""
864        Variable num,ii,runNum
865       
866        //expand number ranges, if any
867        list = ExpandNumRanges(list)
868       
869        num=itemsinlist(list,",")
870       
871        for(ii=0;ii<num;ii+=1)
872                //get the item
873                item = StringFromList(ii,list,",")
874                //is it already a valid filename?
875               
876                tempStr=FindValidFilename(item) //returns filename if good, null if error
877                if(strlen(tempstr)!=0)
878                        //valid name, add to list
879                        //Print "it's a file"
880                        newList += tempStr + ","
881                else
882                        //not a valid name
883                        //is it a number?
884                        runNum=str2num(item)
885
886                        if(numtype(runNum) != 0)
887                                //not a number -  maybe an error                       
888                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
889                                return("")
890                        else
891                                //a run number or an error
892                                tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) )
893                                if(strlen(tempstr)==0)
894                                        //file not found, error
895                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
896                                        return("")
897                                else
898                                        newList += tempStr + ","
899                                endif
900                        endif
901                endif
902        endfor          //loop over all items in list
903
904        return(newList)
905End
906
907//takes a comma delimited list that MAY contain number range, and
908//expands any range of run numbers into a comma-delimited list...
909//and returns the new list - if not a range, return unchanged
910//
911// local function
912//
913// NO CHANGE NEEDED
914//
915
916Function/S ExpandNumRanges(list)
917        String list
918       
919        String newList="",dash="-",item,str
920        Variable num,ii,hasDash
921       
922        num=itemsinlist(list,",")
923
924        for(ii=0;ii<num;ii+=1)
925                //get the item
926                item = StringFromList(ii,list,",")
927                //does it contain a dash?
928                hasDash = strsearch(item,dash,0)                //-1 if no dash found
929                if(hasDash == -1)
930                        //not a range, keep it in the list
931                        newList += item + ","
932                else
933                        //has a dash (so it's a range), expand (or add null)
934                        newList += ListFromDash(item)           
935                endif
936        endfor
937       
938        return newList
939End
940
941//be sure to add a trailing comma to the return string...
942//
943// local function
944//
945// NO CHANGE NEEDED
946//
947Function/S ListFromDash(item)
948        String item
949       
950        String numList="",loStr="",hiStr=""
951        Variable lo,hi,ii
952       
953        loStr=StringFromList(0,item,"-")        //treat the range as a list
954        hiStr=StringFromList(1,item,"-")
955        lo=str2num(loStr)
956        hi=str2num(hiStr)
957        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
958                numList=""
959                return numList
960        endif
961        for(ii=lo;ii<=hi;ii+=1)
962                numList += num2str(ii) + ","
963        endfor
964       
965        Return numList
966End
967
968
969//returns the proper attenuation factor based on the instrument
970//
971// filestr is passed from TextRead[3] = the default directory, used to identify the instrument
972// lam is passed from RealsRead[26]
973// AttenNo is passed from ReaslRead[3]
974//
975// Attenuation factor as defined here is <= 1
976//
977// Facilities can pass ("",1,attenuationFactor) and have this function simply
978// spit back the attenuationFactor (that was read into rw[3])
979//
980// called by Correct.ipf, ProtocolAsPanel.ipf, Transmission.ipf
981//
982// atten_err is one std. deviation, passed back by reference
983Function AttenuationFactor(fileStr,lam,attenuation, atten_err)
984        String fileStr
985        Variable lam,attenuation, &atten_err  //    0 =< attenuation <= 100 (%) : where no attenuator stands for 0.
986       
987        Variable attenFactor=1
988       
989        // your code here
990        attenFactor = 1- attenuation*0.01  //???Attenuate transmission
991
992        // Change April 2011 - now returns error in atten trans
993        atten_err = 0
994       
995        return(attenFactor)
996End
997
998//function called by the popups to get a file list of data that can be sorted
999// this procedure simply removes the raw data files from the string - there
1000//can be lots of other junk present, but this is very fast...
1001//
1002// could also use the alternate procedure of keeping only file with the proper extension
1003//
1004// another possibility is to get a listing of the text files, but is unreliable on
1005// Windows, where the data file must be .txt (and possibly OSX)
1006//
1007// called by FIT_Ops.ipf, NSORT.ipf, PlotUtils.ipf
1008//
1009Function/S ReducedDataFileList(ctrlName)
1010        String ctrlName
1011
1012        String list="",newList="",item=""
1013        Variable num,ii
1014       
1015        //check for the path
1016        PathInfo catPathName
1017        if(V_Flag==0)
1018                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
1019                Return("")
1020        Endif
1021       
1022        list = IndexedFile(catpathName,-1,"????")
1023        num=ItemsInList(list,";")
1024
1025        for(ii=(num-1);ii>=0;ii-=1)
1026                item = StringFromList(ii, list  ,";")
1027                //simply remove all that are not raw data files (SA1 SA2 SA3)
1028                //if( !stringmatch(item,"*HiResSANS*.xml") && !stringmatch(item,"*BioSANS*.xml"))
1029                        if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
1030                                newlist += (item) + ";"   
1031                        endif
1032                //endif
1033        endfor
1034        //remove VAX version numbers
1035        newList = RemoveVersNumsFromList(newList)
1036        //sort
1037        newList = SortList(newList,";",0)
1038
1039        return newlist
1040End
1041
1042// returns a list of raw data files in the catPathName directory on disk
1043// - list is SEMICOLON-delimited
1044//
1045// does it the "cheap" way, simply finding the ".SAn" in the file name
1046// = does not check for proper byte length.
1047//
1048// called by PatchFiles.ipf, Tile_2D.ipf
1049//
1050Function/S GetRawDataFileList()
1051       
1052        //make sure that path exists
1053        PathInfo catPathName
1054        if (V_flag == 0)
1055                Abort "Folder path does not exist - use Pick Path button on Main Panel"
1056        Endif
1057       
1058        String list=IndexedFile(catPathName,-1,"????")
1059        String newList="",item=""
1060        Variable num=ItemsInList(list,";"),ii
1061        for(ii=0;ii<num;ii+=1)
1062                item = StringFromList(ii, list  ,";")
1063                if( stringmatch(item,"*.xml") )
1064                        if (CheckIfRawData(S_path+item) >0)
1065                                newlist += item + ";"
1066                        endif
1067                endif
1068                // if condition is in here twice, not sure why since they are both "*.xml"
1069//              if( stringmatch(item,"*.xml") )
1070//                      if (CheckIfRawData(S_path+item) >0)
1071//                              newlist += item + ";"
1072//                      endif
1073//              endif
1074        endfor
1075        newList = SortList(newList,";",0)
1076        return(newList)
1077End
1078
1079//**********************
1080// 2D resolution function calculation - in terms of X and Y
1081//
1082// based on notes from David Mildner, 2008
1083//
1084// the final NCNR version is located in NCNR_Utils.ipf
1085//
1086Function/S get2DResolution(inQ,phi,lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,del_r,usingLenses,r_dist,SigmaQX,SigmaQY,fSubS)
1087        Variable inQ, phi,lambda, lambdaWidth, DDet, apOff, S1, S2, L1, L2, BS, del_r,usingLenses,r_dist
1088        Variable &SigmaQX,&SigmaQY,&fSubS               //these are the output quantities at the input Q value
1089       
1090        return("Function Empty")
1091End
1092
1093
1094
1095
1096// Return the filename that represents the previous or next file.
1097// Input is current filename and increment.
1098// Increment should be -1 or 1
1099// -1 => previous file
1100// 1 => next file
1101Function/S GetPrevNextRawFile(curfilename, prevnext)
1102        String curfilename
1103        Variable prevnext
1104
1105        String filename
1106       
1107        //get the run number
1108        Variable num = GetRunNumFromFile(curfilename)
1109               
1110        //find the next specified file by number
1111        fileName = FindPrevNextRawFile(curfilename, prevnext)
1112
1113        if(cmpstr(fileName,"")==0)
1114                //null return, do nothing
1115                fileName = FindFileFromRunNumber(num)
1116        Endif
1117
1118        //print "in FU "+filename
1119
1120        Return filename
1121End
1122
1123// Find next or previous file name w/ current file name given.
1124// Sort the list of files and get the next/previous file name.
1125Function/S FindPrevNextRawFile(curfilename, prevnext)
1126        String curfilename
1127        Variable prevnext
1128       
1129        String fullName="",partialName="",item="", list=""
1130        Variable numItems,isRAW
1131                       
1132        //make sure that path exists
1133        PathInfo catPathName
1134        String path = S_path
1135       
1136        if (V_flag == 0)
1137                Abort "folder path does not exist - use Pick Path button"
1138        Endif
1139
1140       
1141        list = SortList(IndexedFile(catPathName,-1,"????"),";") //get all files in folder and make sure it is sorted.
1142       
1143        //find (the) one with the number in the run # location in the name
1144
1145        numItems = ItemsInList(list,";")                //get the new number of items in the list
1146        //index of curfilename
1147        Variable index = WhichListItem(curfilename,list,";",0,0)
1148        //get the prenextitem in the list
1149        item = StringFromList(index+prevnext, list  ,";")
1150        partialName = FindValidFileName(item)
1151       
1152        if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
1153                fullName = path + partialName
1154                //check if RAW, if so,this must be the file!
1155                isRAW = CheckIfRawData(fullName)
1156                if(isRaw)
1157                        //stop here
1158                        return(fullname)
1159                Endif
1160        Endif
1161
1162        print "Please type 'scan number(s)' from your file name..."
1163        Return ("")     //null return if file not found in list
1164End
1165
Note: See TracBrowser for help on using the repository browser.