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

Last change on this file since 1241 was 1241, checked in by srkline, 3 years ago

fix in VSANS transmission to name the panel when updating popup controls

addition to SANS event mode to speedup the non-XOP event file loader. old veriosn was 28x slower than the xop. this version is now only about 5x slower. Still not great, but tolerable if the XOP is not present (macOS notarization issues)

File size: 15.4 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 root:tictoc = startMSTimer
29end
30 
31function toc()
32        NVAR/Z tictoc = root: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
257
258
259// for testing, not used anymore
260//Proc FillMREDList()
261//      setMREDFileList(rStr)
262//      DoUpdate
263//End
264
265//Function setMREDFileList(str)
266//      String str
267//     
268//      SVAR/Z list = root:myGlobals:MRED:gFileNumList
269//      if(SVAR_Exists(list)==0)                //check for myself
270//              DoAlert 0,"The Multiple Reduce Panel must be open for you to use this function"
271//              Return(1)
272//      endif
273//     
274//      list = str
275//     
276//      //force an update If the SVAR exists, then the panel does too - MRED cleans up after itself when done
277//      DoWindow/F Multiple_Reduce_Panel                        //bring to front
278//      MRedPopMenuProc("MRFilesPopup",0,"")            //parse the list, pop the menu
279//     
280//      return(0)
281//End
282
283Proc FillEMPUsingSelection()
284        FillEMPFilenameWSelection("")
285End
286
287Proc GuessEveryTransFile(num)
288        Variable num=6
289        GuessAllTransFiles(num)
290End
291
292Proc GuessSelectedTransFiles(num)
293        Variable num=6
294        fGuessSelectedTransFiles(num)
295End
296
297Proc ClearSelectedTransAssignments()
298        ClearSelectedAssignments("")
299End
300
301Proc CreateRunNumList()
302        String/G rStr=""
303        rStr=RunNumberList()
304        Print "The list is stored in root:rStr"
305        print rStr
306End
307
308Proc TransList()
309        String/G rStr=""
310        rStr=RunNumberList()
311        rStr=isTransList(rStr)
312        print rStr
313End
314
315Proc ScatteringAtSDDList(sdd)
316        Variable sdd=13
317       
318        String/G rStr=""
319        rStr=RunNumberList()
320        rStr=removeTrans(rStr)
321        rStr=atSDDList(rStr,sdd)
322       
323        //for Igor 4, the search is case-sensitive, so use all permutations
324        // in Igor 5, use the proper flag in strsearch() inside FindStringInLabel()
325        rStr = RemoveEmptyBlocked(rStr,"EMPTY")
326//      rStr = RemoveEmptyBlocked(rStr,"Empty")
327//      rStr = RemoveEmptyBlocked(rStr,"empty")
328//      rStr = RemoveEmptyBlocked(rStr,"MT Cell")
329        rStr = RemoveEmptyBlocked(rStr,"MT CELL")
330//      rStr = RemoveEmptyBlocked(rStr,"mt cell")
331        rStr = RemoveEmptyBlocked(rStr,"BLOCKED")
332//      rStr = RemoveEmptyBlocked(rStr,"Blocked")
333//      rStr = RemoveEmptyBlocked(rStr,"blocked")
334       
335        print rStr
336End
337
338
339
340//num passed in is the run number, as in the list
341// ii is the index of all of the files from the catalog
342//return will be -1 if string not found, >=0 if found
343//
344Function FindStringInLabel(num,findThisStr)
345        Variable num
346        String findThisStr
347       
348        Wave/T w = $"root:myGlobals:CatVSHeaderInfo:Labels"
349        Wave RunNumber = $"root:myGlobals:CatVSHeaderInfo:RunNumber"
350       
351        if( (WaveExists(w) == 0 ) ||  (WaveExists(RunNumber) == 0 ) )
352                return(0)
353        endif
354       
355        Variable pts=numpnts(RunNumber),ii,loc
356        for(ii=0;ii<pts;ii+=1)
357                if(RunNumber[ii] == num)
358//                      loc = strsearch(w[ii], findThisStr, 0)                  //Igor 4 version is case-sensitive
359                        loc = strsearch(w[ii], findThisStr, 0 ,2)               //2==case insensitive, but Igor 5 specific
360                        if(loc != -1)
361                                Print "Remove w[ii] = ",num,"  ",w[ii]
362                        endif
363                endif
364        endfor
365       
366        return(loc)             //return will be -1 if string not found, >=0 if found
367end
368
369//rStr is the global string, already atSDD (so there should be only one instance of
370// empty and one instance of blocked
371//
372//scan through the list, and remove those that are have "empty" or "blocked" in the label
373// or anything that is listed in StrToFind
374//
375Function/S RemoveEmptyBlocked(list,StrToFind)
376        String list,StrToFind
377       
378        Variable ii,num,temp
379        num=ItemsInList(list ,",")
380        for(ii=0;ii<num;ii+=1)
381                temp = str2num( StringFromList(ii, list ,",") )
382                if(FindStringInLabel(temp,StrToFind) != -1)
383                        list = RemoveFromList(num2str(temp),list,",")
384                        ii -= 1                 //item ii was just deleted (everything moves to fill in)
385                        num -= 1                // and the list is shorter now
386                endif
387        endfor
388        //print list
389        return(list)
390end
391
392// input is a single run number to remove from the list
393//  - typically EC and BN - before sending to MRED
394Proc RemoveRunFromList(remList)
395        String remList=""
396         
397        rStr = RemoveFromList(remList, rStr ,",")
398end
399
400
401//////////general folder utilities
402
403//prompts user to choose the local folder that contains the SANS Data
404//only one folder can be used, and its path is catPathName (and is a NAME, not a string)
405//this will overwrite the path selection
406//returns 1 if no path selected as error condition, or if user cancelled
407Function PickPath()
408       
409        //set the global string to the selected pathname
410        NewPath/O/M="pick the SANS data folder" catPathName
411        if(V_Flag != 0)
412                return(1)               //user cancelled
413        endif
414       
415        PathInfo/S catPathName
416        String dum = S_path
417        String alertStr = ""
418        alertStr = "You must set the path to Charlotte through a Mapped Network Drive, not through the Network Neighborhood"
419        //alertStr += "  Please see the manual for details."
420        if (V_flag == 0)
421                //path does not exist - no folder selected
422                String/G root:myGlobals:gCatPathStr = "no folder selected"
423                return(1)
424        else
425                //set the global to the path (as a string)
426                // need 4 \ since it is the escape character
427               
428// SRK 2016, for windows 10, try to eliminate this restriction         
429//              print igorinfo(3)
430//              if(cmpstr("\\\\",dum[0,1])==0)  //Windows user going through network neighborhood
431//                      DoAlert 0,alertStr
432//                      KillPath catPathName
433//                      return(1)
434//              endif
435               
436                String/G root:myGlobals:gCatPathStr = dum
437                // these are now set in their respective procedures, since the folders don't exist yet!
438//              String/G root:myGlobals:Patch:gCatPathStr = dum //and the global used by Patch and Trans
439//              String/G root:myGlobals:TransHeaderInfo:gCatPathStr = dum       //and the global used by Patch and Trans
440                return(0)               //no error
441        endif
442End
443
444//a utility function that prompts the user for a file (of any type)
445//and returns the full path:name;vers string required to open the file
446//the file is NOT opened by this routine (/D flag)
447//a null string is returned if no file is selected
448//"msgStr" is the message displayed in the dialog, informing the user what
449//file is desired
450//
451Function/S PromptForPath(msgStr)
452        String msgStr
453        String fullPath
454        Variable refnum
455       
456        //this just asks for the filename, doesn't open the file
457        Open/D/R/T="????"/M=(msgStr) refNum
458        fullPath = S_FileName           //fname is the full path
459        //      Print refnum,fullPath
460       
461        //null string is returned in S_FileName if user cancelled, and is passed back to calling  function
462        Return(fullPath)
463End
464
465
466
467//procedure is not called from anywhere, for debugging purposes only
468//not for gerneral users, since it Kills data folders, requiring
469//re-initialization of the experiment
470//
471Proc ClearWorkFolders()
472
473        //not foolproof - will generage an error if any wavs, etc.. are in use.
474        KillDataFolder root:Packages:NIST:RAW
475        KillDataFolder root:Packages:NIST:SAM
476        KillDataFolder root:Packages:NIST:EMP
477        KillDataFolder root:Packages:NIST:BGD
478        KillDataFolder root:Packages:NIST:COR
479        KillDataFolder root:Packages:NIST:DIV
480        KillDataFolder root:Packages:NIST:MSK
481        KillDataFolder root:Packages:NIST:ABS
482        KillDataFolder root:Packages:NIST:CAL
483        SetDataFolder root:
484       
485End
486
487//not used - but potentially very useful for ensuring that old
488// data in work folders is not accidentally being used
489//
490Function ClearWorkFolder(type)
491        String type
492       
493        SetDataFolder $("root:Packages:NIST:"+type)
494        KillWaves/A/Z
495        KillStrings/A/Z
496        KillVariables/A/Z
497       
498        SetDataFolder root:
499End
500
501
502//procedure is not called from anywhere, for debugging purposes only
503//not for gerneral users, but could be useful in reducon clutter
504//
505Proc ClearRootFolder()
506
507        DoAlert 1,"Are you sure you want to delete everything from the root level?"
508        SetDataFolder root:
509        KillWaves/A/Z
510        KillStrings/A/Z
511        KillVariables/A/Z
512       
513End
514
515/////////string matching
516
517
518//the following is a WaveMetrics procedure from <StrMatchList>
519// MatchList(matchStr,list,sep)
520// Returns the items of the list whose items match matchStr
521// The lists are separated by the sep character, usually ";"
522//
523// matchStr may be something like "abc", in which case it is identical to CmpStr
524// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
525//      "*abc" to match anything ending with "abc".
526// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
527//      the pattern.
528// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
529//
530Function/S MyMatchList(matchStr,list,sep)
531        String matchStr,list,sep
532        String item,outList=""
533        Variable n=strlen(list)
534        Variable en,st=0
535        do
536                en= strsearch(list,sep,st)
537                if( en < 0 )
538                        if( st < n-1 )
539                                en= n   // no trailing separator
540                                sep=""  // don't put sep in output, either
541                        else
542                                break   // no more items in list
543                        endif
544                endif
545                item=list[st,en-1]
546                if( MyStrMatch(matchStr,item) == 0 )
547                        outlist += item+sep
548                Endif
549                st=en+1
550        while (st < n ) // exit is by break, above
551        return outlist
552End
553
554//the following is a WaveMetrics procedure from <StrMatchList>
555// StrMatch(matchStr,str)
556// Returns 0 if the pattern in matchStr matches str, else it returns 1
557//
558// matchStr may be something like "abc", in which case it is identical to CmpStr
559// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
560//      "*abc" to match anything ending with "abc".
561// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
562//      the pattern.
563// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
564//
565Function MyStrMatch(matchStr,str)
566        String matchStr,str
567        Variable match = 1              // 0 means match
568        Variable invert= strsearch(matchStr,"!",0) == 0
569        if( invert )
570                matchStr[0,0]=""        // remove the "!"
571        endif
572        Variable st=0,en=strlen(str)-1
573        Variable starPos= strsearch(matchStr,"*",0)
574        if( starPos >= 0 )      // have a star
575                if( starPos == 0 )      // at start
576                        matchStr[0,0]=""                                // remove star at start
577                else                                    // at end
578                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
579                endif
580                Variable len=strlen(matchStr)
581                if( len > 0 )
582                        if(starPos == 0)        // star at start, match must be at end
583                                st=en-len+1
584                        else
585                                en=len-1        // star at end, match at start
586                        endif
587                else
588                        str=""  // so that "*" matches anything
589                endif
590        endif
591        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
592        if( invert )
593                match= 1-match
594        endif
595        return match
596End
597
598
599// converts a hexadecimal string to a decimal value
600// crude, no error checking
601//
602Function str2hex(str)
603        String str
604       
605        Variable hex
606       
607        sscanf str,"%x",hex
608       
609        return(hex)
610End
Note: See TracBrowser for help on using the repository browser.