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

Last change on this file since 890 was 886, checked in by srkline, 10 years ago

Changes to SASCALC and other locations in the code that identify the instrument from the account name that is stored in the file header. New designation of NGA for the 10-m SANS, and NGB is reserved for the NG3 30-m SANS when it is moved into the new guide hall. Changes to incorporate the 10m SANS are functional, but INCOMPLETE since many of the instrument details have not been filled in yet (they haven't been measured yet).

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