source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_Utilities_General.ipf @ 1002

Last change on this file since 1002 was 1002, checked in by srkline, 6 years ago

main changes here are the addition of a first pass at the file catalog, and patch panel. each of these is based on the old SANS file (for now) and has been updated to at least compile.

Much more work needs to be done to get the functionality to be what VSANS needs, both in what is important to report in the file catalog, and how to best present the patch GUI for different situations

File size: 26.2 KB
Line 
1#pragma TextEncoding = "MacRoman"               // For details execute DisplayHelpTopic "The TextEncoding Pragma"
2#pragma rtGlobals=3             // Use modern global access method and strict wave access.
3
4//
5//              general utilities
6//
7// for use by multiple panels and packages
8
9
10//prompts user to choose the local folder that contains the SANS Data
11//only one folder can be used, and its path is catPathName (and is a NAME, not a string)
12//this will overwrite the path selection
13//returns 1 if no path selected as error condition, or if user cancelled
14Function V_PickPath()
15       
16        //set the global string to the selected pathname
17        NewPath/O/M="pick the SANS data folder" catPathName
18        if(V_Flag != 0)
19                return(1)               //user cancelled
20        endif
21       
22        PathInfo/S catPathName
23        String dum = S_path
24        String alertStr = ""
25        alertStr = "You must set the path to Charlotte through a Mapped Network Drive, not through the Network Neighborhood"
26        //alertStr += "  Please see the manual for details."
27        if (V_flag == 0)
28                //path does not exist - no folder selected
29                String/G root:Packges:NIST:VSANS:Globals:gCatPathStr = "no folder selected"
30                return(1)
31        else
32                //set the global to the path (as a string)
33                // need 4 \ since it is the escape character
34                if(cmpstr("\\\\",dum[0,1])==0)  //Windows user going through network neighborhood
35                        DoAlert 0,alertStr
36                        KillPath catPathName
37                        return(1)
38                endif
39                String/G root:Packges:NIST:VSANS:Globals:gCatPathStr = dum
40                return(0)               //no error
41        endif
42End
43
44//
45// entry from the Main Panel
46//
47Proc V_ChangeDisplay(type)
48        String type
49        Prompt type,"WORK data type to display",popup,"RAW;SAM;EMP;BGD;ADJ;"
50
51// make sure that data exists before passing this on...
52       
53        if(DataExists(type) > 0)
54                UpdateDisplayInformation(type)
55        else
56                DoAlert 0,"No data in "+type
57        endif
58End
59
60// TODO
61//
62// very simple function to look for something in a work folder
63// -- only checks for FR data to exist, assumes everything else is there
64// -- can't use the V_get() functions, these will try to load data if it's not there!
65Function DataExists(type)
66        String type
67       
68        Wave/Z w = $("root:Packages:NIST:VSANS:"+type+":entry:instrument:detector_FR:data")
69       
70        return(WaveExists(w))
71end
72//
73// tests if two values are close enough to each other
74// very useful since ICE came to be
75//
76// tol is an absolute value (since input v1 or v2 may be zero, can't reliably
77// use a percentage
78Function CloseEnough(v1,v2,tol)
79        Variable v1, v2, tol
80
81        if(abs(v1-v2) < tol)
82                return(1)
83        else
84                return(0)
85        endif
86End
87
88
89
90// TODO:
91// -- this must be called as needed to force a re-read of the data from disk
92//    "as needed" means that when an operation is done that needs to ensure
93//     a fresh read from disk, it must take care of the kill.
94// -- the ksBaseDFPath needs to be removed. It's currently pointing to RawVSANS, which is
95//    really not used as intended anymore.
96//
97Function V_KillNamedDataFolder(fname)
98        String fname
99       
100        Variable err=0
101       
102        String folderStr = V_GetFileNameFromPathNoSemi(fname)
103        folderStr = V_RemoveDotExtension(folderStr)
104       
105        KillDataFolder/Z $(ksBaseDFPath+folderStr)
106        err = V_flag
107       
108        return(err)
109end
110
111// TODO:
112// -- this still does not quite work. If there are no sub folders present in the RawVSANS folder
113//    it still thinks there are (1) item there.
114// -- if I replace the semicolon with a comma, it thinks there are two folders present and appears
115//    to delete the RawVSANS folder itself! seems very dangerous...this is because DataFolderDir returns
116//    a comma delimited list, but with a semicolon and \r at the end. need to remove these...
117Function V_CleanOutRawVSANS()
118
119        SetDataFolder root:Packages:NIST:VSANS:RawVSANS:
120       
121        // get a list of the data folders there
122        // kill them all if possible
123        String list,item
124        Variable numFolders,ii,pt
125       
126        list = DataFolderDir(1)
127        // this has FOLDERS: at the beginning and is comma-delimited
128        list = list[8,strlen(list)]
129        pt = strsearch(list,";",inf,1)
130        list = list[0,pt-1]                     //remove the ";\r" from the end of the string
131//      print list
132       
133        numFolders = ItemsInList(list , ",")
134//      Print List
135//      print strlen(list)
136
137        for(ii=0;ii<numFolders;ii+=1)
138                item = StringFromList(ii, list ,",")
139//              Print item
140                KillDataFolder/Z $(item)
141        endfor
142
143        list = DataFolderDir(1)
144        list = list[8,strlen(list)]
145        pt = strsearch(list,";",inf,1)
146        list = list[0,pt-1]
147        numFolders = ItemsInList(list, ",")
148        Printf "%g RawVSANS folders could not be killed\r",numFolders
149               
150        SetDataFolder root:
151        return(0)
152End
153
154//given a filename of a SANS data filename of the form
155// name.anything
156//returns the name as a string without the ".fbdfasga" extension
157//
158// returns the input string if a "." can't be found (maybe it wasn't there)
159Function/S V_RemoveDotExtension(item)
160        String item
161        String invalid = item   //
162        Variable num=-1
163       
164        //find the "dot"
165        String runStr=""
166        Variable pos = strsearch(item,".",0)
167        if(pos == -1)
168                //"dot" not found
169                return (invalid)
170        else
171                //found, get all of the characters preceeding it
172                runStr = item[0,pos-1]
173                return (runStr)
174        Endif
175End
176
177//returns a string containing filename (WITHOUT the ;vers)
178//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
179//with the folders separated by colons
180//
181// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
182//
183Function/S V_GetFileNameFromPathNoSemi(fullPath)
184        String fullPath
185       
186        Variable offset1,offset2
187        String filename=""
188        //String PartialPath
189        offset1 = 0
190        do
191                offset2 = StrSearch(fullPath, ":", offset1)
192                if (offset2 == -1)                              // no more colons ?
193                        fileName = FullPath[offset1,strlen(FullPath) ]
194                        //PartialPath = FullPath[0, offset1-1]
195                        break
196                endif
197                offset1 = offset2+1
198        while (1)
199       
200        //remove version number from name, if it's there - format should be: filename;N
201        filename =  StringFromList(0,filename,";")              //returns null if error
202       
203        Return filename
204End
205
206//
207// -- this was copied directly, no changes , from PlotUtils_Macro_v40
208//
209// returns the path to the file, or null if the user cancelled
210// fancy use of optional parameters
211//
212// enforce short file names (25 characters)
213Function/S V_DoSaveFileDialog(msg,[fname,suffix])
214        String msg,fname,suffix
215        Variable refNum
216//      String message = "Save the file as"
217
218        if(ParamIsDefault(fname))
219//              Print "fname not supplied"
220                fname = ""
221        endif
222        if(ParamIsDefault(suffix))
223//              Print "suffix not supplied"
224                suffix = ""
225        endif
226       
227        String outputPath,tmpName,testStr
228        Variable badLength=0,maxLength=25,l1,l2
229       
230       
231        tmpName = fname + suffix
232       
233        do
234                badLength=0
235                Open/D/M=msg/T="????" refNum as tmpName         //OS will allow 255 characters, but then I can't read it back in!
236                outputPath = S_fileName
237               
238                testStr = ParseFilePath(0, outputPath, ":", 1, 0)               //just the filename
239                if(strlen(testStr)==0)
240                        break           //cancel, allow exit
241                endif
242                if(strlen(testStr) > maxLength)
243                        badlength = 1
244                        DoAlert 2,"File name is too long. Is\r"+testStr[0,maxLength-1]+"\rOK?"
245                        if(V_flag==3)
246                                outputPath = ""
247                                break
248                        endif
249                        if(V_flag==1)                   //my suggested name is OK, so trim the output
250                                badlength=0
251                                l1 = strlen(testStr)            //too long length
252                                l1 = l1-maxLength               //number to trim
253                                //Print outputPath
254                                l2=strlen(outputPath)
255                                outputPath = outputPath[0,l2-1-l1]
256                                //Print "modified  ",outputPath
257                        endif
258                        //if(V_flag==2)  do nothing, let it go around again
259                endif
260               
261        while(badLength)
262       
263        return outputPath
264End
265
266
267
268//
269// previous/next button needs these functions
270// as well as many other utilities that manipulate the data file names
271// and parse run numbers.
272//
273
274
275// TODO
276// x- load in the proper file
277// x- re-click the I(q) button
278// x- be sure that the globals are updated w/ filename
279// -- getting the file_name from the root: global is a poor choice.
280//     Need a better, more reliable solution than this
281// -- make a copy of "oldName" that is local and not the SVAR, as the SVAR changes
282//    when the next file is loaded in (if it's not in RawVSANS), resulting in a "skipped" file number
283//
284//displays next (or previous) file in series of run numbers
285//file is read from disk, if path is set and the file number is present
286//increment +1, adds 1 to run number, -1 subtracts one
287//
288// will automatically step a gap of 10 run numbers, but nothing larger. Don't want to loop too long
289// trying to find a file (frustrating), don't want to look past the end of the run numbers (waste)
290// -- may find a more elegant solution later.
291//
292Function V_LoadPlotAndDisplayRAW(increment)
293        Variable increment
294
295        Variable i,val
296        String filename,tmp,curFileName
297        //take the currently displayed RAW file
298        SVAR oldName = root:file_name
299        oldname = V_RemoveAllSpaces(oldname)            //
300        curFileName = oldName
301//      print oldName
302       
303        filename = oldname
304//      for (i = 0; i < abs(increment); i += 1)
305//              filename = GetPrevNextRawFile(filename,increment/abs(increment))
306//      endfor 
307        i = 1
308        val = increment
309        do
310//              print filename,val
311                filename = V_GetPrevNextRawFile(filename,val)
312//              print "new= ",filename
313               
314                val = i*increment
315                i+=1
316                tmp = ParseFilePath(0, filename, ":", 1, 0)
317
318//              print val,strlen(tmp),strlen(oldname)
319//              print cmpstr(tmp,oldname)
320
321                if(strlen(tmp) == 0)            //in some cases, a null string can be returned - handle gracefully
322                        return(0)
323                endif
324               
325        while( (cmpstr(tmp,curFileName) == 0) && i < 11)
326//      print filename
327       
328        // display the specified RAW data file
329        // this is the set of steps done in DisplayMainButtonProc(ctrlName) : ButtonControl
330        Variable err=   V_LoadHDF5Data(filename,"RAW")                  // load the data, set the global w/file name loaded
331//      Print "Load err = "+num2str(err)
332        if(!err)
333                SVAR hdfDF = root:file_name                     // last file loaded, may not be the safest way to pass
334                String folder = StringFromList(0,hdfDF,".")
335               
336                // this (in SANS) just passes directly to fRawWindowHook()
337                Execute "UpdateDisplayInformation(\"RAW\")"     // plot the data in whatever folder type
338               
339                FakeRestorePanelsButtonClick()          //so the panels display correctly
340               
341        endif
342
343        // TODO
344        // -- update the 1D plotting as needed. these are SANS calls (OK for now, but will need to be better)
345        //do the average and plot (either the default, or what is on the panel currently)
346        V_PlotData_Panel()
347       
348
349        return(0)
350End
351
352
353// Return the full path:filename that represents the previous or next file.
354// Input is current filename and increment.
355// Increment should be -1 or 1
356// -1 => previous file
357// 1 => next file
358//
359// V_CheckIfRawData(fname)
360//
361Function/S V_GetPrevNextRawFile(curfilename, prevnext)
362        String curfilename
363        Variable prevnext
364
365        String filename
366       
367        //get the run number
368        Variable num = V_GetRunNumFromFile(curfilename)
369               
370        //find the next specified file by number
371        fileName = V_FindFileFromRunNumber(num+prevnext)
372
373        if(cmpstr(fileName,"")==0)
374                //null return, do nothing
375                fileName = V_FindFileFromRunNumber(num)         //returns the full path, not just curFileName
376        Endif
377
378        Return filename
379End
380
381
382//returns a string containing the full path to the file containing the
383//run number "num". The null string is returned if no valid file can be found
384//the path "catPathName" used and is hard-wired, will abort if this path does not exist
385//the file returned will be a RAW VSANS data file, other types of files are
386//filtered out.
387//
388// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
389//
390Function/S V_FindFileFromRunNumber(num)
391        Variable num
392       
393        String fullName="",partialName="",item=""
394        //get list of raw data files in folder that match "num" (add leading zeros)
395        if( (num>9999) || (num<=0) )
396                Print "error in  FindFileFromRunNumber(num), file number too large or too small"
397                Return ("")
398        Endif
399        //make a four character string of the run number
400        String numStr=""
401        if(num<10)
402                numStr = "000"+num2str(num)
403        else
404                if(num<100)
405                        numStr = "00"+num2str(num)
406                else
407                        if(num<1000)
408                                numstr = "0"+num2str(num)
409                        else
410                                numStr = num2str(num)
411                        endif
412                Endif
413        Endif
414        //Print "numstr = ",numstr
415       
416        //make sure that path exists
417        PathInfo catPathName
418        String path = S_path
419        if (V_flag == 0)
420                Abort "folder path does not exist - use Pick Path button"
421        Endif
422        String list="",newList="",testStr=""
423       
424        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
425        //find (the) one with the number in the run # location in the name
426        Variable numItems,ii,runFound,isRAW
427        numItems = ItemsInList(list,";")                //get the new number of items in the list
428        ii=0
429        do
430                //parse through the list in this order:
431                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
432                // 2 - exclude by isRaw? (to minimize disk access)
433                item = StringFromList(ii, list  ,";" )
434                if(strlen(item) != 0)
435                        //find the run number, if it exists as a three character string
436                        testStr = V_GetRunNumStrFromFile(item)
437                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
438                        if(runFound == 0)
439                                //the run Number was found
440                                //build valid filename
441                                partialName = V_FindValidFileName(item)
442                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
443                                        fullName = path + partialName
444                                        //check if RAW, if so,this must be the file!
445                                        isRAW = V_CheckIfRawData(fullName)
446                                        if(isRaw)
447                                                //print "is raw, ",fullname
448                                                //stop here
449                                                return(fullname)
450                                        Endif
451                                Endif
452                        Endif
453                Endif
454                ii+=1
455        while(ii<numItems)              //process all items in list
456        Return ("")     //null return if file not found in list
457End
458
459//
460// TODO x- for VSANS Nexus files, how do I quickly identify if a file is
461//   RAW VSANS data? I don't want to generate any errors, but I want to quickly
462//   weed out the reduced data sets, etc. from file catalogs.
463//      (check the instrument name...)
464
465// TODO -- as was written by SANS, this function is expecting fname to be the path:fileName
466// - but are the V_get() functions OK with getting a full path, and what do they
467//  do when they fail? I don't want them to spit up another open file dialog
468//
469Function V_CheckIfRawData(fname)
470        String fname
471       
472        Variable refnum,totalBytes
473        String testStr=""
474       
475        testStr = V_getInstrumentName(fname)
476
477        if(cmpstr(testStr,"NG3-VSANS") == 0)
478                //testStr exists, ASSUMING it's a raw VSANS data file
479                Return(1)
480        else
481                //some other file
482                Return(0)
483        Endif
484End
485
486// TODO -- need to fill in correctly by determining this from the INTENT field
487//
488Function V_isTransFile(fname)
489        String fname
490       
491        Variable refnum,totalBytes
492        String testStr=""
493       
494//      testStr = V_getInstrumentName(fname)
495
496        if(cmpstr(testStr,"NG3-VSANS") == 0)            //wrong test
497                //testStr exists, ASSUMING it's a raw VSANS data file
498                Return(1)
499        else
500                //some other file
501                Return(0)
502        Endif
503End
504
505
506Function V_GetRunNumFromFile(item)
507        String item
508       
509        String str = V_GetRunNumStrFromFile(item)
510       
511        return(str2num(str))
512end
513
514
515// TODO -- the file name structure for VSANS file is undecided
516// so some of these base functions will need to change
517//
518//given a filename of a VSANS data filename of the form
519// sansNNNN.nxs.ngv
520//returns the run number "NNNN" as a STRING of FOUR characters
521//returns "ABCD" as an invalid file number
522//
523// local function to aid in locating files by run number
524//
525Function/S V_GetRunNumStrFromFile(item)
526        String item
527        String invalid = "ABCD" //"ABCD" is not a valid run number, since it's text
528        Variable num=-1
529       
530        //find the "dot"
531        String runStr=""
532        Variable numChar = 4
533        Variable pos = strsearch(item,".",0)
534        if(pos == -1)
535                //"dot" not found
536                return (invalid)
537        else
538                //found, get the four characters preceeding it
539                if (pos <= numChar-1)
540                        //not enough characters
541                        return (invalid)
542                else
543                        runStr = item[pos-numChar,pos-1]
544                        return (runStr)
545                Endif
546        Endif
547End
548
549//Function attempts to find valid filename from partial name by checking for
550// the existence of the file on disk.
551// - checks as is
552// - strips spaces
553// - permutations of upper/lowercase
554//
555// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
556// since from marquee, the filename field (textread[0]) must be used, and can be a mix of                       //02JUL13
557// upper/lowercase letters, while the filename on the server (should) be all caps
558// now makes repeated calls to ValidFileString()
559//
560// returns a valid filename (No path prepended) or a null string
561//
562// called by any functions, both external and local
563//
564Function/S V_FindValidFilename(partialName)
565        String PartialName
566       
567        String retStr=""
568       
569        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
570        retStr = V_ValidFileString(partialName)
571        if(cmpstr(retStr,"") !=0)
572                //non-null return
573                return(retStr)
574        Endif
575       
576        //if the partial name is derived from the file header, there can be spaces at the beginning
577        //or in the middle of the filename - depending on the prefix and initials used
578        //
579        //remove any leading spaces from the name before starting
580        partialName = V_RemoveAllSpaces(partialName)
581       
582        //try name with no spaces
583        retStr = V_ValidFileString(partialName)
584        if(cmpstr(retStr,"") !=0)
585                //non-null return
586                return(retStr)
587        Endif
588       
589        //try all UPPERCASE
590        partialName = UpperStr(partialName)
591        retStr = V_ValidFileString(partialName)
592        if(cmpstr(retStr,"") !=0)
593                //non-null return
594                return(retStr)
595        Endif
596       
597        //try all lowercase (ret null if failure)
598        partialName = LowerStr(partialName)
599        retStr = V_ValidFileString(partialName)
600        if(cmpstr(retStr,"") !=0)
601                //non-null return
602                return(retStr)
603        else
604                return(retStr)
605        Endif
606End
607
608
609// Function checks for the existence of a file
610// partialName;vers (to account for VAX filenaming conventions)
611// The partial name is tried first with no version number
612//
613// *** the PATH is hard-wired to catPathName (which is assumed to exist)
614// version numers up to ;10 are tried
615// only the "name;vers" is returned if successful. The path is not prepended
616//
617// local function
618//
619// TODO -- is this really necessary anymore for the NON-VAX files of VSANS.
620// -- can this be made a pass-through, or will there be another function that is needed for VSANS?
621//
622Function/S V_ValidFileString(partialName)
623        String partialName
624       
625        String tempName = "",msg=""
626        Variable ii,refnum
627       
628        ii=0
629        do
630                if(ii==0)
631                        //first pass, try the partialName
632                        tempName = partialName
633                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
634                        if(V_flag == 0)
635                                //file exists
636                                Close refnum            //YES needed,
637                                break
638                        endif
639                else
640                        tempName = partialName + ";" + num2str(ii)
641                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
642                        if(V_flag == 0)
643                                //file exists
644                                Close refnum
645                                break
646                        endif
647                Endif
648                ii+=1
649                //print "ii=",ii
650        while(ii<11)
651        //go get the selected bits of information, using tempName, which exists
652        if(ii>=11)
653                //msg = partialName + " not found. is version number > 11?"
654                //DoAlert 0, msg
655                //PathInfo catPathName
656                //Print S_Path
657                Return ("")             //use null string as error condition
658        Endif
659       
660        Return (tempName)
661End
662
663//function to remove all spaces from names when searching for filenames
664//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
665//but the text field in the header WILL, if less than 3 characters were used for the
666//user's initials, and can have leading spaces if prefix was less than 5 characters
667//
668//returns a string identical to the original string, except with the interior spaces removed
669//
670// local function for file name manipulation
671//
672Function/S V_RemoveAllSpaces(str)
673        String str
674       
675        String tempstr = str
676        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
677        ii=0
678        do
679                len = strlen(tempStr)
680                spc = strsearch(tempStr," ",0)          //is the last character a space?
681                if (spc == -1)
682                        break           //no more spaces found, get out
683                endif
684                str = tempstr
685                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
686        While(1)        //should never be more than 2 or 3
687       
688        If(strlen(tempStr) < 1)
689                tempStr = ""            //be sure to return a null string if problem found
690        Endif
691       
692        //Print strlen(tempstr)
693       
694        Return(tempStr)
695               
696End
697
698// returns a list of raw data files in the catPathName directory on disk
699// - list is SEMICOLON-delimited
700//
701// TODO: decide how to do this...
702// (1)
703// checks each file in the directory to see if it is a RAW data file by
704// call to V_CheckIfRawData() which currently looks for the instrument name in the file.
705// -- CON - this is excruciatingly slow, and by checking a field in the file, has to load in the
706//  ENTIRE data file, and will load EVERY file in the folder. ugh.
707//
708// (2)
709// as was done for VAX files, look for a specific string in the file name as written by the acquisition
710//  (was .saN), now key on ".nxs.ngv"?
711//
712// called by PatchFiles.ipf, Tile_2D.ipf
713//
714Function/S V_GetRawDataFileList()
715       
716        //make sure that path exists
717        PathInfo catPathName
718        if (V_flag == 0)
719                Abort "Folder path does not exist - use Pick Path button on Main Panel"
720        Endif
721        String path = S_Path
722       
723        String list=IndexedFile(catPathName,-1,"????")
724        String newList="",item="",validName="",fullName=""
725        Variable num=ItemsInList(list,";"),ii
726       
727        for(ii=0;ii<num;ii+=1)
728                item = StringFromList(ii, list  ,";")
729
730                validName = V_FindValidFileName(item)
731                if(strlen(validName) != 0)              //non-null return from FindValidFileName()
732                        fullName = path + validName             
733
734        //method (1)                   
735//                      if(V_CheckIfRawData(item))
736//                              newlist += item + ";"
737//                      endif
738
739        //method (2)                   
740                        if( stringmatch(item,"*.nxs.ngv*") )
741                                newlist += item + ";"
742                        endif
743
744                       
745                endif
746                //print "ii=",ii
747        endfor
748        newList = SortList(newList,";",0)
749        return(newList)
750End
751
752
753//the following is a WaveMetrics procedure from <StrMatchList>
754// MatchList(matchStr,list,sep)
755// Returns the items of the list whose items match matchStr
756// The lists are separated by the sep character, usually ";"
757//
758// matchStr may be something like "abc", in which case it is identical to CmpStr
759// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
760//      "*abc" to match anything ending with "abc".
761// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
762//      the pattern.
763// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
764//
765Function/S V_MyMatchList(matchStr,list,sep)
766        String matchStr,list,sep
767        String item,outList=""
768        Variable n=strlen(list)
769        Variable en,st=0
770        do
771                en= strsearch(list,sep,st)
772                if( en < 0 )
773                        if( st < n-1 )
774                                en= n   // no trailing separator
775                                sep=""  // don't put sep in output, either
776                        else
777                                break   // no more items in list
778                        endif
779                endif
780                item=list[st,en-1]
781                if( V_MyStrMatch(matchStr,item) == 0 )
782                        outlist += item+sep
783                Endif
784                st=en+1
785        while (st < n ) // exit is by break, above
786        return outlist
787End
788
789//the following is a WaveMetrics procedure from <StrMatchList>
790// StrMatch(matchStr,str)
791// Returns 0 if the pattern in matchStr matches str, else it returns 1
792//
793// matchStr may be something like "abc", in which case it is identical to CmpStr
794// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
795//      "*abc" to match anything ending with "abc".
796// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
797//      the pattern.
798// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
799//
800Function V_MyStrMatch(matchStr,str)
801        String matchStr,str
802        Variable match = 1              // 0 means match
803        Variable invert= strsearch(matchStr,"!",0) == 0
804        if( invert )
805                matchStr[0,0]=""        // remove the "!"
806        endif
807        Variable st=0,en=strlen(str)-1
808        Variable starPos= strsearch(matchStr,"*",0)
809        if( starPos >= 0 )      // have a star
810                if( starPos == 0 )      // at start
811                        matchStr[0,0]=""                                // remove star at start
812                else                                    // at end
813                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
814                endif
815                Variable len=strlen(matchStr)
816                if( len > 0 )
817                        if(starPos == 0)        // star at start, match must be at end
818                                st=en-len+1
819                        else
820                                en=len-1        // star at end, match at start
821                        endif
822                else
823                        str=""  // so that "*" matches anything
824                endif
825        endif
826        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
827        if( invert )
828                match= 1-match
829        endif
830        return match
831End
832
833
834//input is a list of run numbers, and output is a list of filenames (not the full path)
835//*** input list must be COMMA delimited***
836//output is equivalent to selecting from the CAT table
837//if some or all of the list items are valid filenames, keep them...
838//if an error is encountered, notify of the offending element and return a null list
839//
840//output is COMMA delimited
841//
842// this routine is expecting that the "ask", "none" special cases are handled elsewhere
843//and not passed here
844//
845// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
846//
847Function/S ParseRunNumberList(list)
848        String list
849       
850        String newList="",item="",tempStr=""
851        Variable num,ii,runNum
852       
853        //expand number ranges, if any
854        list = V_ExpandNumRanges(list)
855       
856        num=itemsinlist(list,",")
857       
858        for(ii=0;ii<num;ii+=1)
859                //get the item
860                item = StringFromList(ii,list,",")
861                //is it already a valid filename?
862                tempStr=V_FindValidFilename(item) //returns filename if good, null if error
863                if(strlen(tempstr)!=0)
864                        //valid name, add to list
865                        //Print "it's a file"
866                        newList += tempStr + ","
867                else
868                        //not a valid name
869                        //is it a number?
870                        runNum=str2num(item)
871                        //print runnum
872                        if(numtype(runNum) != 0)
873                                //not a number -  maybe an error                       
874                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
875                                return("")
876                        else
877                                //a run number or an error
878                                tempStr = V_GetFileNameFromPathNoSemi( V_FindFileFromRunNumber(runNum) )
879                                if(strlen(tempstr)==0)
880                                        //file not found, error
881                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
882                                        return("")
883                                else
884                                        newList += tempStr + ","
885                                endif
886                        endif
887                endif
888        endfor          //loop over all items in list
889       
890        return(newList)
891End
892
893//takes a comma delimited list that MAY contain number range, and
894//expands any range of run numbers into a comma-delimited list...
895//and returns the new list - if not a range, return unchanged
896//
897// local function
898//
899Function/S V_ExpandNumRanges(list)
900        String list
901       
902        String newList="",dash="-",item,str
903        Variable num,ii,hasDash
904       
905        num=itemsinlist(list,",")
906//      print num
907        for(ii=0;ii<num;ii+=1)
908                //get the item
909                item = StringFromList(ii,list,",")
910                //does it contain a dash?
911                hasDash = strsearch(item,dash,0)                //-1 if no dash found
912                if(hasDash == -1)
913                        //not a range, keep it in the list
914                        newList += item + ","
915                else
916                        //has a dash (so it's a range), expand (or add null)
917                        newList += V_ListFromDash(item)         
918                endif
919        endfor
920       
921        return newList
922End
923
924//be sure to add a trailing comma to the return string...
925//
926// local function
927//
928Function/S V_ListFromDash(item)
929        String item
930       
931        String numList="",loStr="",hiStr=""
932        Variable lo,hi,ii
933       
934        loStr=StringFromList(0,item,"-")        //treat the range as a list
935        hiStr=StringFromList(1,item,"-")
936        lo=str2num(loStr)
937        hi=str2num(hiStr)
938        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
939                numList=""
940                return numList
941        endif
942        for(ii=lo;ii<=hi;ii+=1)
943                numList += num2str(ii) + ","
944        endfor
945       
946        Return numList
947End
948
Note: See TracBrowser for help on using the repository browser.