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

Last change on this file since 1099 was 1099, checked in by srkline, 5 years ago

added Beaucage model to White Beam so that I could model the CFG sample.

cleaned up a few routines to get rid of NaN values in the output I(q) data sets if they were not masked out completely

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