source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/SANS_Utilities.ipf @ 575

Last change on this file since 575 was 570, checked in by srkline, 13 years ago

Change (1):
In preparation for release, updated pragma IgorVersion?=6.1 in all procedures

Change (2):
As a side benefit of requiring 6.1, we can use the MultiThread? keyword to thread any model function we like. The speed benefit is only noticeable on functions that require at least one integration and at least 100 points (resolution smearing is NOT threaded, too many threadSafe issues, too little benefit). I have chosen to use the MultiThread? only on the XOP assignment. In the Igor code there are too many functions that are not explicitly declared threadsafe, making for a mess.

File size: 14.5 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
4
5// contains general utility procedures for:
6// file open dialogs
7// paths
8// lists to waves (and the reverse)
9//
10// and BETA procedures for:
11// generating MRED lists
12// guessing of transmission file assignments
13//
14// - these files may or may not be NCNR-specific. They may eventually
15// need to be moved into NCNR_Utils, or to more appropriate locations
16//
17//
18// 29MAR07 SRK
19//
20
21
22//////////////////////
23// "intelligent" differentiation of the data files based on information gathered while
24// getting the FIle Catalog. Uses some waves that are generated there, but not displayed in the table
25//
26// See CatVSTable.ipf for where these files are created (and sorted to keep them together)
27////////////
28
29//testing - unused
30//
31Function/S TextWave2SemiList(textW)
32        Wave/T textW
33       
34        String list=""
35        Variable num=numpnts(textW),ii=0
36        do
37                list += textw[ii] + ";"
38                ii+=1
39        while(ii<num)
40        return(list)
41End
42
43Function/S NumWave2CommaList(numW)
44        Wave numW
45       
46        String list=""
47        Variable num=numpnts(numW),ii=0
48        do
49                list += num2Str(numW[ii]) + ","
50                ii+=1
51        while(ii<num)
52        return(list)
53End
54
55// utility function to convert a list (string) of semicolon-delimited
56//items to a text wave
57Function List2TextWave(str,tw)
58        String str
59        wave/T tw
60       
61        Variable num=ItemsinList(str,";"),ii=0
62        Redimension/N=(num) tw
63        do
64                tw[ii] = StringFromList(ii, str ,";")
65                ii+=1
66        while(ii<num)
67        return(0)
68       
69End
70
71// generates a list of the procedure files in the experiment
72// putting the results in a wave named "tw", editing and sorting the wave
73//
74Proc ListIncludedFiles()
75        Make/O/T/N=2 tw
76        String str=""
77        //str = WinList("*", ";","INCLUDE:6")
78        str = WinList("*", ";","WIN:128")
79        List2TextWave(str,tw)
80        Edit tw
81        Sort tw tw
82End
83
84// returns a comma delimited list of run numbers based on the run numbers collected
85// during the building of the File Catalog (why do it twice)
86Function/S RunNumberList()
87
88        Wave w= $"root:myGlobals:CatVSHeaderInfo:RunNumber"
89        String list=""
90        if(WaveExists(w) == 0)
91                list = ""
92        else
93                list=NumWave2CommaList(w)
94        endif
95        return(list)
96End
97
98// list is a comma delimited list of run numbers, from the File Catalog
99// - scan through the list and remove numbers that are not transmission files
100//
101Function/S isTransList(list)
102        String list
103       
104        //scan through the list, find the corresponding point number, and see what isTrans says
105        Variable ii,num,temp
106        String newList=""
107        num=ItemsInList(list ,",")
108        for(ii=0;ii<num;ii+=1)
109                temp = str2num( StringFromList(ii, list ,",") )
110                if(RunNumIsTransFile(temp))
111                        newList += num2str(temp) + ","
112                endif
113        endfor
114       
115        return(newList)
116End
117
118//truth if run number is a transmission file
119// based on whatever is currently in the File Catalog
120//
121// Can't use findlevel - it assumes a monotonic RunNumber wave
122Function RunNumIsTransFile(num)
123        Variable num
124       
125        Wave isTrans = $"root:myGlobals:CatVSHeaderInfo:IsTrans"
126        Wave RunNumber = $"root:myGlobals:CatVSHeaderInfo:RunNumber"
127       
128        if( (WaveExists(isTrans) == 0 ) ||  (WaveExists(RunNumber) == 0 ) )
129                return(0)
130        endif
131       
132        Variable pts=numpnts(RunNumber),ii
133        for(ii=0;ii<pts;ii+=1)
134                if(RunNumber[ii] == num)
135                        return(isTrans[ii])
136                endif
137        endfor
138//      FindLevel/P/Q RunNumber,num
139//
140//      if(isTrans[V_LevelX]==1)
141//              return(1)
142//      else
143//              return(0)
144//      endif
145End
146
147//truth if run number is at the given sample to detector distance
148// based on whatever is currently in the File Catalog
149//
150// need fuzzy comparison, since SDD = 1.33 may actually be represented in FP as 1.33000004      !!!
151Function RunNumIsAtSDD(num,sdd)
152        Variable num,sdd
153       
154        Wave w = $"root:myGlobals:CatVSHeaderInfo:SDD"
155        Wave RunNumber = $"root:myGlobals:CatVSHeaderInfo:RunNumber"
156       
157        if( (WaveExists(w) == 0 ) ||  (WaveExists(RunNumber) == 0 ) )
158                return(0)
159        endif
160        Variable pts=numpnts(RunNumber),ii
161        for(ii=0;ii<pts;ii+=1)
162                if(RunNumber[ii] == num)
163                        if(abs(w[ii] - sdd) < 0.001     )               //if numerically within 0.001 meter, they're the same
164                                return(1)
165                        else
166                                return(0)
167                        endif
168                endif
169        endfor
170End
171
172
173// list is a comma delimited list of run numbers, from the File Catalog
174// - scan through the list and remove numbers that are not at the specified SDD
175//
176Function/S atSDDList(list,sdd)
177        String list
178        Variable sdd
179       
180        //scan through the list, find the corresponding point number, and see what SDD the run is at
181        Variable ii,num,temp
182        String newList=""
183        num=ItemsInList(list ,",")
184        for(ii=0;ii<num;ii+=1)
185                temp = str2num( StringFromList(ii, list ,",") )
186                if(RunNumIsAtSDD(temp,sdd))
187                        newList += num2str(temp) + ","
188                endif
189        endfor
190       
191        return(newList)
192End
193
194//given a comma-delimited list, remove those that are trans files
195//
196Function/S removeTrans(list)
197        String list
198       
199        //scan through the list, and remove those that are trans files
200        Variable ii,num,temp
201//      String newList=""
202        num=ItemsInList(list ,",")
203        for(ii=0;ii<num;ii+=1)
204                temp = str2num( StringFromList(ii, list ,",") )
205                if(RunNumIsTransFile(temp))
206                        list = RemoveFromList(num2str(temp),list,",")
207                        ii -= 1                 //item ii was just deleted (everything moves to fill in)
208                        num -= 1                // and the list is shorter now
209                endif
210        endfor
211       
212        return(list)
213End
214
215Function setMREDFileList(str)
216        String str
217       
218        SVAR/Z list = root:myGlobals:MRED:gFileNumList
219        if(SVAR_Exists(list)==0)                //check for myself
220                DoAlert 0,"The Multiple Reduce Panel must be open for you to use this function"
221                Return(1)
222        endif
223       
224        list = str
225       
226        //force an update If the SVAR exists, then the panel does too - MRED cleans up after itself when done
227        DoWindow/F Multiple_Reduce_Panel                        //bring to front
228        MRedPopMenuProc("MRFilesPopup",0,"")            //parse the list, pop the menu
229       
230        return(0)
231End
232
233Proc FillEMPUsingSelection()
234        FillEMPFilenameWSelection()
235End
236
237Proc GuessEveryTransFile(num)
238        Variable num=6
239        GuessAllTransFiles(num)
240End
241
242Proc GuessSelectedTransFiles(num)
243        Variable num=6
244        fGuessSelectedTransFiles(num)
245End
246
247Proc ClearSelectedTransAssignments()
248        ClearSelectedAssignments()
249End
250
251Proc CreateRunNumList()
252        String/G rStr=""
253        rStr=RunNumberList()
254        Print "The list is stored in root:rStr"
255        print rStr
256End
257
258Proc TransList()
259        String/G rStr=""
260        rStr=RunNumberList()
261        rStr=isTransList(rStr)
262        print rStr
263End
264
265Proc ScatteringAtSDDList(sdd)
266        Variable sdd=13
267       
268        String/G rStr=""
269        rStr=RunNumberList()
270        rStr=removeTrans(rStr)
271        rStr=atSDDList(rStr,sdd)
272       
273        //for Igor 4, the search is case-sensitive, so use all permutations
274        // in Igor 5, use the proper flag in strsearch() inside FindStringInLabel()
275        rStr = RemoveEmptyBlocked(rStr,"EMPTY")
276//      rStr = RemoveEmptyBlocked(rStr,"Empty")
277//      rStr = RemoveEmptyBlocked(rStr,"empty")
278//      rStr = RemoveEmptyBlocked(rStr,"MT Cell")
279        rStr = RemoveEmptyBlocked(rStr,"MT CELL")
280//      rStr = RemoveEmptyBlocked(rStr,"mt cell")
281        rStr = RemoveEmptyBlocked(rStr,"BLOCKED")
282//      rStr = RemoveEmptyBlocked(rStr,"Blocked")
283//      rStr = RemoveEmptyBlocked(rStr,"blocked")
284       
285        print rStr
286End
287
288Proc FillMREDList()
289        setMREDFileList(rStr)
290        DoUpdate
291End
292
293//num passed in is the run number, as in the list
294// ii is the index of all of the files from the catalog
295//return will be -1 if string not found, >=0 if found
296//
297Function FindStringInLabel(num,findThisStr)
298        Variable num
299        String findThisStr
300       
301        Wave/T w = $"root:myGlobals:CatVSHeaderInfo:Labels"
302        Wave RunNumber = $"root:myGlobals:CatVSHeaderInfo:RunNumber"
303       
304        if( (WaveExists(w) == 0 ) ||  (WaveExists(RunNumber) == 0 ) )
305                return(0)
306        endif
307       
308        Variable pts=numpnts(RunNumber),ii,loc
309        for(ii=0;ii<pts;ii+=1)
310                if(RunNumber[ii] == num)
311//                      loc = strsearch(w[ii], findThisStr, 0)                  //Igor 4 version is case-sensitive
312                        loc = strsearch(w[ii], findThisStr, 0 ,2)               //2==case insensitive, but Igor 5 specific
313                        if(loc != -1)
314                                Print "Remove w[ii] = ",num,"  ",w[ii]
315                        endif
316                endif
317        endfor
318       
319        return(loc)             //return will be -1 if string not found, >=0 if found
320end
321
322//rStr is the global string, already atSDD (so there should be only one instance of
323// empty and one instance of blocked
324//
325//scan through the list, and remove those that are have "empty" or "blocked" in the label
326// or anything that is listed in StrToFind
327//
328Function/S RemoveEmptyBlocked(list,StrToFind)
329        String list,StrToFind
330       
331        Variable ii,num,temp
332        num=ItemsInList(list ,",")
333        for(ii=0;ii<num;ii+=1)
334                temp = str2num( StringFromList(ii, list ,",") )
335                if(FindStringInLabel(temp,StrToFind) != -1)
336                        list = RemoveFromList(num2str(temp),list,",")
337                        ii -= 1                 //item ii was just deleted (everything moves to fill in)
338                        num -= 1                // and the list is shorter now
339                endif
340        endfor
341        //print list
342        return(list)
343end
344
345// input is a single run number to remove from the list
346//  - typically EC and BN - before sending to MRED
347Proc RemoveRunFromList(remList)
348        String remList=""
349         
350        rStr = RemoveFromList(remList, rStr ,",")
351end
352
353
354//////////general folder utilities
355
356//prompts user to choose the local folder that contains the SANS Data
357//only one folder can be used, and its path is catPathName (and is a NAME, not a string)
358//this will overwrite the path selection
359//returns 1 if no path selected as error condition, or if user cancelled
360Function PickPath()
361       
362        //set the global string to the selected pathname
363        NewPath/O/M="pick the SANS data folder" catPathName
364        if(V_Flag != 0)
365                return(1)               //user cancelled
366        endif
367       
368        PathInfo/S catPathName
369        String dum = S_path
370        String alertStr = ""
371        alertStr = "You must set the path to Charlotte through a Mapped Network Drive, not through the Network Neighborhood"
372        //alertStr += "  Please see the manual for details."
373        if (V_flag == 0)
374                //path does not exist - no folder selected
375                String/G root:myGlobals:gCatPathStr = "no folder selected"
376                return(1)
377        else
378                //set the global to the path (as a string)
379                // need 4 \ since it is the escape character
380                if(cmpstr("\\\\",dum[0,1])==0)  //Windoze user going through network neighborhood
381                        DoAlert 0,alertStr
382                        KillPath catPathName
383                        return(1)
384                endif
385                String/G root:myGlobals:gCatPathStr = dum
386                // these are now set in theire respective procedures, since the folders don't exist yet!
387//              String/G root:myGlobals:Patch:gCatPathStr = dum //and the global used by Patch and Trans
388//              String/G root:myGlobals:TransHeaderInfo:gCatPathStr = dum       //and the global used by Patch and Trans
389                return(0)               //no error
390        endif
391End
392
393//a utility function that prompts the user for a file (of any type)
394//and returns the full path:name;vers string required to open the file
395//the file is NOT opened by this routine (/D flag)
396//a null string is returned if no file is selected
397//"msgStr" is the message displayed in the dialog, informing the user what
398//file is desired
399//
400Function/S PromptForPath(msgStr)
401        String msgStr
402        String fullPath
403        Variable refnum
404       
405        //this just asks for the filename, doesn't open the file
406        Open/D/R/T="????"/M=(msgStr) refNum
407        fullPath = S_FileName           //fname is the full path
408        //      Print refnum,fullPath
409       
410        //null string is returned in S_FileName if user cancelled, and is passed back to calling  function
411        Return(fullPath)
412End
413
414
415
416//procedure is not called from anywhere, for debugging purposes only
417//not for gerneral users, since it Kills data folders, requiring
418//re-initialization of the experiment
419//
420Proc ClearWorkFolders()
421
422        //not foolproof - will generage an error if any wavs, etc.. are in use.
423        KillDataFolder root:Packages:NIST:RAW
424        KillDataFolder root:Packages:NIST:SAM
425        KillDataFolder root:Packages:NIST:EMP
426        KillDataFolder root:Packages:NIST:BGD
427        KillDataFolder root:Packages:NIST:COR
428        KillDataFolder root:Packages:NIST:DIV
429        KillDataFolder root:Packages:NIST:MSK
430        KillDataFolder root:Packages:NIST:ABS
431        KillDataFolder root:Packages:NIST:CAL
432        SetDataFolder root:
433       
434End
435
436//not used - but potentially very useful for ensuring that old
437// data in work folders is not accidentally being used
438//
439Function ClearWorkFolder(type)
440        String type
441       
442        SetDataFolder $("root:Packages:NIST:"+type)
443        KillWaves/A/Z
444        KillStrings/A/Z
445        KillVariables/A/Z
446       
447        SetDataFolder root:
448End
449
450
451//procedure is not called from anywhere, for debugging purposes only
452//not for gerneral users, but could be useful in reducon clutter
453//
454Proc ClearRootFolder()
455
456        DoAlert 1,"Are you sure you want to delete everything from the root level?"
457        SetDataFolder root:
458        KillWaves/A/Z
459        KillStrings/A/Z
460        KillVariables/A/Z
461       
462End
463
464/////////string matching
465
466
467//the following is a WaveMetrics procedure from <StrMatchList>
468// MatchList(matchStr,list,sep)
469// Returns the items of the list whose items match matchStr
470// The lists are separated by the sep character, usually ";"
471//
472// matchStr may be something like "abc", in which case it is identical to CmpStr
473// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
474//      "*abc" to match anything ending with "abc".
475// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
476//      the pattern.
477// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
478//
479Function/S MyMatchList(matchStr,list,sep)
480        String matchStr,list,sep
481        String item,outList=""
482        Variable n=strlen(list)
483        Variable en,st=0
484        do
485                en= strsearch(list,sep,st)
486                if( en < 0 )
487                        if( st < n-1 )
488                                en= n   // no trailing separator
489                                sep=""  // don't put sep in output, either
490                        else
491                                break   // no more items in list
492                        endif
493                endif
494                item=list[st,en-1]
495                if( MyStrMatch(matchStr,item) == 0 )
496                        outlist += item+sep
497                Endif
498                st=en+1
499        while (st < n ) // exit is by break, above
500        return outlist
501End
502
503//the following is a WaveMetrics procedure from <StrMatchList>
504// StrMatch(matchStr,str)
505// Returns 0 if the pattern in matchStr matches str, else it returns 1
506//
507// matchStr may be something like "abc", in which case it is identical to CmpStr
508// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
509//      "*abc" to match anything ending with "abc".
510// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
511//      the pattern.
512// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
513//
514Function MyStrMatch(matchStr,str)
515        String matchStr,str
516        Variable match = 1              // 0 means match
517        Variable invert= strsearch(matchStr,"!",0) == 0
518        if( invert )
519                matchStr[0,0]=""        // remove the "!"
520        endif
521        Variable st=0,en=strlen(str)-1
522        Variable starPos= strsearch(matchStr,"*",0)
523        if( starPos >= 0 )      // have a star
524                if( starPos == 0 )      // at start
525                        matchStr[0,0]=""                                // remove star at start
526                else                                    // at end
527                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
528                endif
529                Variable len=strlen(matchStr)
530                if( len > 0 )
531                        if(starPos == 0)        // star at start, match must be at end
532                                st=en-len+1
533                        else
534                                en=len-1        // star at end, match at start
535                        endif
536                else
537                        str=""  // so that "*" matches anything
538                endif
539        endif
540        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
541        if( invert )
542                match= 1-match
543        endif
544        return match
545End
Note: See TracBrowser for help on using the repository browser.