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

Last change on this file since 1246 was 1246, checked in by srkline, 2 years ago

A large number of changes to the size of panels to enable "Laptop Mode" where all of the panels and controls are scaled down so that they fit on screen and are still in correct proportion. For the laptop I'm using for testing, the resolution is 1920x1080. For this, a scaling of 0.7 seems to work. The on/off of the "laptop Mode" is controlled by a checkbox in the preference panel (under the General tab).

There are still more panels to update in the next commit.

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