source: sans/SANSReduction/trunk/Put in User Procedures/SANS_Reduction_v5.00/VAXFileUtils.ipf @ 40

Last change on this file since 40 was 40, checked in by srkline, 16 years ago

Initial checkin of V5.00 SANSReduction files

File size: 34.9 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=4.0
4
5//**************************
6// Vers. 1.2 092101
7//
8//this file is a collection of uilities for processing vax filenames
9//and processing lists (especially for display in popup menus)
10//
11//required to correctly account for VAX supplied version numbers, which
12//may or may not be removed by the ftp utility
13//
14// - parses lists of run numbers into real filenames
15// - selects proper detector constants
16//
17//**************************
18
19
20//given a filename of a SANS data filename of the form
21//TTTTTnnn.SAn_TTT_Txxx
22//returns the run number "nnn" as a number
23//returns -1 as an invalid file number
24Function GetRunNumFromFile(item)
25        String item
26        Variable invalid = -1   //negative numbers are invalid
27        Variable num=-1
28       
29        //find the "dot"
30        String runStr=""
31        Variable pos = strsearch(item,".",0)
32        if(pos == -1)
33                //"dot" not found
34                return (invalid)
35        else
36                //found, get the three characters preceeding it
37                if (pos <=2)
38                        //not enough characters
39                        return (invalid)
40                else
41                        runStr = item[pos-3,pos-1]
42                        //convert to a number
43                        num = str2num(runStr)
44                        //if valid, return it
45                        if (num == NaN)
46                                //3 characters were not a number
47                                return (invalid)
48                        else
49                                //run was OK
50                                return (num)
51                        Endif
52                Endif
53        Endif
54End
55
56//given a filename of a SANS data filename of the form
57//TTTTTnnn.SAn_TTT_Txxx
58//returns the run number "nnn" as a STRING of THREE characters
59//returns "ABC" as an invalid file number
60Function/S GetRunNumStrFromFile(item)
61        String item
62        String invalid = "ABC"  //"ABC" is not a valid run number, since it's text
63        Variable num=-1
64       
65        //find the "dot"
66        String runStr=""
67        Variable pos = strsearch(item,".",0)
68        if(pos == -1)
69                //"dot" not found
70                return (invalid)
71        else
72                //found, get the three characters preceeding it
73                if (pos <=2)
74                        //not enough characters
75                        return (invalid)
76                else
77                        runStr = item[pos-3,pos-1]
78                        return (runStr)
79                Endif
80        Endif
81End
82
83//returns a string containing the full path and file to the file containing the
84//run number "num". The null string is returned if no valid file can be found
85//the path "catPathName" used and is hard-wired, will abort if this path does not exist
86//the file returned will be a RAW SANS data file, other types of files are
87//filtered out.
88Function/S FindFileFromRunNumber(num)
89        Variable num
90       
91        String fullName="",partialName="",item=""
92        //get list of raw data files in folder that match "num" (add leading zeros)
93        if( (num>999) || (num<=0) )
94                //Print "error in  FindFileFromRunNumber(num), file number too large or too small"
95                Return ("")
96        Endif
97        //make a three character string of the run number
98        String numStr=""
99        if(num<10)
100                numStr = "00"+num2str(num)
101        else
102                if(num<100)
103                        numStr = "0"+num2str(num)
104                else
105                        numStr = num2str(num)
106                Endif
107        Endif
108        //Print "numstr = ",numstr
109       
110        //make sure that path exists
111        PathInfo catPathName
112        String path = S_path
113        if (V_flag == 0)
114                Abort "folder path does not exist - use Pick Path button"
115        Endif
116        String list="",newList="",testStr=""
117       
118        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
119        //find (the) one with the number in the run # location in the name
120        Variable numItems,ii,runFound,isRAW
121        numItems = ItemsInList(list,";")                //get the new number of items in the list
122        ii=0
123        do
124                //parse through the list in this order:
125                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
126                // 2 - exclude by isRaw? (to minimize disk access)
127                item = StringFromList(ii, list  ,";" )
128                if(strlen(item) != 0)
129                        //find the run number, if it exists as a three character string
130                        testStr = GetRunNumStrFromFile(item)
131                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
132                        if(runFound == 0)
133                                //the run Number was found
134                                //build valid filename
135                                partialName = FindValidFileName(item)
136                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
137                                        fullName = path + partialName
138                                        //check if RAW, if so,this must be the file!
139                                        isRAW = CheckIfRawData(fullName)
140                                        if(isRaw)
141                                                //stop here
142                                                return(fullname)
143                                        Endif
144                                Endif
145                        Endif
146                Endif
147                ii+=1
148        while(ii<numItems)              //process all items in list
149        Return ("")     //null return if file not found in list
150End
151
152//function to test a binary file to see if it is a RAW binary SANS file
153//first checks the total bytes in the file (which for raw data is 33316 bytes)
154//**note that the "DIV" file will also show up as a raw file by the run field
155//should be listed in CAT/SHORT and in patch windows
156//
157//Function then checks the file fname (full path:file) for "RAW" run.type field
158//if not found, the data is not raw data and zero is returned
159Function CheckIfRawData(fname)
160        String fname
161       
162        Variable refnum,totalBytes
163        String testStr=""
164       
165        Open/R/T="????TEXT" refNum as fname
166        //get the total number of bytes in the file, to avoid moving past EOF
167        FStatus refNum
168        totalBytes = V_logEOF
169        //Print totalBytes
170        if(totalBytes!=33316)
171                //can't possibly be a raw data file
172                Close refnum
173                return(0)               //not a raw SANS file
174        Endif
175        FSetPos refNum,75
176        FReadLine/N=3 refNum,testStr
177        Close refNum
178       
179        if(cmpstr(testStr,"RAW")==0)
180                //true, is raw data file
181                Return(1)
182        else
183                //some other file
184                Return(0)
185        Endif
186End
187
188//function to remove all spaces from names when searching for filenames
189//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
190//but the text field in the header WILL, if less than 3 characters were used for the
191//user's initials, and can have leading spaces if prefix was less than 5 characters
192//
193//returns a string identical to the original string, except with the interior spaces removed
194//
195Function/S RemoveAllSpaces(str)
196        String str
197       
198        String tempstr = str
199        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
200        ii=0
201        do
202                len = strlen(tempStr)
203                spc = strsearch(tempStr," ",0)          //is the last character a space?
204                if (spc == -1)
205                        break           //no more spaces found, get out
206                endif
207                str = tempstr
208                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
209        While(1)        //should never be more than 2 or 3
210       
211        If(strlen(tempStr) < 1)
212                tempStr = ""            //be sure to return a null string if problem found
213        Endif
214       
215        //Print strlen(tempstr)
216       
217        Return(tempStr)
218               
219End
220
221
222//Function attempts to find valid filename from partial name that has been stripped of
223//the VAX version number. The partial name is tried first
224//*** the PATH is hard-wired to catPathName (which is assumed to exist)
225//version numers up to ;10 are tried
226//only the "name;vers" is returned. the path is not prepended, hence the return string
227//is not a complete specification of the file
228//
229// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
230// since from marquee, the filename field (textread[0]) must be used, and can be a mix of
231// upper/lowercase letters, while the filename on the server (should) be all caps
232// now makes repeated calls to ValidFileString()
233//
234Function/S FindValidFilename(partialName)
235        String PartialName
236       
237        String retStr=""
238       
239        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
240        retStr = ValidFileString(partialName)
241        if(cmpstr(retStr,"") !=0)
242                //non-null return
243                return(retStr)
244        Endif
245       
246        //if the partial name is derived from the file header, there can be spaces at the beginning
247        //or in the middle of the filename - depending on the prefix and initials used
248        //
249        //remove any leading spaces from the name before starting
250        partialName = RemoveAllSpaces(partialName)
251       
252        //try name with no spaces
253        retStr = ValidFileString(partialName)
254        if(cmpstr(retStr,"") !=0)
255                //non-null return
256                return(retStr)
257        Endif
258       
259        //try all UPPERCASE
260        partialName = UpperStr(partialName)
261        retStr = ValidFileString(partialName)
262        if(cmpstr(retStr,"") !=0)
263                //non-null return
264                return(retStr)
265        Endif
266       
267        //try all lowercase (ret null if failure)
268        partialName = LowerStr(partialName)
269        retStr = ValidFileString(partialName)
270        if(cmpstr(retStr,"") !=0)
271                //non-null return
272                return(retStr)
273        else
274                return(retStr)
275        Endif
276End
277
278//Function attempts to find valid filename from partial name that has been stripped of
279//the VAX version number. The partial name is tried first
280//*** the PATH is hard-wired to catPathName (which is assumed to exist)
281//version numers up to ;10 are tried
282//only the "name;vers" is returned. the path is not prepended, hence the return string
283//is not a complete specification of the file
284//
285Function/S ValidFileString(partialName)
286        String partialName
287       
288        String tempName = "",msg=""
289        Variable ii,refnum
290       
291        ii=0
292        do
293                if(ii==0)
294                        //first pass, try the partialName
295                        tempName = partialName
296                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
297                        if(V_flag == 0)
298                                //file exists
299                                Close refnum            //YES needed,
300                                break
301                        endif
302                else
303                        tempName = partialName + ";" + num2str(ii)
304                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
305                        if(V_flag == 0)
306                                //file exists
307                                Close refnum
308                                break
309                        endif
310                Endif
311                ii+=1
312                //print "ii=",ii
313        while(ii<11)
314        //go get the selected bits of information, using tempName, which exists
315        if(ii>=11)
316                //msg = partialName + " not found. is version number > 11?"
317                //DoAlert 0, msg
318                //PathInfo catPathName
319                //Print S_Path
320                Return ("")             //use null string as error condition
321        Endif
322       
323        Return (tempName)
324End
325
326
327
328//the following is a WaveMetrics procedure from <StrMatchList>
329// MatchList(matchStr,list,sep)
330// Returns the items of the list whose items match matchStr
331// The lists are separated by the sep character, usually ";"
332//
333// matchStr may be something like "abc", in which case it is identical to CmpStr
334// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
335//      "*abc" to match anything ending with "abc".
336// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
337//      the pattern.
338// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
339//
340Function/S MyMatchList(matchStr,list,sep)
341        String matchStr,list,sep
342        String item,outList=""
343        Variable n=strlen(list)
344        Variable en,st=0
345        do
346                en= strsearch(list,sep,st)
347                if( en < 0 )
348                        if( st < n-1 )
349                                en= n   // no trailing separator
350                                sep=""  // don't put sep in output, either
351                        else
352                                break   // no more items in list
353                        endif
354                endif
355                item=list[st,en-1]
356                if( MyStrMatch(matchStr,item) == 0 )
357                        outlist += item+sep
358                Endif
359                st=en+1
360        while (st < n ) // exit is by break, above
361        return outlist
362End
363
364//the following is a WaveMetrics procedure from <StrMatchList>
365// StrMatch(matchStr,str)
366// Returns 0 if the pattern in matchStr matches str, else it returns 1
367//
368// matchStr may be something like "abc", in which case it is identical to CmpStr
369// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
370//      "*abc" to match anything ending with "abc".
371// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
372//      the pattern.
373// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
374//
375Function MyStrMatch(matchStr,str)
376        String matchStr,str
377        Variable match = 1              // 0 means match
378        Variable invert= strsearch(matchStr,"!",0) == 0
379        if( invert )
380                matchStr[0,0]=""        // remove the "!"
381        endif
382        Variable st=0,en=strlen(str)-1
383        Variable starPos= strsearch(matchStr,"*",0)
384        if( starPos >= 0 )      // have a star
385                if( starPos == 0 )      // at start
386                        matchStr[0,0]=""                                // remove star at start
387                else                                    // at end
388                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
389                endif
390                Variable len=strlen(matchStr)
391                if( len > 0 )
392                        if(starPos == 0)        // star at start, match must be at end
393                                st=en-len+1
394                        else
395                                en=len-1        // star at end, match at start
396                        endif
397                else
398                        str=""  // so that "*" matches anything
399                endif
400        endif
401        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
402        if( invert )
403                match= 1-match
404        endif
405        return match
406End
407
408
409//returns a string containing filename (WITHOUT the ;vers)
410//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
411//with the folders separated by colons
412Function/S GetFileNameFromPathNoSemi(fullPath)
413        String fullPath
414       
415        Variable offset1,offset2
416        String filename=""
417        //String PartialPath
418        offset1 = 0
419        do
420                offset2 = StrSearch(fullPath, ":", offset1)
421                if (offset2 == -1)                              // no more colons ?
422                        fileName = FullPath[offset1,strlen(FullPath) ]
423                        //PartialPath = FullPath[0, offset1-1]
424                        break
425                endif
426                offset1 = offset2+1
427        while (1)
428       
429        //remove version number from name, if it's there - format should be: filename;N
430        filename =  StringFromList(0,filename,";")              //returns null if error
431       
432        Return filename
433End
434
435//returns a string containing filename (INCLUDING the ;vers)
436//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
437//with the folders separated by colons
438Function/S GetFileNameFromPathKeepSemi(fullPath)
439        String fullPath
440       
441        Variable offset1,offset2
442        String filename
443        //String PartialPath
444        offset1 = 0
445        do
446                offset2 = StrSearch(fullPath, ":", offset1)
447                if (offset2 == -1)                              // no more colons ?
448                        fileName = FullPath[offset1,strlen(FullPath) ]
449                        //PartialPath = FullPath[0, offset1-1]
450                        break
451                endif
452                offset1 = offset2+1
453        while (1)
454       
455        //keep version number from name, if it's there - format should be: filename;N
456       
457        Return filename
458End
459
460//given the full path and filename (fullPath), strips the data path
461//(Mac-style, separated by colons) and returns this path
462//this partial path is the same string that would be returned from PathInfo, for example
463Function/S GetPathStrFromfullName(fullPath)
464        String fullPath
465       
466        Variable offset1,offset2
467        //String filename
468        String PartialPath
469        offset1 = 0
470        do
471                offset2 = StrSearch(fullPath, ":", offset1)
472                if (offset2 == -1)                              // no more colons ?
473                        //fileName = FullPath[offset1,strlen(FullPath) ]
474                        PartialPath = FullPath[0, offset1-1]
475                        break
476                endif
477                offset1 = offset2+1
478        while (1)
479       
480        Return PartialPath
481End
482
483//given the VAX filename, pull off the first 8 characters to make a valid
484//file string that can be used for naming averaged 1-d files
485Function/S GetNameFromHeader(fullName)
486        String fullName
487        String temp, newName = ""
488        Variable spc,ii=0
489       
490        //filename is 20 characters NNNNNxxx.SAn_NNN_NNN
491        //want the first 8 characters, NNNNNxxx, then strip off any spaces at the beginning
492        //NNNNN was entered as less than 5 characters
493        //returns a null string if no name can be found
494        do
495                temp = fullname[ii,7]           //characters ii,7 of the name
496                spc = strsearch(temp," ",0)
497                if (spc == -1)
498                        break           //no more spaces found
499                endif
500                ii+=1
501        While(ii<8)
502       
503        If(strlen(temp) < 1)
504                newName = ""            //be sure to return a null string if problem found
505        else
506                newName = temp
507        Endif
508       
509        Return(newName)
510End
511
512//list (input) is a list, typically returned from IndexedFile()
513//which is semicolon-delimited, and may contain filesnames from the VAX
514//that contain version numbers, where the version number appears as a separate list item
515//(and also as a non-existent file)
516//these numbers must be purged from the list, especially for display in a popup
517//or list processing of filenames
518//the function returns the list, cleaned of version numbers (up to 11)
519//raw data files will typically never have a version number other than 1.
520Function/S RemoveVersNumsFromList(list)
521        String list
522       
523        //get rid of version numbers first (up to 11)
524        Variable ii,num
525        String item
526        num = ItemsInList(list,";")
527        ii=1
528        do
529                item = num2str(ii)
530                list = RemoveFromList(item, list ,";" )
531                ii+=1
532        while(ii<12)
533       
534        return (list)
535End
536
537//input is a list of run numbers, and output is a list of filenames (not the full path)
538//*** input list must be COMMA delimited***
539//output is equivalent to selecting from the CAT table
540//if some or all of the list items are valid filenames, keep them...
541//if an error is encountered, notify of the offending element and return the null list
542//
543//output is COMMA delimited
544//
545// this routine is expecting that the "ask", "none" special cases are handled elsewhere
546//and not passed here
547Function/S ParseRunNumberList(list)
548        String list
549       
550        String newList="",item="",tempStr=""
551        Variable num,ii,runNum
552       
553        //expand number ranges, if any
554        list = ExpandNumRanges(list)
555       
556        num=itemsinlist(list,",")
557       
558        for(ii=0;ii<num;ii+=1)
559                //get the item
560                item = StringFromList(ii,list,",")
561                //is it already a valid filename?
562                tempStr=FindValidFilename(item) //returns filename if good, null if error
563                if(strlen(tempstr)!=0)
564                        //valid name, add to list
565                        //Print "it's a file"
566                        newList += tempStr + ","
567                else
568                        //not a valid name
569                        //is it a number?
570                        runNum=str2num(item)
571                        //print runnum
572                        if(numtype(runNum) != 0)
573                                //not a number -  maybe an error                       
574                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
575                                return("")
576                        else
577                                //a run number or an error
578                                tempStr = GetFileNameFromPathNoSemi( FindFileFromRunNumber(runNum) )
579                                if(strlen(tempstr)==0)
580                                        //file not found, error
581                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
582                                        return("")
583                                else
584                                        newList += tempStr + ","
585                                endif
586                        endif
587                endif
588        endfor          //loop over all items in list
589       
590        return(newList)
591End
592
593//takes a comma delimited list that MAY contain number range, and
594//expands any range of run numbers into a comma-delimited list...
595//and returns the new list - if not a range, return unchanged
596Function/S ExpandNumRanges(list)
597        String list
598       
599        String newList="",dash="-",item,str
600        Variable num,ii,hasDash
601       
602        num=itemsinlist(list,",")
603//      print num
604        for(ii=0;ii<num;ii+=1)
605                //get the item
606                item = StringFromList(ii,list,",")
607                //does it contain a dash?
608                hasDash = strsearch(item,dash,0)                //-1 if no dash found
609                if(hasDash == -1)
610                        //not a range, keep it in the list
611                        newList += item + ","
612                else
613                        //has a dash (so it's a range), expand (or add null)
614                        newList += ListFromDash(item)           
615                endif
616        endfor
617       
618        return newList
619End
620
621//be sure to add a trailing comma to the return string...
622Function/S ListFromDash(item)
623        String item
624       
625        String numList="",loStr="",hiStr=""
626        Variable lo,hi,ii
627       
628        loStr=StringFromList(0,item,"-")        //treat the range as a list
629        hiStr=StringFromList(1,item,"-")
630        lo=str2num(loStr)
631        hi=str2num(hiStr)
632        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
633                numList=""
634                return numList
635        endif
636        for(ii=lo;ii<=hi;ii+=1)
637                numList += num2str(ii) + ","
638        endfor
639       
640        Return numList
641End
642
643
644//****************
645//utilities for handling binary data - prompting for files or paths,
646//moving data from one folder to another (within IGOR)
647//and converting data to log or linear scale
648
649
650//prompts user to choose the local folder that contains the SANS Data
651//only one folder can be used, and its path is catPathName (and is a NAME, not a string)
652//this will overwrite the path selection
653//returns 1 if no path selected as error condition, or if user cancelled
654Function PickPath()
655       
656        //set the global string to the selected pathname
657        NewPath/O/M="pick the SANS data folder" catPathName
658        if(V_Flag != 0)
659                return(1)               //user cancelled
660        endif
661       
662        PathInfo/S catPathName
663        String dum = S_path
664        String alertStr = ""
665        alertStr = "You must set the path to Charlotte through a Mapped Network Drive, not through the Network Neighborhood"
666        //alertStr += "  Please see the manual for details."
667        if (V_flag == 0)
668                //path does not exist - no folder selected
669                String/G root:myGlobals:gCatPathStr = "no folder selected"
670                return(1)
671        else
672                //set the global to the path (as a string)
673                // need 4 \ since it is the escape character
674                if(cmpstr("\\\\",dum[0,1])==0)  //Windoze user going through network neighborhood
675                        DoAlert 0,alertStr
676                        KillPath catPathName
677                        return(1)
678                endif
679                String/G root:myGlobals:gCatPathStr = dum
680                // these are now set in theire respective procedures, since the folders don't exist yet!
681//              String/G root:myGlobals:Patch:gCatPathStr = dum //and the global used by Patch and Trans
682//              String/G root:myGlobals:TransHeaderInfo:gCatPathStr = dum       //and the global used by Patch and Trans
683                return(0)               //no error
684        endif
685End
686
687//a utility function that prompts the user for a file (of any type)
688//and returns the full path:name;vers string required to open the file
689//the file is NOT opened by this routine (/D flag)
690//a null string is returned if no file is selected
691//"msgStr" is the message displayed in the dialog, informing the user what
692//file is desired
693//
694Function/S PromptForPath(msgStr)
695        String msgStr
696        String fullPath
697        Variable refnum
698       
699        //this just asks for the filename, doesn't open the file
700        Open/D/R/T="????"/M=(msgStr) refNum
701        fullPath = S_FileName           //fname is the full path
702        //      Print refnum,fullPath
703       
704        //null string is returned in S_FileName if user cancelled, and is passed back to calling  function
705        Return(fullPath)
706End
707
708
709//returns a string containg the transmision stored in the file that is
710//currently in the "type" folder (not from the binary header)
711//returns "none" if the value (in RealsRead) cannot be found
712//
713Function/S GetTrans(type)
714        String type
715       
716        String name="root:"+type+":realsread"
717        WAVE reals = $name
718        if(waveExists(reals))
719                return(num2str(reals[4]))
720        else
721                return("none")
722        endif   
723End
724
725//returns a string containg the sample thickness stored in the file that is
726//currently in the "type" folder (not from the binary header)
727//returns "none" if the value (in RealsRead) cannot be found
728//
729Function/S GetThick(type)
730        String type
731       
732        String name="root:"+type+":realsread"
733        WAVE reals = $name
734        if(waveExists(reals))
735                return(num2str(reals[5]))
736        else
737                return("none")
738        endif   
739End
740
741//procedure is not called from anywhere, for debugging purposes only
742//not for gerneral users, since it Kills data folders, requiring
743//re-initialization of the experiment
744//
745Proc ClearWorkFolders()
746
747        //not foolproof - will generage an error if any wavs, etc.. are in use.
748        KillDataFolder root:RAW
749        KillDataFolder root:SAM
750        KillDataFolder root:EMP
751        KillDataFolder root:BGD
752        KillDataFolder root:COR
753        KillDataFolder root:DIV
754        KillDataFolder root:MSK
755        KillDataFolder root:ABS
756        KillDataFolder root:CAL
757        SetDataFolder root:
758       
759End
760
761//not used - but potentially very useful for ensuring that old
762// data in work folders is not accidentally being used
763//
764Function ClearWorkFolder(type)
765        String type
766       
767        SetDataFolder $("root:"+type)
768        KillWaves/A/Z
769        KillStrings/A/Z
770        KillVariables/A/Z
771       
772        SetDataFolder root:
773End
774
775
776//procedure is not called from anywhere, for debugging purposes only
777//not for gerneral users, but could be useful in reducon clutter
778//
779Proc ClearRootFolder()
780
781        DoAlert 1,"Are you sure you want to delete everything from the root level?"
782        SetDataFolder root:
783        KillWaves/A/Z
784        KillStrings/A/Z
785        KillVariables/A/Z
786       
787End
788
789///*****************
790//unused testing procedure for writing a 4 byte floating point value in VAX format
791Proc TestReWriteReal()
792        String Path
793        Variable value,start
794       
795        GetFileAndPath()
796        Path = S_Path + S_filename
797       
798        value = 0.2222
799        start = 158             //trans starts at byte 159
800        ReWriteReal(path,value,start)
801       
802        SetDataFolder root:
803End
804
805//function will re-write a real value (4bytes) to the header of a RAW data file
806//to ensure re-readability, the real value must be written mimicking VAX binary format
807//which is done in this function
808//path is the full path:file;vers to the file
809//value is the real value to write
810//start is the position to move the file marker to, to begin writing
811//--so start is actually the "end byte" of the previous value
812//
813//this procedure takes care of all file open/close pairs needed
814//
815Function ReWriteReal(path,value,start)
816        String path
817        Variable value,start
818       
819        //Print " in F(), path = " + path
820        Variable refnum,int1,int2, value4
821
822//////
823        value4 = 4*value
824       
825        Open/A/T="????TEXT" refnum as path
826        //write IEEE FP, 4*desired value
827        FSetPos refnum,start
828        FBinWrite/B=3/F=4 refnum,value4         //write out as little endian
829       
830        //move to the end of the file
831        FStatus refnum
832        FSetPos refnum,V_logEOF
833        //Print "Wrote end of header to " + num2str(V_filePOS)
834       
835        Close refnum
836       
837///////
838        Open/R refnum as path
839        //read back as two 16-bit integers
840        FSetPos refnum,start
841        FBinRead/B=2/F=2 refnum,int1    //read as big-endian
842        FBinRead/B=2/F=2 refnum,int2
843       
844        //file was opened read-only
845        //no need to move to the end of the file, just close it
846       
847        Close refnum
848///////
849        Open/A/T="????TEXT" refnum as path
850        //write the two 16-bit integers, reversed
851        FSetPos refnum,start
852        FBinWrite/B=2/F=2 refnum,int2   //re-write as big endian
853        FBinWrite/B=2/F=2 refnum,int1
854       
855        //move to the end of the file
856        FStatus refnum
857        FSetPos refnum,V_logEOF
858        //Print "Wrote end of header to " + num2str(V_filePOS)
859       
860        Close refnum                            //at this point, it is as the VAX would have written it.
861       
862        Return(0)
863End
864
865//Utility function that returns the detector resolution (in cm) given information
866//from the file header
867//Global values are set in the Initialize procedure
868Function DetectorPixelResolution(fileStr,detStr)
869        String fileStr,detStr
870       
871        Variable DDet
872        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
873       
874        NVAR PixelResNG3_ILL = root:myGlobals:PixelResNG3_ILL           //pixel resolution in cm
875        NVAR PixelResNG5_ILL = root:myGlobals:PixelResNG5_ILL
876        NVAR PixelResNG7_ILL = root:myGlobals:PixelResNG7_ILL
877        NVAR PixelResNG3_ORNL = root:myGlobals:PixelResNG3_ORNL
878        NVAR PixelResNG5_ORNL = root:myGlobals:PixelResNG5_ORNL
879        NVAR PixelResNG7_ORNL = root:myGlobals:PixelResNG7_ORNL
880        NVAR PixelResDefault = root:myGlobals:PixelResDefault
881       
882        strswitch(instr)
883                case "NG3":
884                        if(cmpstr(detStr, "ILL   ") == 0 )
885                                DDet= PixelResNG3_ILL
886                        else
887                                DDet = PixelResNG3_ORNL //detector is ordella-type
888                        endif
889                        break
890                case "NG5":
891                        if(cmpstr(detStr, "ILL   ") == 0 )
892                                DDet= PixelResNG5_ILL
893                        else
894                                DDet = PixelResNG5_ORNL //detector is ordella-type
895                        endif
896                        break
897                case "NG7":
898                        if(cmpstr(detStr, "ILL   ") == 0 )
899                                DDet= PixelResNG7_ILL
900                        else
901                                DDet = PixelResNG7_ORNL //detector is ordella-type
902                        endif
903                        break
904                default:                                                       
905                        //return error?
906                        DDet = PixelResDefault  //5mm, typical for new ORNL detectors
907        endswitch
908       
909        return(DDet)
910End
911
912//Utility function that returns the detector deadtime (in seconds) given information
913//from the file header
914//Global values are set in the Initialize procedure
915Function DetectorDeadtime(fileStr,detStr)
916        String fileStr,detStr
917       
918        Variable deadtime
919        String instr=fileStr[1,3]       //filestr is "[NGnSANSn] " or "[NGnSANSnn]" (11 characters total)
920       
921        NVAR DeadtimeNG3_ILL = root:myGlobals:DeadtimeNG3_ILL           //pixel resolution in cm
922        NVAR DeadtimeNG5_ILL = root:myGlobals:DeadtimeNG5_ILL
923        NVAR DeadtimeNG7_ILL = root:myGlobals:DeadtimeNG7_ILL
924        NVAR DeadtimeNG3_ORNL = root:myGlobals:DeadtimeNG3_ORNL
925        NVAR DeadtimeNG5_ORNL = root:myGlobals:DeadtimeNG5_ORNL
926        NVAR DeadtimeNG7_ORNL = root:myGlobals:DeadtimeNG7_ORNL
927        NVAR DeadtimeDefault = root:myGlobals:DeadtimeDefault
928       
929        strswitch(instr)
930                case "NG3":
931                        if(cmpstr(detStr, "ILL   ") == 0 )
932                                deadtime= DeadtimeNG3_ILL
933                        else
934                                deadtime = DeadtimeNG3_ORNL     //detector is ordella-type
935                        endif
936                        break
937                case "NG5":
938                        if(cmpstr(detStr, "ILL   ") == 0 )
939                                deadtime= DeadtimeNG5_ILL
940                        else
941                                deadtime = DeadtimeNG5_ORNL     //detector is ordella-type
942                        endif
943                        break
944                case "NG7":
945                        if(cmpstr(detStr, "ILL   ") == 0 )
946                                deadtime= DeadtimeNG7_ILL
947                        else
948                                deadtime = DeadtimeNG7_ORNL     //detector is ordella-type
949                        endif
950                        break
951                default:                                                       
952                        //return error?
953                        deadtime = DeadtimeDefault      //1e-6 seconds, typical for new ORNL detectors
954        endswitch
955       
956        return(deadtime)
957End
958
959//////////////////////
960// "intelligent" differentiation of the data files based on information gathered while
961// getting the FIle Catalog. Uses some waves that are generated there, but not displayed in the table
962//
963// See CatVSTable.ipf for where these files are created (and sorted to keep them together)
964////////////
965
966//testing - unused
967//
968Function/S TextWave2SemiList(textW)
969        Wave/T textW
970       
971        String list=""
972        Variable num=numpnts(textW),ii=0
973        do
974                list += textw[ii] + ";"
975                ii+=1
976        while(ii<num)
977        return(list)
978End
979
980Function/S NumWave2CommaList(numW)
981        Wave numW
982       
983        String list=""
984        Variable num=numpnts(numW),ii=0
985        do
986                list += num2Str(numW[ii]) + ","
987                ii+=1
988        while(ii<num)
989        return(list)
990End
991
992// utility function to convert a list (string) of semicolon-delimited
993//items to a text wave
994Function List2TextWave(str,tw)
995        String str
996        wave/T tw
997       
998        Variable num=ItemsinList(str,";"),ii=0
999        Redimension/N=(num) tw
1000        do
1001                tw[ii] = StringFromList(ii, str ,";")
1002                ii+=1
1003        while(ii<num)
1004        return(0)
1005       
1006End
1007
1008// generates a list of the procedure files in the experiment
1009// putting the results in a wave named "tw", editing and sorting the wave
1010//
1011Proc ListIncludedFiles()
1012        Make/O/T/N=2 tw
1013        String str=""
1014        //str = WinList("*", ";","INCLUDE:6")
1015        str = WinList("*", ";","WIN:128")
1016        List2TextWave(str,tw)
1017        Edit tw
1018        Sort tw tw
1019End
1020
1021// returns a comma delimited list of run numbers based on the run numbers collected
1022// during the building of the File Catalog (why do it twice)
1023Function/S RunNumberList()
1024
1025        Wave w= $"root:myGlobals:CatVSHeaderInfo:RunNumber"
1026        String list=""
1027        if(WaveExists(w) == 0)
1028                list = ""
1029        else
1030                list=NumWave2CommaList(w)
1031        endif
1032        return(list)
1033End
1034
1035// list is a comma delimited list of run numbers, from the File Catalog
1036// - scan through the list and remove numbers that are not transmission files
1037//
1038Function/S isTransList(list)
1039        String list
1040       
1041        //scan through the list, find the corresponding point number, and see what isTrans says
1042        Variable ii,num,temp
1043        String newList=""
1044        num=ItemsInList(list ,",")
1045        for(ii=0;ii<num;ii+=1)
1046                temp = str2num( StringFromList(ii, list ,",") )
1047                if(RunNumIsTransFile(temp))
1048                        newList += num2str(temp) + ","
1049                endif
1050        endfor
1051       
1052        return(newList)
1053End
1054
1055//truth if run number is a transmission file
1056// based on whatever is currently in the File Catalog
1057//
1058// Can't use findlevel - it assumes a monotonic RunNumber wave
1059Function RunNumIsTransFile(num)
1060        Variable num
1061       
1062        Wave isTrans = $"root:myGlobals:CatVSHeaderInfo:IsTrans"
1063        Wave RunNumber = $"root:myGlobals:CatVSHeaderInfo:RunNumber"
1064       
1065        if( (WaveExists(isTrans) == 0 ) ||  (WaveExists(RunNumber) == 0 ) )
1066                return(0)
1067        endif
1068       
1069        Variable pts=numpnts(RunNumber),ii
1070        for(ii=0;ii<pts;ii+=1)
1071                if(RunNumber[ii] == num)
1072                        return(isTrans[ii])
1073                endif
1074        endfor
1075//      FindLevel/P/Q RunNumber,num
1076//
1077//      if(isTrans[V_LevelX]==1)
1078//              return(1)
1079//      else
1080//              return(0)
1081//      endif
1082End
1083
1084//truth if run number is at the given sample to detector distance
1085// based on whatever is currently in the File Catalog
1086//
1087// need fuzzy comparison, since SDD = 1.33 may actually be represented in FP as 1.33000004      !!!
1088Function RunNumIsAtSDD(num,sdd)
1089        Variable num,sdd
1090       
1091        Wave w = $"root:myGlobals:CatVSHeaderInfo:SDD"
1092        Wave RunNumber = $"root:myGlobals:CatVSHeaderInfo:RunNumber"
1093       
1094        if( (WaveExists(w) == 0 ) ||  (WaveExists(RunNumber) == 0 ) )
1095                return(0)
1096        endif
1097        Variable pts=numpnts(RunNumber),ii
1098        for(ii=0;ii<pts;ii+=1)
1099                if(RunNumber[ii] == num)
1100                        if(abs(w[ii] - sdd) < 0.001     )               //if numerically within 0.001 meter, they're the same
1101                                return(1)
1102                        else
1103                                return(0)
1104                        endif
1105                endif
1106        endfor
1107End
1108
1109
1110// list is a comma delimited list of run numbers, from the File Catalog
1111// - scan through the list and remove numbers that are not at the specified SDD
1112//
1113Function/S atSDDList(list,sdd)
1114        String list
1115        Variable sdd
1116       
1117        //scan through the list, find the corresponding point number, and see what SDD the run is at
1118        Variable ii,num,temp
1119        String newList=""
1120        num=ItemsInList(list ,",")
1121        for(ii=0;ii<num;ii+=1)
1122                temp = str2num( StringFromList(ii, list ,",") )
1123                if(RunNumIsAtSDD(temp,sdd))
1124                        newList += num2str(temp) + ","
1125                endif
1126        endfor
1127       
1128        return(newList)
1129End
1130
1131//given a comma-delimited list, remove those that are trans files
1132//
1133Function/S removeTrans(list)
1134        String list
1135       
1136        //scan through the list, and remove those that are trans files
1137        Variable ii,num,temp
1138//      String newList=""
1139        num=ItemsInList(list ,",")
1140        for(ii=0;ii<num;ii+=1)
1141                temp = str2num( StringFromList(ii, list ,",") )
1142                if(RunNumIsTransFile(temp))
1143                        list = RemoveFromList(num2str(temp),list,",")
1144                        ii -= 1                 //item ii was just deleted (everything moves to fill in)
1145                        num -= 1                // and the list is shorter now
1146                endif
1147        endfor
1148       
1149        return(list)
1150End
1151
1152Function setMREDFileList(str)
1153        String str
1154       
1155        SVAR/Z list = root:myGlobals:MRED:gFileNumList
1156        if(SVAR_Exists(list)==0)                //check for myself
1157                DoAlert 0,"The Multiple Reduce Panel must be open for you to use this function"
1158                Return(1)
1159        endif
1160       
1161        list = str
1162       
1163        //force an update If the SVAR exists, then the panel does too - MRED cleans up after itself when done
1164        DoWindow/F Multiple_Reduce_Panel                        //bring to front
1165        MRedPopMenuProc("MRFilesPopup",0,"")            //parse the list, pop the menu
1166       
1167        return(0)
1168End
1169
1170Proc FillEMPUsingSelection()
1171        FillEMPFilenameWSelection()
1172End
1173
1174Proc GuessEveryTransFiles(num)
1175        Variable num=6
1176        GuessAllTransFiles(num)
1177End
1178
1179Proc GuessSelectedTransFiles(num)
1180        Variable num=6
1181        fGuessSelectedTransFiles(num)
1182End
1183
1184Proc ClearSelectedTransAssignments()
1185        ClearSelectedAssignments()
1186End
1187
1188Proc CreateRunNumList()
1189        String/G rStr=""
1190        rStr=RunNumberList()
1191        Print "The list is stored in root:rStr"
1192        print rStr
1193End
1194
1195Proc TransList()
1196        String/G rStr=""
1197        rStr=RunNumberList()
1198        rStr=isTransList(rStr)
1199        print rStr
1200End
1201
1202Proc ScatteringAtSDDList(sdd)
1203        Variable sdd=13
1204       
1205        String/G rStr=""
1206        rStr=RunNumberList()
1207        rStr=removeTrans(rStr)
1208        rStr=atSDDList(rStr,sdd)
1209       
1210        //for Igor 4, the search is case-sensitive, so use all permutations
1211        // in Igor 5, use the proper flag in strsearch() inside FindStringInLabel()
1212        rStr = RemoveEmptyBlocked(rStr,"EMPTY")
1213        rStr = RemoveEmptyBlocked(rStr,"Empty")
1214        rStr = RemoveEmptyBlocked(rStr,"empty")
1215        rStr = RemoveEmptyBlocked(rStr,"MT Cell")
1216        rStr = RemoveEmptyBlocked(rStr,"MT CELL")
1217        rStr = RemoveEmptyBlocked(rStr,"mt cell")
1218        rStr = RemoveEmptyBlocked(rStr,"BLOCKED")
1219        rStr = RemoveEmptyBlocked(rStr,"Blocked")
1220        rStr = RemoveEmptyBlocked(rStr,"blocked")
1221       
1222        print rStr
1223End
1224
1225Proc FillMREDList()
1226        setMREDFileList(rStr)
1227        DoUpdate
1228End
1229
1230//num passed in is the run number, as in the list
1231// ii is the index of all of the files from the catalog
1232//return will be -1 if string not found, >=0 if found
1233//
1234Function FindStringInLabel(num,findThisStr)
1235        Variable num
1236        String findThisStr
1237       
1238        Wave/T w = $"root:myGlobals:CatVSHeaderInfo:Labels"
1239        Wave RunNumber = $"root:myGlobals:CatVSHeaderInfo:RunNumber"
1240       
1241        if( (WaveExists(w) == 0 ) ||  (WaveExists(RunNumber) == 0 ) )
1242                return(0)
1243        endif
1244       
1245        Variable pts=numpnts(RunNumber),ii,loc
1246        for(ii=0;ii<pts;ii+=1)
1247                if(RunNumber[ii] == num)
1248                        loc = strsearch(w[ii], findThisStr, 0)                  //Igor 4 version is case-sensitive
1249//                      loc = strsearch(w[ii], findThisStr, 0 ,2)               //2==case insensitive, but Igor 5 specific
1250                        if(loc != -1)
1251                                Print "Remove w[ii] = ",num,"  ",w[ii]
1252                        endif
1253                endif
1254        endfor
1255       
1256        return(loc)             //return will be -1 if string not found, >=0 if found
1257end
1258
1259//rStr is the global string, already atSDD (so there should be only one instance of
1260// empty and one instance of blocked
1261//
1262//scan through the list, and remove those that are have "empty" or "blocked" in the label
1263// or anything that is listed in StrToFind
1264//
1265Function/S RemoveEmptyBlocked(list,StrToFind)
1266        String list,StrToFind
1267       
1268        Variable ii,num,temp
1269        num=ItemsInList(list ,",")
1270        for(ii=0;ii<num;ii+=1)
1271                temp = str2num( StringFromList(ii, list ,",") )
1272                if(FindStringInLabel(temp,StrToFind) != -1)
1273                        list = RemoveFromList(num2str(temp),list,",")
1274                        ii -= 1                 //item ii was just deleted (everything moves to fill in)
1275                        num -= 1                // and the list is shorter now
1276                endif
1277        endfor
1278        //print list
1279        return(list)
1280end
1281
1282// input is a single run number to remove from the list
1283//  - typically EC and BN - before sending to MRED
1284Proc RemoveRunFromList(remList)
1285        String remList=""
1286         
1287        rStr = RemoveFromList(remList, rStr ,",")
1288end
Note: See TracBrowser for help on using the repository browser.