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

Last change on this file since 1107 was 1107, checked in by srkline, 4 years ago

fixed bug in "next" file buttons for some cases where they would not properly skip missing file numbers.

File size: 41.4 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
11//prompts user to choose the local folder that contains the VSANS Data
12//only one folder can be used, and its path is catPathName (and is a NAME, not a string)
13//this will overwrite the path selection
14//returns 1 if no path selected as error condition, or if user cancelled
15Function V_PickPath()
16       
17        //set the global string to the selected pathname
18        NewPath/O/M="pick the SANS data folder" catPathName
19        if(V_Flag != 0)
20                return(1)               //user cancelled
21        endif
22       
23        PathInfo/S catPathName
24        String dum = S_path
25        String alertStr = ""
26        alertStr = "You must set the path to Charlotte through a Mapped Network Drive, not through the Network Neighborhood"
27        //alertStr += "  Please see the manual for details."
28        if (V_flag == 0)
29                //path does not exist - no folder selected
30                String/G root:Packges:NIST:VSANS:Globals:gCatPathStr = "no folder selected"
31                return(1)
32        else
33        // SRK 2016, for windows 10, try to eliminate this restriction 
34        //---- connecting through the network neighborhood seems to be perfectly fine except for
35        //     path issues with GBLoadWave, which only affects VAX data sets
36               
37//              print igorinfo(3)
38//              //set the global to the path (as a string)
39//              // need 4 \ since it is the escape character
40//              if(cmpstr("\\\\",dum[0,1])==0)  //Windows user going through network neighborhood
41//                      DoAlert 0,alertStr
42//                      KillPath catPathName
43//                      return(1)
44//              endif
45                String/G root:Packges:NIST:VSANS:Globals:gCatPathStr = dum
46                return(0)               //no error
47        endif
48       
49End
50
51//
52// entry from the Main Panel
53//
54Proc V_ChangeDisplay(type)
55        String type
56        Prompt type,"WORK data type to display",popup,"RAW;SAM;EMP;BGD;COR;ABS;STO;SUB;ADJ;"
57
58// make sure that data exists before passing this on...
59       
60        if(V_DataExists(type) > 0)
61                V_UpdateDisplayInformation(type)
62        else
63                DoAlert 0,"No data in "+type
64        endif
65End
66
67//
68//
69// very simple function to look for something in a work folder
70// -- only checks for FR data to exist, assumes everything else is there
71// -- can't use the V_get() functions, these will try to load data if it's not there!
72Function V_DataExists(type)
73        String type
74       
75        Wave/Z w = $("root:Packages:NIST:VSANS:"+type+":entry:instrument:detector_FR:data")
76       
77        return(WaveExists(w))
78end
79
80
81
82// (DONE):
83// x- this must be called as needed to force a re-read of the data from disk
84//    "as needed" means that when an operation is done that needs to ensure
85//     a fresh read from disk, it must take care of the kill.
86//
87// ksBaseDFPath points to RawVSANS
88//
89//
90Function V_KillNamedDataFolder(fname)
91        String fname
92       
93        Variable err=0
94       
95        String folderStr = V_GetFileNameFromPathNoSemi(fname)
96        folderStr = V_RemoveDotExtension(folderStr)
97       
98        KillDataFolder/Z $(ksBaseDFPath+folderStr)
99        err = V_flag
100       
101        return(err)
102end
103
104// (DONE)
105// x- this still does not quite work. If there are no sub folders present in the RawVSANS folder
106//    it still thinks there is (1) item there.
107// x- if I replace the semicolon with a comma, it thinks there are two folders present and appears
108//    to delete the RawVSANS folder itself! seems very dangerous...this is because DataFolderDir returns
109//    a comma delimited list, but with a semicolon and \r at the end. need to remove these...
110//
111// NOTE -- use V_CleanupData_w_Progress(0,1) to get a progress bar - since this will take more than
112//     a few seconds to complete, especially if a file catalog was done, or a "batch" patching, etc.
113//
114// *** this appears to be unused, in favor of V_CleanupData_w_Progress(0,1)  **********
115//
116Function V_CleanOutRawVSANS()
117
118        SetDataFolder root:Packages:NIST:VSANS:RawVSANS:
119       
120        // get a list of the data folders there
121        // kill them all if possible
122        String list,item
123        Variable numFolders,ii,pt
124       
125        list = DataFolderDir(1)
126        // this has FOLDERS: at the beginning and is comma-delimited
127        list = list[8,strlen(list)]
128        pt = strsearch(list,";",inf,1)
129        list = list[0,pt-1]                     //remove the ";\r" from the end of the string
130//      print list
131       
132        numFolders = ItemsInList(list , ",")
133//      Print List
134//      print strlen(list)
135
136        for(ii=0;ii<numFolders;ii+=1)
137                item = StringFromList(ii, list ,",")
138//              Print item
139                KillDataFolder/Z $(item)
140        endfor
141
142        list = DataFolderDir(1)
143        list = list[8,strlen(list)]
144        pt = strsearch(list,";",inf,1)
145        list = list[0,pt-1]
146        numFolders = ItemsInList(list, ",")
147        Printf "%g RawVSANS folders could not be killed\r",numFolders
148               
149        SetDataFolder root:
150        return(0)
151End
152
153//
154// examples straight from Wavemetrics help file topic "Progress Windows"
155// Try simpletest(0,0) and simpletest(1,0), simpletest(0,1) and simpletest(1,1)
156//
157//
158// look for simpletest() function in Wavemetrics help file topic "Progress Windows"
159//  this is a modified version.
160//
161// call with (1,1) to get the candystripe bar
162// call with (0,1) to the the "countdown" bar as they are killed
163//
164Function V_CleanupData_w_Progress(indefinite, useIgorDraw)
165        Variable indefinite
166        Variable useIgorDraw            // True to use Igor's own draw method rather than native
167       
168        Variable num,numToClean
169       
170        // is there anything there to be killed?
171        num = V_CleanOutOneRawVSANS()
172        numToClean = num
173        if(num <= 0)
174                return(0)
175        endif
176       
177        // there are some folders to kill, so proceed
178       
179        NewPanel /N=ProgressPanel /W=(285,111,739,193)
180        ValDisplay valdisp0,win=ProgressPanel,pos={18,32},size={342,18},limits={0,num,0},barmisc={0,0}
181        ValDisplay valdisp0,win=ProgressPanel,value= _NUM:0
182        DrawText 20,24,"Cleaning up old files... Please Wait..."
183       
184        if( indefinite )
185                ValDisplay valdisp0,win=ProgressPanel,mode= 4   // candy stripe
186        else
187                ValDisplay valdisp0,win=ProgressPanel,mode= 3   // bar with no fractional part
188        endif
189        if( useIgorDraw )
190                ValDisplay valdisp0,win=ProgressPanel,highColor=(15000,45535,15000)             //(0,65535,0)
191        endif
192        Button bStop,win=ProgressPanel,pos={375,32},size={50,20},title="Stop"
193        DoUpdate /W=ProgressPanel /E=1  // mark this as our progress window
194
195        do
196                num = V_CleanOutOneRawVSANS()
197                if( V_Flag == 2 || num == 0 || num == -1)       // either "stop" or clean exit, or "done" exit from function
198                        break
199                endif
200               
201                ValDisplay valdisp0,win=ProgressPanel,value= _NUM:num
202                DoUpdate /W=ProgressPanel
203        while(1)
204       
205
206        KillWindow ProgressPanel
207        return(numToClean)
208End
209
210
211//
212// x- this still does not quite work. If there are no sub folders present in the RawVSANS folder
213//    it still thinks there is (1) item there.
214// x- if I replace the semicolon with a comma, it thinks there are two folders present and appears
215//    to delete the RawVSANS folder itself! seems very dangerous...this is because DataFolderDir returns
216//    a comma delimited list, but with a semicolon and \r at the end. need to remove these...
217//
218// x- for use with progress bar, kills only one folder, returns the new number of folders left
219// x- if n(in) = n(out), nothing was able to be killed, so return "done" code
220Function V_CleanOutOneRawVSANS()
221
222        SetDataFolder root:Packages:NIST:VSANS:RawVSANS:
223       
224        // get a list of the data folders there
225        // kill them all if possible
226        String list,item
227        Variable numFolders,ii,pt,numIn
228       
229        list = DataFolderDir(1)
230        // this has FOLDERS: at the beginning and is comma-delimited
231        list = list[8,strlen(list)]
232        pt = strsearch(list,";",inf,1)
233        list = list[0,pt-1]                     //remove the ";\r" from the end of the string
234//      print list
235       
236        numFolders = ItemsInList(list , ",")
237        numIn = numFolders
238//      Print List
239//      print strlen(list)
240
241        if(numIn > 0)
242                item = StringFromList(0, list ,",")
243//              Print item
244                KillDataFolder/Z $(item)
245        endif
246
247        list = DataFolderDir(1)
248        list = list[8,strlen(list)]
249        pt = strsearch(list,";",inf,1)
250        list = list[0,pt-1]
251        numFolders = ItemsInList(list, ",")
252       
253        if(numIn == numFolders)
254                Printf "%g RawVSANS folders could not be killed\r",numFolders
255                SetDataFolder root:
256
257                return (-1)
258        endif
259       
260        SetDataFolder root:     
261        return(numFolders)
262End
263
264
265
266
267
268//given a filename of a SANS data filename of the form
269// name.anything
270//returns the name as a string without the ".fbdfasga" extension
271//
272// returns the input string if a "." can't be found (maybe it wasn't there)
273Function/S V_RemoveDotExtension(item)
274        String item
275        String invalid = item   //
276        Variable num=-1
277       
278        //find the "dot"
279        String runStr=""
280        Variable pos = strsearch(item,".",0)
281        if(pos == -1)
282                //"dot" not found
283                return (invalid)
284        else
285                //found, get all of the characters preceeding it
286                runStr = item[0,pos-1]
287                return (runStr)
288        Endif
289End
290
291//returns a string containing filename (WITHOUT the ;vers)
292//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
293//with the folders separated by colons
294//
295// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
296//
297Function/S V_GetFileNameFromPathNoSemi(fullPath)
298        String fullPath
299       
300        Variable offset1,offset2
301        String filename=""
302        //String PartialPath
303        offset1 = 0
304        do
305                offset2 = StrSearch(fullPath, ":", offset1)
306                if (offset2 == -1)                              // no more colons ?
307                        fileName = FullPath[offset1,strlen(FullPath) ]
308                        //PartialPath = FullPath[0, offset1-1]
309                        break
310                endif
311                offset1 = offset2+1
312        while (1)
313       
314        //remove version number from name, if it's there - format should be: filename;N
315        filename =  StringFromList(0,filename,";")              //returns null if error
316       
317        Return filename
318End
319
320//
321// -- this was copied directly, no changes , from PlotUtils_Macro_v40
322//
323// returns the path to the file, or null if the user cancelled
324// fancy use of optional parameters
325//
326// enforce short file names (25 characters)
327Function/S V_DoSaveFileDialog(msg,[fname,suffix])
328        String msg,fname,suffix
329        Variable refNum
330//      String message = "Save the file as"
331
332        if(ParamIsDefault(fname))
333//              Print "fname not supplied"
334                fname = ""
335        endif
336        if(ParamIsDefault(suffix))
337//              Print "suffix not supplied"
338                suffix = ""
339        endif
340       
341        String outputPath,tmpName,testStr
342        Variable badLength=0,maxLength=25,l1,l2
343       
344       
345        tmpName = fname + suffix
346       
347        do
348                badLength=0
349                Open/D/M=msg/T="????" refNum as tmpName         //OS will allow 255 characters, but then I can't read it back in!
350                outputPath = S_fileName
351               
352                testStr = ParseFilePath(0, outputPath, ":", 1, 0)               //just the filename
353                if(strlen(testStr)==0)
354                        break           //cancel, allow exit
355                endif
356                if(strlen(testStr) > maxLength)
357                        badlength = 1
358                        DoAlert 2,"File name is too long. Is\r"+testStr[0,maxLength-1]+"\rOK?"
359                        if(V_flag==3)
360                                outputPath = ""
361                                break
362                        endif
363                        if(V_flag==1)                   //my suggested name is OK, so trim the output
364                                badlength=0
365                                l1 = strlen(testStr)            //too long length
366                                l1 = l1-maxLength               //number to trim
367                                //Print outputPath
368                                l2=strlen(outputPath)
369                                outputPath = outputPath[0,l2-1-l1]
370                                //Print "modified  ",outputPath
371                        endif
372                        //if(V_flag==2)  do nothing, let it go around again
373                endif
374               
375        while(badLength)
376       
377        return outputPath
378End
379
380
381
382//
383// this will only load the data into RAW, overwriting whatever is there. no copy is put in rawVSANS
384//
385Function V_LoadAndPlotRAW_wName(fname)
386        String fname
387
388        Variable err=   V_LoadHDF5Data(fname,"RAW")                     // load the data
389//      Print "Load err = "+num2str(err)
390        if(!err)
391                SVAR hdfDF = root:file_name                     // last file loaded, may not be the safest way to pass
392                String folder = StringFromList(0,hdfDF,".")
393               
394                // this (in SANS) just passes directly to fRawWindowHook()
395                V_UpdateDisplayInformation("RAW")               // plot the data in whatever folder type
396                               
397                // set the global to display ONLY if the load was called from here, not from the
398                // other routines that load data (to read in values)
399                SVAR gLastFile =        root:Packages:NIST:VSANS:Globals:gLastLoadedFile
400                gLastFile = hdfDF
401        endif
402End
403
404
405
406//
407// previous/next button needs these functions
408// as well as many other utilities that manipulate the data file names
409// and parse run numbers.
410//
411
412
413// TODO
414// -- getting the file_name from the root: global is a poor choice.
415//     Need a better, more reliable solution than this
416//
417// DONE
418// x- load in the proper file
419// x- re-click the I(q) button
420// x- be sure that the globals are updated w/ filename
421// x- make a copy of "oldName" that is local and not the SVAR, as the SVAR changes
422//    when the next file is loaded in (if it's not in RawVSANS), resulting in a "skipped" file number
423//
424//displays next (or previous) file in series of run numbers
425//file is read from disk, if path is set and the file number is present
426//increment +1, adds 1 to run number, -1 subtracts one
427//
428// will automatically step a gap of 10 run numbers, but nothing larger. Don't want to loop too long
429// trying to find a file (frustrating), don't want to look past the end of the run numbers (waste)
430// -- may find a more elegant solution later.
431//
432Function V_LoadPlotAndDisplayRAW(increment)
433        Variable increment
434
435        Variable i,val
436        String filename,tmp,curFileName,str
437        //take the currently displayed RAW file
438        SVAR oldName = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
439        oldname = V_RemoveAllSpaces(oldname)            //
440        curFileName = oldName
441       
442        filename = oldname
443
444        i = 1
445        val = increment
446        do
447
448                val = i*increment
449                filename = V_GetPrevNextRawFile(oldName,val)
450               
451//              printf "i=%d, file=%s\r",i,filename
452               
453                tmp = ParseFilePath(0, filename, ":", 1, 0)
454                               
455                i+=1
456        while( strlen(tmp) == 0 && i < 11)
457
458
459        if(strlen(tmp) == 0)            //in some cases, a null string can be returned - handle gracefully
460                return(0)
461        endif
462       
463        // display the specified RAW data file
464        // this is the set of steps done in DisplayMainButtonProc(ctrlName) : ButtonControl
465        Variable err=   V_LoadHDF5Data(filename,"RAW")                  // load the data, set the global w/file name loaded
466//      Print "Load err = "+num2str(err)
467        if(!err)
468                SVAR hdfDF = root:file_name                     // last file loaded, may not be the safest way to pass
469                String folder = StringFromList(0,hdfDF,".")
470               
471                // this (in SANS) just passes directly to fRawWindowHook()
472                V_UpdateDisplayInformation("RAW")       // plot the data in whatever folder type
473               
474                // set the global to display ONLY if the load was called from here, not from the
475                // other routines that load data (to read in values)
476                SVAR gLastLoad = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
477                gLastLoad = hdfDF
478        endif
479
480        //
481        // x- update the 1D plotting as needed. these are SANS calls (OK for now, but will need to be better)
482        //do the average and plot (either the default, or what is on the panel currently)
483        SVAR type = root:Packages:NIST:VSANS:Globals:gCurDispType
484        type = "RAW"
485        V_PlotData_Panel()              // read the binType from the panel
486        Variable binType = V_GetBinningPopMode()
487        ControlInfo/W=V_1D_Data popup0
488        V_BinningModePopup("",binType,S_Value)          // does default circular binning and updates the graph
489
490
491        return(0)
492End
493
494
495// Return the full path:filename that represents the previous or next file.
496// Input is current filename and increment.
497// Increment should be -1 or 1
498// -1 => previous file
499// 1 => next file
500//
501// V_CheckIfRawData(fname)
502//
503Function/S V_GetPrevNextRawFile(curfilename, prevnext)
504        String curfilename
505        Variable prevnext
506
507        String filename
508       
509        //get the run number
510        Variable num = V_GetRunNumFromFile(curfilename)
511               
512        //find the next specified file by number
513        fileName = V_FindFileFromRunNumber(num+prevnext)
514
515        Return filename
516End
517
518
519//returns a string containing the full path to the file containing the
520//run number "num". The null string is returned if no valid file can be found
521//the path "catPathName" used and is hard-wired, will abort if this path does not exist
522//the file returned will be a RAW VSANS data file, other types of files are
523//filtered out.
524//
525//
526// -- with the run numbers incrementing from 1, there is no need to add leading zeros to the
527//    file names. simply add the number and go.
528//
529// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
530//
531Function/S V_FindFileFromRunNumber(num)
532        Variable num
533       
534        String fullName="",partialName="",item=""
535        //get list of raw data files in folder that match "num"
536
537        String numStr=""
538        numStr = num2istr(num)
539
540        //make sure that path exists
541        PathInfo catPathName
542        String path = S_path
543        if (V_flag == 0)
544                Abort "folder path does not exist - use Pick Path button"
545        Endif
546        String list="",newList="",testStr=""
547       
548        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
549        //find (the) one with the number in the run # location in the name
550        Variable numItems,ii,runFound,isRAW
551        numItems = ItemsInList(list,";")                //get the new number of items in the list
552        ii=0
553        do
554                //parse through the list in this order:
555                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
556                // 2 - exclude by isRaw? (to minimize disk access)
557                item = StringFromList(ii, list  ,";" )
558                if(strlen(item) != 0)
559                        //find the run number, if it exists as a three character string
560                        testStr = V_GetRunNumStrFromFile(item)
561                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
562                        if(runFound == 0)
563                                //the run Number was found
564                                //build valid filename
565                                partialName = V_FindValidFileName(item)
566                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
567                                        fullName = path + partialName
568                                        //check if RAW, if so,this must be the file!
569                                        isRAW = V_CheckIfRawData(fullName)
570                                        if(isRaw)
571                                                //print "is raw, ",fullname
572                                                //stop here
573                                                return(fullname)
574                                        Endif
575                                Endif
576                        Endif
577                Endif
578                ii+=1
579        while(ii<numItems)              //process all items in list
580        Return ("")     //null return if file not found in list
581End
582
583//
584//  x- for VSANS Nexus files, how do I quickly identify if a file is
585//   RAW VSANS data? I don't want to generate any errors, but I want to quickly
586//   weed out the reduced data sets, etc. from file catalogs.
587//      (check the instrument name...)
588
589// (DONE) x- as was written by SANS, this function is expecting fname to be the path:fileName
590// - but are the V_get() functions OK with getting a full path, and what do they
591//  do when they fail? I don't want them to spit up another open file dialog
592//
593// x- problem -- if "sans1234.abs" is passed, then V_getStringFromHDF5(fname,path,num)
594//  will remove the extension and look for the sans1234 folder -- which may or may not be present.
595//  If it is present, then sans1234 validates as RAW data -- which is incorrect!
596// x- so I need a way to exclude everything that does not have the proper extension...
597//
598//
599Function V_CheckIfRawData(fname)
600        String fname
601       
602        String testStr=""
603
604// check for the proper raw data extension
605        if( stringmatch(fname,"*.nxs.ngv*") )
606                // name appears OK, proceed
607                testStr = V_getInstrumentName(fname)
608
609                if(cmpstr(testStr,"NG3-VSANS") == 0)
610                        //testStr exists, ASSUMING it's a raw VSANS data file
611                        Return(1)
612                else
613                        //some other file
614                        Return(0)
615                Endif
616       
617        else
618                // not a proper raw VSANS file name
619                return(0)
620               
621        endif   
622       
623
624End
625
626//  x- need to fill in correctly by determining this from the INTENT field
627//
628Function V_isTransFile(fname)
629        String fname
630       
631        Variable refnum,totalBytes
632        String testStr=""
633       
634        testStr = V_getReduction_intent(fname)
635
636        if(cmpstr(testStr,"TRANSMISSION") == 0)         //
637                //yes, a transmission file
638                Return(1)
639        else
640                //some other file intent
641                Return(0)
642        Endif
643End
644
645
646Function V_GetRunNumFromFile(item)
647        String item
648       
649        String str = V_GetRunNumStrFromFile(item)
650       
651        return(str2num(str))
652end
653
654
655// (DONE) x- the file name structure for VSANS file is undecided
656// so some of these base functions will need to change
657//
658//given a filename of a VSANS data filename of the form
659// sansNNNN.nxs.ngv
660//returns the run number "NNNN" as a STRING of (x) characters
661//
662// -- the run number incements from 1, so the number of digits is UNKNOWN
663// -- number starts at position [4] (the 5th character)
664// -- number ends with the character prior to the first "."
665//
666//returns "ABCD" as an invalid file number
667//
668// local function to aid in locating files by run number
669//
670Function/S V_GetRunNumStrFromFile(item)
671        String item
672        String invalid = "ABCD" //"ABCD" is not a valid run number, since it's text
673        Variable num=-1
674       
675        //find the "dot"
676        String runStr=""
677        Variable numChar = 4
678        Variable pos = strsearch(item,".",0)
679        if(pos == -1)
680                //"dot" not found
681                return (invalid)
682        else
683                //found, get the characters preceeding it, but still after the "sans" characters
684                if (pos-1 < 4)
685                        //not enough characters
686                        return (invalid)
687                else
688                        runStr = item[4,pos-1]
689                        return (runStr)
690                Endif
691        Endif
692End
693
694//Function attempts to find valid filename from partial name by checking for
695// the existence of the file on disk.
696// - checks as is
697// - strips spaces
698// - permutations of upper/lowercase
699//
700// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
701// since from marquee, the filename field (textread[0]) must be used, and can be a mix of                       //02JUL13
702// upper/lowercase letters, while the filename on the server (should) be all caps
703// now makes repeated calls to ValidFileString()
704//
705// returns a valid filename (No path prepended) or a null string
706//
707// called by any functions, both external and local
708//
709Function/S V_FindValidFilename(partialName)
710        String PartialName
711       
712        String retStr=""
713       
714        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
715        retStr = V_ValidFileString(partialName)
716        if(cmpstr(retStr,"") !=0)
717                //non-null return
718                return(retStr)
719        Endif
720       
721        //if the partial name is derived from the file header, there can be spaces at the beginning
722        //or in the middle of the filename - depending on the prefix and initials used
723        //
724        //remove any leading spaces from the name before starting
725        partialName = V_RemoveAllSpaces(partialName)
726       
727        //try name with no spaces
728        retStr = V_ValidFileString(partialName)
729        if(cmpstr(retStr,"") !=0)
730                //non-null return
731                return(retStr)
732        Endif
733       
734        //try all UPPERCASE
735        partialName = UpperStr(partialName)
736        retStr = V_ValidFileString(partialName)
737        if(cmpstr(retStr,"") !=0)
738                //non-null return
739                return(retStr)
740        Endif
741       
742        //try all lowercase (ret null if failure)
743        partialName = LowerStr(partialName)
744        retStr = V_ValidFileString(partialName)
745        if(cmpstr(retStr,"") !=0)
746                //non-null return
747                return(retStr)
748        else
749                return(retStr)
750        Endif
751End
752
753
754// Function checks for the existence of a file
755// partialName;vers (to account for VAX filenaming conventions)
756// The partial name is tried first with no version number
757//
758// *** the PATH is hard-wired to catPathName (which is assumed to exist)
759// version numers up to ;10 are tried
760// only the "name;vers" is returned if successful. The path is not prepended
761//
762// local function
763//
764// DONE
765// x- this is essentially a pass-through, since there are no version numbers for VSANS data files
766//    it is kept in case there are conditions in the future.
767//
768Function/S V_ValidFileString(partialName)
769        String partialName
770       
771        String tempName = "",msg=""
772        Variable ii,refnum
773       
774        ii=0
775        do
776                if(ii==0)
777                        //first pass, try the partialName
778                        tempName = partialName
779                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
780                        if(V_flag == 0)
781                                //file exists
782                                Close refnum            //YES needed,
783                                break
784                        endif
785                else
786                        tempName = partialName + ";" + num2istr(ii)
787                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
788                        if(V_flag == 0)
789                                //file exists
790                                Close refnum
791                                break
792                        endif
793                Endif
794                ii+=1
795                //print "ii=",ii
796        while(ii<11)
797        //go get the selected bits of information, using tempName, which exists
798        if(ii>=11)
799                //msg = partialName + " not found. is version number > 11?"
800                //DoAlert 0, msg
801                //PathInfo catPathName
802                //Print S_Path
803                Return ("")             //use null string as error condition
804        Endif
805       
806        Return (tempName)
807End
808
809//function to remove all spaces from names when searching for filenames
810//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
811//but the text field in the header WILL, if less than 3 characters were used for the
812//user's initials, and can have leading spaces if prefix was less than 5 characters
813//
814//returns a string identical to the original string, except with the interior spaces removed
815//
816// local function for file name manipulation
817//
818Function/S V_RemoveAllSpaces(str)
819        String str
820       
821        String tempstr = str
822        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
823        ii=0
824        do
825                len = strlen(tempStr)
826                spc = strsearch(tempStr," ",0)          //is the last character a space?
827                if (spc == -1)
828                        break           //no more spaces found, get out
829                endif
830                str = tempstr
831                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
832        While(1)        //should never be more than 2 or 3
833       
834        If(strlen(tempStr) < 1)
835                tempStr = ""            //be sure to return a null string if problem found
836        Endif
837       
838        //Print strlen(tempstr)
839       
840        Return(tempStr)
841               
842End
843
844// returns a list of raw data files in the catPathName directory on disk
845// - list is SEMICOLON-delimited
846//
847//  decide how to do this...
848// (1)
849// checks each file in the directory to see if it is a RAW data file by
850// call to V_CheckIfRawData() which currently looks for the instrument name in the file.
851// -- CON - this is excruciatingly slow, and by checking a field in the file, has to load in the
852//  ENTIRE data file, and will load EVERY file in the folder. ugh.
853//
854// (2)
855// as was done for VAX files, look for a specific string in the file name as written by the acquisition
856//  (was .saN), now key on ".nxs.ngv"?
857//
858// ** use method (2), reading each file is just way too slow
859//
860//
861Function/S V_GetRawDataFileList()
862       
863        //make sure that path exists
864        PathInfo catPathName
865        if (V_flag == 0)
866                Abort "Folder path does not exist - use Pick Path button on Main Panel"
867        Endif
868        String path = S_Path
869       
870        String list=IndexedFile(catPathName,-1,"????")
871        String newList="",item="",validName="",fullName=""
872        Variable num=ItemsInList(list,";"),ii
873       
874        for(ii=0;ii<num;ii+=1)
875                item = StringFromList(ii, list  ,";")
876
877                validName = V_FindValidFileName(item)
878                if(strlen(validName) != 0)              //non-null return from FindValidFileName()
879                        fullName = path + validName             
880
881        //method (1)                   
882//                      if(V_CheckIfRawData(item))
883//                              newlist += item + ";"
884//                      endif
885
886        //method (2)                   
887                        if( stringmatch(item,"*.nxs.ngv*") )
888                                newlist += item + ";"
889                        endif
890
891                       
892                endif
893                //print "ii=",ii
894        endfor
895        newList = SortList(newList,";",0)
896        return(newList)
897End
898
899//
900//
901// x- does this need to be more sophisticated?
902//
903// simple "not" of V_GetRawDataFileList()
904Function/S V_Get_NotRawDataFileList()
905       
906        //make sure that path exists
907        PathInfo catPathName
908        if (V_flag == 0)
909                Abort "Folder path does not exist - use Pick Path button on Main Panel"
910        Endif
911        String path = S_Path
912       
913        String list=IndexedFile(catPathName,-1,"????")
914        String newList="",item="",validName="",fullName=""
915        Variable num=ItemsInList(list,";"),ii
916       
917        for(ii=0;ii<num;ii+=1)
918                item = StringFromList(ii, list  ,";")
919
920//              validName = V_FindValidFileName(item)
921//              if(strlen(validName) != 0)              //non-null return from FindValidFileName()
922//                      fullName = path + validName             
923
924        //method (2)                   
925                        if( !stringmatch(item,"*.nxs.ngv*") )
926                                newlist += item + ";"
927                        endif
928
929                       
930//              endif
931                //print "ii=",ii
932        endfor
933        newList = SortList(newList,";",0)
934        return(newList)
935End
936
937// removes any item with ".EXT" from the list
938// don't pass the "."
939// returns a modified list
940Function/S V_RemoveEXTFromList(list,ext)
941        String list,ext
942       
943        ext = "*."+ext
944        Variable num=ItemsInList(list,";"),ii
945        String item,newList=""
946       
947        for(ii=0;ii<num;ii+=1)
948                item = StringFromList(ii, list  ,";")
949
950                if( !stringmatch(item,ext) )
951                        newlist += item + ";"
952                endif
953               
954        endfor
955        return(newList)
956End
957
958//the following is a WaveMetrics procedure from <StrMatchList>
959// MatchList(matchStr,list,sep)
960// Returns the items of the list whose items match matchStr
961// The lists are separated by the sep character, usually ";"
962//
963// matchStr may be something like "abc", in which case it is identical to CmpStr
964// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
965//      "*abc" to match anything ending with "abc".
966// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
967//      the pattern.
968// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
969//
970Function/S V_MyMatchList(matchStr,list,sep)
971        String matchStr,list,sep
972        String item,outList=""
973        Variable n=strlen(list)
974        Variable en,st=0
975        do
976                en= strsearch(list,sep,st)
977                if( en < 0 )
978                        if( st < n-1 )
979                                en= n   // no trailing separator
980                                sep=""  // don't put sep in output, either
981                        else
982                                break   // no more items in list
983                        endif
984                endif
985                item=list[st,en-1]
986                if( V_MyStrMatch(matchStr,item) == 0 )
987                        outlist += item+sep
988                Endif
989                st=en+1
990        while (st < n ) // exit is by break, above
991        return outlist
992End
993
994//the following is a WaveMetrics procedure from <StrMatchList>
995// StrMatch(matchStr,str)
996// Returns 0 if the pattern in matchStr matches str, else it returns 1
997//
998// matchStr may be something like "abc", in which case it is identical to CmpStr
999// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
1000//      "*abc" to match anything ending with "abc".
1001// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
1002//      the pattern.
1003// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
1004//
1005Function V_MyStrMatch(matchStr,str)
1006        String matchStr,str
1007        Variable match = 1              // 0 means match
1008        Variable invert= strsearch(matchStr,"!",0) == 0
1009        if( invert )
1010                matchStr[0,0]=""        // remove the "!"
1011        endif
1012        Variable st=0,en=strlen(str)-1
1013        Variable starPos= strsearch(matchStr,"*",0)
1014        if( starPos >= 0 )      // have a star
1015                if( starPos == 0 )      // at start
1016                        matchStr[0,0]=""                                // remove star at start
1017                else                                    // at end
1018                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
1019                endif
1020                Variable len=strlen(matchStr)
1021                if( len > 0 )
1022                        if(starPos == 0)        // star at start, match must be at end
1023                                st=en-len+1
1024                        else
1025                                en=len-1        // star at end, match at start
1026                        endif
1027                else
1028                        str=""  // so that "*" matches anything
1029                endif
1030        endif
1031        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
1032        if( invert )
1033                match= 1-match
1034        endif
1035        return match
1036End
1037
1038
1039//input is a list of run numbers, and output is a list of filenames (not the full path)
1040//*** input list must be COMMA delimited***
1041//output is equivalent to selecting from the CAT table
1042//if some or all of the list items are valid filenames, keep them...
1043//if an error is encountered, notify of the offending element and return a null list
1044//
1045//output is COMMA delimited
1046//
1047// this routine is expecting that the "ask", "none" special cases are handled elsewhere
1048//and not passed here
1049//
1050// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
1051//
1052Function/S V_ParseRunNumberList(list)
1053        String list
1054       
1055        String newList="",item="",tempStr=""
1056        Variable num,ii,runNum
1057       
1058        //expand number ranges, if any
1059        list = V_ExpandNumRanges(list)
1060       
1061        num=itemsinlist(list,",")
1062       
1063        for(ii=0;ii<num;ii+=1)
1064                //get the item
1065                item = StringFromList(ii,list,",")
1066                //is it already a valid filename?
1067                tempStr=V_FindValidFilename(item) //returns filename if good, null if error
1068                if(strlen(tempstr)!=0)
1069                        //valid name, add to list
1070                        //Print "it's a file"
1071                        newList += tempStr + ","
1072                else
1073                        //not a valid name
1074                        //is it a number?
1075                        runNum=str2num(item)
1076                        //print runnum
1077                        if(numtype(runNum) != 0)
1078                                //not a number -  maybe an error                       
1079                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
1080                                return("")
1081                        else
1082                                //a run number or an error
1083                                tempStr = V_GetFileNameFromPathNoSemi( V_FindFileFromRunNumber(runNum) )
1084                                if(strlen(tempstr)==0)
1085                                        //file not found, error
1086                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
1087                                        return("")
1088                                else
1089                                        newList += tempStr + ","
1090                                endif
1091                        endif
1092                endif
1093        endfor          //loop over all items in list
1094       
1095        return(newList)
1096End
1097
1098//takes a comma delimited list that MAY contain number range, and
1099//expands any range of run numbers into a comma-delimited list...
1100//and returns the new list - if not a range, return unchanged
1101//
1102// local function
1103//
1104Function/S V_ExpandNumRanges(list)
1105        String list
1106       
1107        String newList="",dash="-",item,str
1108        Variable num,ii,hasDash
1109       
1110        num=itemsinlist(list,",")
1111//      print num
1112        for(ii=0;ii<num;ii+=1)
1113                //get the item
1114                item = StringFromList(ii,list,",")
1115                //does it contain a dash?
1116                hasDash = strsearch(item,dash,0)                //-1 if no dash found
1117                if(hasDash == -1)
1118                        //not a range, keep it in the list
1119                        newList += item + ","
1120                else
1121                        //has a dash (so it's a range), expand (or add null)
1122                        newList += V_ListFromDash(item)         
1123                endif
1124        endfor
1125       
1126        return newList
1127End
1128
1129//be sure to add a trailing comma to the return string...
1130//
1131// local function
1132//
1133Function/S V_ListFromDash(item)
1134        String item
1135       
1136        String numList="",loStr="",hiStr=""
1137        Variable lo,hi,ii
1138       
1139        loStr=StringFromList(0,item,"-")        //treat the range as a list
1140        hiStr=StringFromList(1,item,"-")
1141        lo=str2num(loStr)
1142        hi=str2num(hiStr)
1143        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
1144                numList=""
1145                return numList
1146        endif
1147        for(ii=lo;ii<=hi;ii+=1)
1148                numList += num2istr(ii) + ","
1149        endfor
1150       
1151        Return numList
1152End
1153
1154//*********************
1155// List utilities
1156//*********************
1157Function/WAVE V_List2TextWave(list,sep,waveStr)
1158        String list,sep,waveStr
1159       
1160        Variable n= ItemsInList(list,sep)
1161        Make/O/T/N=(n) $waveStr= StringFromList(p,list,sep)
1162        return $waveStr
1163End
1164
1165Function/WAVE V_List2NumWave(list,sep,waveStr)
1166        String list,sep,waveStr
1167       
1168        Variable n= ItemsInList(list,sep)
1169        Make/O/D/N=(n) $waveStr= str2num( StringFromList(p,list,sep) )
1170        return $waveStr
1171End
1172
1173Function /S V_TextWave2List(w,sep)
1174        Wave/T w
1175        String sep
1176       
1177        String newList=""
1178        Variable n=numpnts(w),ii=0
1179        do
1180                newList += w[ii] + sep
1181                ii+=1
1182        while(ii<n)
1183        return(newList)
1184End
1185
1186//for numerical waves
1187Function/S V_NumWave2List(w,sep)
1188        Wave w
1189        String sep
1190       
1191        String newList="",temp=""
1192        Variable n=numpnts(w),ii=0,val
1193        do
1194                val=w[ii]
1195                temp=""
1196                sprintf temp,"%g",val
1197                newList += temp
1198                newList += sep
1199                ii+=1
1200        while(ii<n)
1201        return(newList)
1202End
1203
1204
1205/////
1206// @ IgorExchange
1207//TicToc
1208//Posted April 16th, 2009 by bgallarda
1209//      ¥       in Programming 6.10.x
1210
1211////duplicated here -- for VSANS use
1212function v_tic()
1213        variable/G tictoc = startMSTimer
1214end
1215 
1216function v_toc()
1217        NVAR/Z tictoc
1218        variable ttTime = stopMSTimer(tictoc)
1219        printf "%g seconds\r", (ttTime/1e6)
1220        killvariables/Z tictoc
1221end
1222
1223
1224
1225////// methods for filtering out different lists of files.
1226
1227// testStr is the "intent" string, or grep string
1228// method is the method to use to find the file
1229// 0 = (default) is to use the file catalog (= fastest)
1230// 1 = Grep (not terribly slow)
1231// 2 = read every file (bad choice)
1232//
1233Function/S V_getFileIntentList(testStr,method)
1234        String testStr
1235        Variable method
1236       
1237        Variable ii,num
1238        String list="",item="",fname,newList,intent
1239
1240        // read every file...
1241        if(method == 2)
1242                PathInfo catPathName
1243                String path = S_path
1244                newList = V_GetRawDataFileList()
1245                num=ItemsInList(newList)
1246               
1247                for(ii=0;ii<num;ii+=1)
1248                        item=StringFromList(ii, newList , ";")
1249                        fname = path + item
1250                        intent = V_getReduction_intent(fname)
1251                        if(cmpstr(intent,testStr) == 0)
1252                                list += item + ";"
1253                        endif
1254                endfor 
1255        endif
1256       
1257        // use Grep
1258        if(method == 1)
1259                newList = V_GetRawDataFileList()
1260                num=ItemsInList(newList)
1261                for(ii=0;ii<num;ii+=1)
1262                        item=StringFromList(ii, newList , ";")
1263                        Grep/P=catPathName/Q/E=("(?i)"+testStr) item
1264                        if( V_value )   // at least one instance was found
1265        //                              Print "found ", item,ii
1266                                list += item + ";"
1267                        endif
1268                endfor 
1269       
1270        else
1271        // get the list from the file catalog
1272       
1273                WAVE/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
1274                WAVE/T intentW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Intent
1275               
1276                Variable np = numpnts(intentW)          //fileNameW is LONGER - so don't use numpnts(fileWave)
1277                for(ii=0;ii<np;ii+=1)
1278                        if(cmpstr(intentW[ii],testStr)==0)              //this is case-INSENSITIVE (necessary, since the case is unknown)
1279                                list += fileNameW[ii] + ";"
1280                        endif           
1281                endfor
1282               
1283                List = SortList(List,";",0)
1284        endif
1285       
1286        return(list)
1287end
1288
1289
1290// testStr is the "purpose" string, or grep string
1291// method is the method to use to find the file
1292// 0 = (default) is to use the file catalog (= fastest)
1293// 1 = Grep (not terribly slow)
1294// 2 = read every file (bad choice)
1295//
1296Function/S V_getFilePurposeList(testStr,method)
1297        String testStr
1298        Variable method
1299       
1300        Variable ii,num
1301        String list="",item="",fname,newList,purpose
1302
1303        // read every file...
1304        if(method == 2)
1305                PathInfo catPathName
1306                String path = S_path
1307                newList = V_GetRawDataFileList()
1308                num=ItemsInList(newList)
1309               
1310                for(ii=0;ii<num;ii+=1)
1311                        item=StringFromList(ii, newList , ";")
1312                        fname = path + item
1313                        purpose = V_getReduction_purpose(fname)
1314                        if(cmpstr(purpose,testStr) == 0)
1315                                list += item + ";"
1316                        endif
1317                endfor 
1318        endif
1319       
1320        // use Grep
1321        if(method == 1)
1322                newList = V_GetRawDataFileList()
1323                num=ItemsInList(newList)
1324                for(ii=0;ii<num;ii+=1)
1325                        item=StringFromList(ii, newList , ";")
1326                        Grep/P=catPathName/Q/E=("(?i)"+testStr) item
1327                        if( V_value )   // at least one instance was found
1328        //                              Print "found ", item,ii
1329                                list += item + ";"
1330                        endif
1331                endfor 
1332       
1333        else
1334        // get the list from the file catalog
1335       
1336                WAVE/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
1337                WAVE/T purposeW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Purpose
1338               
1339                Variable np = numpnts(purposeW)         //fileNameW is LONGER - so don't use numpnts(fileWave)
1340                for(ii=0;ii<np;ii+=1)
1341                        if(cmpstr(purposeW[ii],testStr)==0)             //this is case-INSENSITIVE (necessary, since the case is unknown)
1342                                list += fileNameW[ii] + ";"
1343                        endif           
1344                endfor
1345               
1346                List = SortList(List,";",0)
1347        endif
1348       
1349        return(list)
1350end
1351
1352
1353// match BOTH the intent and purpose
1354// -- needed to identify the SAMPLE + SCATTERING data files.
1355//
1356//
1357// method is the method to use to find the file (currently ignored, CAT is always used)
1358// 0 = (default) is to use the file catalog (= fastest)
1359// 1 = Grep (not terribly slow)
1360// 2 = read every file (bad choice)
1361//
1362Function/S V_getFileIntentPurposeList(intent,purpose,method)
1363        String intent,purpose
1364        Variable method
1365       
1366        Variable ii,num
1367        String list="",item="",fname,newList
1368
1369//      // read every file...
1370//      if(method == 2)
1371//              PathInfo catPathName
1372//              String path = S_path
1373//              newList = V_GetRawDataFileList()
1374//              num=ItemsInList(newList)
1375//             
1376//              for(ii=0;ii<num;ii+=1)
1377//                      item=StringFromList(ii, newList , ";")
1378//                      fname = path + item
1379//                      purpose = V_getReduction_purpose(fname)
1380//                      if(cmpstr(purpose,testStr) == 0)
1381//                              list += item + ";"
1382//                      endif
1383//              endfor 
1384//      endif
1385//     
1386//      // use Grep
1387//      if(method == 1)
1388//              newList = V_GetRawDataFileList()
1389//              num=ItemsInList(newList)
1390//              for(ii=0;ii<num;ii+=1)
1391//                      item=StringFromList(ii, newList , ";")
1392//                      Grep/P=catPathName/Q/E=("(?i)"+testStr) item
1393//                      if( V_value )   // at least one instance was found
1394//      //                              Print "found ", item,ii
1395//                              list += item + ";"
1396//                      endif
1397//              endfor 
1398//     
1399//      else
1400        // get the list from the file catalog
1401       
1402                WAVE/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
1403                WAVE/T purposeW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Purpose
1404                WAVE/T intentW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Intent
1405               
1406                Variable np = numpnts(purposeW)         //fileNameW is LONGER - so don't use numpnts(fileWave)
1407                for(ii=0;ii<np;ii+=1)
1408                        if(cmpstr(purposeW[ii],purpose)==0 && cmpstr(intentW[ii],intent)==0)            //this is case-INSENSITIVE (necessary, since the case is unknown)
1409                                list += fileNameW[ii] + ";"
1410                        endif           
1411                endfor
1412               
1413                List = SortList(List,";",0)
1414       
1415        return(list)
1416end
1417
1418
1419// match the INTENT and PURPOSE and GROUP_ID
1420//
1421// -- needed to identify the SAMPLE + SCATTERING data files.
1422//
1423//
1424// method is the method to use to find the file (currently ignored, CAT is always used)
1425// 0 = (default) is to use the file catalog (= fastest)
1426// 1 = Grep (not terribly slow)
1427// 2 = read every file (bad choice)
1428//
1429Function/S V_getFileIntentPurposeIDList(intent,purpose,targetID,method)
1430        String intent,purpose
1431        Variable targetID,method
1432       
1433        Variable ii,num
1434        String list="",item="",fname,newList
1435
1436//      // read every file...
1437//      if(method == 2)
1438//              PathInfo catPathName
1439//              String path = S_path
1440//              newList = V_GetRawDataFileList()
1441//              num=ItemsInList(newList)
1442//             
1443//              for(ii=0;ii<num;ii+=1)
1444//                      item=StringFromList(ii, newList , ";")
1445//                      fname = path + item
1446//                      purpose = V_getReduction_purpose(fname)
1447//                      if(cmpstr(purpose,testStr) == 0)
1448//                              list += item + ";"
1449//                      endif
1450//              endfor 
1451//      endif
1452//     
1453//      // use Grep
1454//      if(method == 1)
1455//              newList = V_GetRawDataFileList()
1456//              num=ItemsInList(newList)
1457//              for(ii=0;ii<num;ii+=1)
1458//                      item=StringFromList(ii, newList , ";")
1459//                      Grep/P=catPathName/Q/E=("(?i)"+testStr) item
1460//                      if( V_value )   // at least one instance was found
1461//      //                              Print "found ", item,ii
1462//                              list += item + ";"
1463//                      endif
1464//              endfor 
1465//     
1466//      else
1467        // get the list from the file catalog
1468       
1469                WAVE/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
1470                WAVE/T purposeW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Purpose
1471                WAVE/T intentW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Intent
1472                WAVE groupIDW = root:Packages:NIST:VSANS:CatVSHeaderInfo:group_id
1473               
1474                Variable np = numpnts(purposeW)         //fileNameW is LONGER - so don't use numpnts(fileWave)
1475                for(ii=0;ii<np;ii+=1)
1476                        if(cmpstr(purposeW[ii],purpose)==0 && cmpstr(intentW[ii],intent)==0 && groupIDW[ii]==targetID)          //this is case-INSENSITIVE (necessary, since the case is unknown)
1477                                list += fileNameW[ii] + ";"
1478                        endif           
1479                endfor
1480               
1481                List = SortList(List,";",0)
1482       
1483        return(list)
1484end
1485
1486// from WM procedure, extended to three waves for I(q) data sets
1487//
1488// RemoveNaNsQIS(theQWave, theIWave, theSWave)
1489//      Removes all points in an XYZ triple if any of the three waves has the value NaN.
1490//      A NaN represents a blank or missing value.
1491//      Returns the number of points removed.
1492Function V_RemoveNaNsQIS(theXWave, theYWave, theZWave)
1493        Wave theXWave
1494        Wave theYWave
1495        Wave theZWave
1496
1497        Variable p, numPoints, numNaNs
1498        Variable xval, yval, zval
1499       
1500        numNaNs = 0
1501        p = 0                                                                                   // the loop index
1502        numPoints = numpnts(theXWave)                   // number of times to loop
1503
1504        do
1505                xval = theXWave[p]
1506                yval = theYWave[p]
1507                zval = theZWave[p]
1508                if ((numtype(xval)==2) %| (numtype(yval)==2) %| (numtype(zval)==2) )            // either is NaN?
1509                        numNaNs += 1
1510                else                                                                            // if not an outlier
1511                        theXWave[p - numNaNs] = xval            // copy to input wave
1512                        theYWave[p - numNaNs] = yval            // copy to input wave
1513                        theZWave[p - numNaNs] = zval            // copy to input wave
1514                endif
1515                p += 1
1516        while (p < numPoints)
1517       
1518        // Truncate the wave
1519        DeletePoints numPoints-numNaNs, numNaNs, theXWave, theYWave, theZWave
1520       
1521        return(numNaNs)
1522End
1523
1524
Note: See TracBrowser for help on using the repository browser.