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

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

Adding utilities to calculate transmission. Added V_Transmission.ipf file. Getting the functionality to work, user interface or incorporation into the data reduction protocol is still to be decided.

File size: 33.2 KB
Line 
1#pragma TextEncoding = "MacRoman"               // For details execute DisplayHelpTopic "The TextEncoding Pragma"
2#pragma rtGlobals=3             // Use modern global access method and strict wave access.
3
4//
5//              general utilities
6//
7// for use by multiple panels and packages
8
9
10//prompts user to choose the local folder that contains the SANS Data
11//only one folder can be used, and its path is catPathName (and is a NAME, not a string)
12//this will overwrite the path selection
13//returns 1 if no path selected as error condition, or if user cancelled
14Function V_PickPath()
15       
16        //set the global string to the selected pathname
17        NewPath/O/M="pick the SANS data folder" catPathName
18        if(V_Flag != 0)
19                return(1)               //user cancelled
20        endif
21       
22        PathInfo/S catPathName
23        String dum = S_path
24        String alertStr = ""
25        alertStr = "You must set the path to Charlotte through a Mapped Network Drive, not through the Network Neighborhood"
26        //alertStr += "  Please see the manual for details."
27        if (V_flag == 0)
28                //path does not exist - no folder selected
29                String/G root:Packges:NIST:VSANS:Globals:gCatPathStr = "no folder selected"
30                return(1)
31        else
32        // SRK 2016, for windows 10, try to eliminate this restriction 
33        //---- connecting through the network neighborhood seems to be perfectly fine except for
34        //     path issues with GBLoadWave, which only affects VAX data sets
35               
36//              print igorinfo(3)
37//              //set the global to the path (as a string)
38//              // need 4 \ since it is the escape character
39//              if(cmpstr("\\\\",dum[0,1])==0)  //Windows user going through network neighborhood
40//                      DoAlert 0,alertStr
41//                      KillPath catPathName
42//                      return(1)
43//              endif
44                String/G root:Packges:NIST:VSANS:Globals:gCatPathStr = dum
45                return(0)               //no error
46        endif
47       
48End
49
50//
51// entry from the Main Panel
52//
53Proc V_ChangeDisplay(type)
54        String type
55        Prompt type,"WORK data type to display",popup,"RAW;SAM;EMP;BGD;ADJ;"
56
57// make sure that data exists before passing this on...
58       
59        if(V_DataExists(type) > 0)
60                V_UpdateDisplayInformation(type)
61        else
62                DoAlert 0,"No data in "+type
63        endif
64End
65
66// TODO
67//
68// very simple function to look for something in a work folder
69// -- only checks for FR data to exist, assumes everything else is there
70// -- can't use the V_get() functions, these will try to load data if it's not there!
71Function V_DataExists(type)
72        String type
73       
74        Wave/Z w = $("root:Packages:NIST:VSANS:"+type+":entry:instrument:detector_FR:data")
75       
76        return(WaveExists(w))
77end
78//
79// tests if two values are close enough to each other
80// very useful since ICE came to be
81//
82// tol is an absolute value (since input v1 or v2 may be zero, can't reliably
83// use a percentage
84Function V_CloseEnough(v1,v2,tol)
85        Variable v1, v2, tol
86
87        if(abs(v1-v2) < tol)
88                return(1)
89        else
90                return(0)
91        endif
92End
93
94
95
96// TODO:
97// -- this must be called as needed to force a re-read of the data from disk
98//    "as needed" means that when an operation is done that needs to ensure
99//     a fresh read from disk, it must take care of the kill.
100// -- the ksBaseDFPath needs to be removed. It's currently pointing to RawVSANS, which is
101//    really not used as intended anymore.
102//
103Function V_KillNamedDataFolder(fname)
104        String fname
105       
106        Variable err=0
107       
108        String folderStr = V_GetFileNameFromPathNoSemi(fname)
109        folderStr = V_RemoveDotExtension(folderStr)
110       
111        KillDataFolder/Z $(ksBaseDFPath+folderStr)
112        err = V_flag
113       
114        return(err)
115end
116
117// TODO:
118// x- this still does not quite work. If there are no sub folders present in the RawVSANS folder
119//    it still thinks there is (1) item there.
120// -- if I replace the semicolon with a comma, it thinks there are two folders present and appears
121//    to delete the RawVSANS folder itself! seems very dangerous...this is because DataFolderDir returns
122//    a comma delimited list, but with a semicolon and \r at the end. need to remove these...
123//
124// NOTE -- use V_CleanupData_w_Progress(0,1) to get a progress bar - since this will take more than
125//     a few seconds to complete, especially if a file catalog was done, or a "batch" patching, etc.
126//
127Function V_CleanOutRawVSANS()
128
129        SetDataFolder root:Packages:NIST:VSANS:RawVSANS:
130       
131        // get a list of the data folders there
132        // kill them all if possible
133        String list,item
134        Variable numFolders,ii,pt
135       
136        list = DataFolderDir(1)
137        // this has FOLDERS: at the beginning and is comma-delimited
138        list = list[8,strlen(list)]
139        pt = strsearch(list,";",inf,1)
140        list = list[0,pt-1]                     //remove the ";\r" from the end of the string
141//      print list
142       
143        numFolders = ItemsInList(list , ",")
144//      Print List
145//      print strlen(list)
146
147        for(ii=0;ii<numFolders;ii+=1)
148                item = StringFromList(ii, list ,",")
149//              Print item
150                KillDataFolder/Z $(item)
151        endfor
152
153        list = DataFolderDir(1)
154        list = list[8,strlen(list)]
155        pt = strsearch(list,";",inf,1)
156        list = list[0,pt-1]
157        numFolders = ItemsInList(list, ",")
158        Printf "%g RawVSANS folders could not be killed\r",numFolders
159               
160        SetDataFolder root:
161        return(0)
162End
163
164//
165// examples straight from Wavemetrics help file topic "Progress Windows"
166// Try simpletest(0,0) and simpletest(1,0), simpletest(0,1) and simpletest(1,1)
167//
168//
169// look for simpletest() function in Wavemetrics help file topic "Progress Windows"
170//  this is a modified version.
171//
172// call with (1,1) to get the candystripe bar
173// call with (0,1) to the the "countdown" bar as they are killed
174//
175Function V_CleanupData_w_Progress(indefinite, useIgorDraw)
176        Variable indefinite
177        Variable useIgorDraw            // True to use Igor's own draw method rather than native
178       
179        Variable num,numToClean
180       
181        // is there anything there to be killed?
182        num = V_CleanOutOneRawVSANS()
183        numToClean = num
184        if(num <= 0)
185                return(0)
186        endif
187       
188        // there are some folders to kill, so proceed
189       
190        NewPanel /N=ProgressPanel /W=(285,111,739,193)
191        ValDisplay valdisp0,win=ProgressPanel,pos={18,32},size={342,18},limits={0,num,0},barmisc={0,0}
192        ValDisplay valdisp0,win=ProgressPanel,value= _NUM:0
193        DrawText 20,24,"Cleaning up old files... Please Wait..."
194       
195        if( indefinite )
196                ValDisplay valdisp0,win=ProgressPanel,mode= 4   // candy stripe
197        else
198                ValDisplay valdisp0,win=ProgressPanel,mode= 3   // bar with no fractional part
199        endif
200        if( useIgorDraw )
201                ValDisplay valdisp0,win=ProgressPanel,highColor=(15000,45535,15000)             //(0,65535,0)
202        endif
203        Button bStop,win=ProgressPanel,pos={375,32},size={50,20},title="Stop"
204        DoUpdate /W=ProgressPanel /E=1  // mark this as our progress window
205
206        do
207                num = V_CleanOutOneRawVSANS()
208                if( V_Flag == 2 || num == 0 || num == -1)       // either "stop" or clean exit, or "done" exit from function
209                        break
210                endif
211               
212                ValDisplay valdisp0,win=ProgressPanel,value= _NUM:num,win=ProgressPanel
213                DoUpdate /W=ProgressPanel
214        while(1)
215       
216
217        KillWindow ProgressPanel
218        return(numToClean)
219End
220
221
222// TODO:
223// x- this still does not quite work. If there are no sub folders present in the RawVSANS folder
224//    it still thinks there is (1) item there.
225// -- if I replace the semicolon with a comma, it thinks there are two folders present and appears
226//    to delete the RawVSANS folder itself! seems very dangerous...this is because DataFolderDir returns
227//    a comma delimited list, but with a semicolon and \r at the end. need to remove these...
228//
229// -- for use with progress bar, kills only one folder, returns the new number of folders left
230// -- if n(in) = n(out), nothing was able to be killed, so return "done" code
231Function V_CleanOutOneRawVSANS()
232
233        SetDataFolder root:Packages:NIST:VSANS:RawVSANS:
234       
235        // get a list of the data folders there
236        // kill them all if possible
237        String list,item
238        Variable numFolders,ii,pt,numIn
239       
240        list = DataFolderDir(1)
241        // this has FOLDERS: at the beginning and is comma-delimited
242        list = list[8,strlen(list)]
243        pt = strsearch(list,";",inf,1)
244        list = list[0,pt-1]                     //remove the ";\r" from the end of the string
245//      print list
246       
247        numFolders = ItemsInList(list , ",")
248        numIn = numFolders
249//      Print List
250//      print strlen(list)
251
252        if(numIn > 0)
253                item = StringFromList(0, list ,",")
254//              Print item
255                KillDataFolder/Z $(item)
256        endif
257
258        list = DataFolderDir(1)
259        list = list[8,strlen(list)]
260        pt = strsearch(list,";",inf,1)
261        list = list[0,pt-1]
262        numFolders = ItemsInList(list, ",")
263       
264        if(numIn == numFolders)
265                Printf "%g RawVSANS folders could not be killed\r",numFolders
266                SetDataFolder root:
267
268                return (-1)
269        endif
270       
271        SetDataFolder root:     
272        return(numFolders)
273End
274
275
276
277
278
279//given a filename of a SANS data filename of the form
280// name.anything
281//returns the name as a string without the ".fbdfasga" extension
282//
283// returns the input string if a "." can't be found (maybe it wasn't there)
284Function/S V_RemoveDotExtension(item)
285        String item
286        String invalid = item   //
287        Variable num=-1
288       
289        //find the "dot"
290        String runStr=""
291        Variable pos = strsearch(item,".",0)
292        if(pos == -1)
293                //"dot" not found
294                return (invalid)
295        else
296                //found, get all of the characters preceeding it
297                runStr = item[0,pos-1]
298                return (runStr)
299        Endif
300End
301
302//returns a string containing filename (WITHOUT the ;vers)
303//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
304//with the folders separated by colons
305//
306// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
307//
308Function/S V_GetFileNameFromPathNoSemi(fullPath)
309        String fullPath
310       
311        Variable offset1,offset2
312        String filename=""
313        //String PartialPath
314        offset1 = 0
315        do
316                offset2 = StrSearch(fullPath, ":", offset1)
317                if (offset2 == -1)                              // no more colons ?
318                        fileName = FullPath[offset1,strlen(FullPath) ]
319                        //PartialPath = FullPath[0, offset1-1]
320                        break
321                endif
322                offset1 = offset2+1
323        while (1)
324       
325        //remove version number from name, if it's there - format should be: filename;N
326        filename =  StringFromList(0,filename,";")              //returns null if error
327       
328        Return filename
329End
330
331//
332// -- this was copied directly, no changes , from PlotUtils_Macro_v40
333//
334// returns the path to the file, or null if the user cancelled
335// fancy use of optional parameters
336//
337// enforce short file names (25 characters)
338Function/S V_DoSaveFileDialog(msg,[fname,suffix])
339        String msg,fname,suffix
340        Variable refNum
341//      String message = "Save the file as"
342
343        if(ParamIsDefault(fname))
344//              Print "fname not supplied"
345                fname = ""
346        endif
347        if(ParamIsDefault(suffix))
348//              Print "suffix not supplied"
349                suffix = ""
350        endif
351       
352        String outputPath,tmpName,testStr
353        Variable badLength=0,maxLength=25,l1,l2
354       
355       
356        tmpName = fname + suffix
357       
358        do
359                badLength=0
360                Open/D/M=msg/T="????" refNum as tmpName         //OS will allow 255 characters, but then I can't read it back in!
361                outputPath = S_fileName
362               
363                testStr = ParseFilePath(0, outputPath, ":", 1, 0)               //just the filename
364                if(strlen(testStr)==0)
365                        break           //cancel, allow exit
366                endif
367                if(strlen(testStr) > maxLength)
368                        badlength = 1
369                        DoAlert 2,"File name is too long. Is\r"+testStr[0,maxLength-1]+"\rOK?"
370                        if(V_flag==3)
371                                outputPath = ""
372                                break
373                        endif
374                        if(V_flag==1)                   //my suggested name is OK, so trim the output
375                                badlength=0
376                                l1 = strlen(testStr)            //too long length
377                                l1 = l1-maxLength               //number to trim
378                                //Print outputPath
379                                l2=strlen(outputPath)
380                                outputPath = outputPath[0,l2-1-l1]
381                                //Print "modified  ",outputPath
382                        endif
383                        //if(V_flag==2)  do nothing, let it go around again
384                endif
385               
386        while(badLength)
387       
388        return outputPath
389End
390
391
392
393//
394// this will only load the data into RAW, overwriting whatever is there. no copy is put in rawVSANS
395//
396Function V_LoadAndPlotRAW_wName(fname)
397        String fname
398
399        Variable err=   V_LoadHDF5Data(fname,"RAW")                     // load the data
400//      Print "Load err = "+num2str(err)
401        if(!err)
402                SVAR hdfDF = root:file_name                     // last file loaded, may not be the safest way to pass
403                String folder = StringFromList(0,hdfDF,".")
404               
405                // this (in SANS) just passes directly to fRawWindowHook()
406                V_UpdateDisplayInformation("RAW")               // plot the data in whatever folder type
407                               
408                // set the global to display ONLY if the load was called from here, not from the
409                // other routines that load data (to read in values)
410                SVAR gLastFile =        root:Packages:NIST:VSANS:Globals:gLastLoadedFile
411                gLastFile = hdfDF
412        endif
413End
414
415
416
417//
418// previous/next button needs these functions
419// as well as many other utilities that manipulate the data file names
420// and parse run numbers.
421//
422
423
424// TODO
425// x- load in the proper file
426// x- re-click the I(q) button
427// x- be sure that the globals are updated w/ filename
428// -- getting the file_name from the root: global is a poor choice.
429//     Need a better, more reliable solution than this
430// -- 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
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//      print oldName
451       
452        filename = oldname
453//      for (i = 0; i < abs(increment); i += 1)
454//              filename = GetPrevNextRawFile(filename,increment/abs(increment))
455//      endfor 
456        i = 1
457        val = increment
458        do
459//              print filename,val
460                filename = V_GetPrevNextRawFile(filename,val)
461//              print "new= ",filename
462               
463                val = i*increment
464                i+=1
465                tmp = ParseFilePath(0, filename, ":", 1, 0)
466
467//              print val,strlen(tmp),strlen(oldname)
468//              print cmpstr(tmp,oldname)
469
470                if(strlen(tmp) == 0)            //in some cases, a null string can be returned - handle gracefully
471                        return(0)
472                endif
473               
474        while( (cmpstr(tmp,curFileName) == 0) && i < 11)
475//      print filename
476       
477        // display the specified RAW data file
478        // this is the set of steps done in DisplayMainButtonProc(ctrlName) : ButtonControl
479        Variable err=   V_LoadHDF5Data(filename,"RAW")                  // load the data, set the global w/file name loaded
480//      Print "Load err = "+num2str(err)
481        if(!err)
482                SVAR hdfDF = root:file_name                     // last file loaded, may not be the safest way to pass
483                String folder = StringFromList(0,hdfDF,".")
484               
485                // this (in SANS) just passes directly to fRawWindowHook()
486                V_UpdateDisplayInformation("RAW")       // plot the data in whatever folder type
487               
488                // set the global to display ONLY if the load was called from here, not from the
489                // other routines that load data (to read in values)
490                SVAR gLastLoad = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
491                gLastLoad = hdfDF
492        endif
493
494        // TODO
495        // -- update the 1D plotting as needed. these are SANS calls (OK for now, but will need to be better)
496        //do the average and plot (either the default, or what is on the panel currently)
497        V_PlotData_Panel(-9999)         // read the binType from the panel
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        if(cmpstr(fileName,"")==0)
525                //null return, do nothing
526                fileName = V_FindFileFromRunNumber(num)         //returns the full path, not just curFileName
527        Endif
528
529        Return filename
530End
531
532
533//returns a string containing the full path to the file containing the
534//run number "num". The null string is returned if no valid file can be found
535//the path "catPathName" used and is hard-wired, will abort if this path does not exist
536//the file returned will be a RAW VSANS data file, other types of files are
537//filtered out.
538//
539//
540// -- with the run numbers incrementing from 1, there is no need to add leading zeros to the
541//    file names. simply add the number and go.
542//
543// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
544//
545Function/S V_FindFileFromRunNumber(num)
546        Variable num
547       
548        String fullName="",partialName="",item=""
549        //get list of raw data files in folder that match "num"
550
551        String numStr=""
552        numStr = num2str(num)
553
554        //make sure that path exists
555        PathInfo catPathName
556        String path = S_path
557        if (V_flag == 0)
558                Abort "folder path does not exist - use Pick Path button"
559        Endif
560        String list="",newList="",testStr=""
561       
562        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
563        //find (the) one with the number in the run # location in the name
564        Variable numItems,ii,runFound,isRAW
565        numItems = ItemsInList(list,";")                //get the new number of items in the list
566        ii=0
567        do
568                //parse through the list in this order:
569                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
570                // 2 - exclude by isRaw? (to minimize disk access)
571                item = StringFromList(ii, list  ,";" )
572                if(strlen(item) != 0)
573                        //find the run number, if it exists as a three character string
574                        testStr = V_GetRunNumStrFromFile(item)
575                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
576                        if(runFound == 0)
577                                //the run Number was found
578                                //build valid filename
579                                partialName = V_FindValidFileName(item)
580                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
581                                        fullName = path + partialName
582                                        //check if RAW, if so,this must be the file!
583                                        isRAW = V_CheckIfRawData(fullName)
584                                        if(isRaw)
585                                                //print "is raw, ",fullname
586                                                //stop here
587                                                return(fullname)
588                                        Endif
589                                Endif
590                        Endif
591                Endif
592                ii+=1
593        while(ii<numItems)              //process all items in list
594        Return ("")     //null return if file not found in list
595End
596
597//
598// TODO x- for VSANS Nexus files, how do I quickly identify if a file is
599//   RAW VSANS data? I don't want to generate any errors, but I want to quickly
600//   weed out the reduced data sets, etc. from file catalogs.
601//      (check the instrument name...)
602
603// TODO -- as was written by SANS, this function is expecting fname to be the path:fileName
604// - but are the V_get() functions OK with getting a full path, and what do they
605//  do when they fail? I don't want them to spit up another open file dialog
606//
607// -- problem -- if "sans1234.abs" is passed, then V_getStringFromHDF5(fname,path,num)
608//  will remove the extension and look for the sans1234 folder -- which may or may not be present.
609//  If it is present, then sans1234 validates as RAW data -- which is incorrect!
610// -- so I need a way to exclude everything that does not have the proper extension...
611//
612//
613Function V_CheckIfRawData(fname)
614        String fname
615       
616        String testStr=""
617
618// check for the proper raw data extension
619        if( stringmatch(fname,"*.nxs.ngv*") )
620                // name appears OK, proceed
621                testStr = V_getInstrumentName(fname)
622
623                if(cmpstr(testStr,"NG3-VSANS") == 0)
624                        //testStr exists, ASSUMING it's a raw VSANS data file
625                        Return(1)
626                else
627                        //some other file
628                        Return(0)
629                Endif
630       
631        else
632                // not a proper raw VSANS file name
633                return(0)
634               
635        endif   
636       
637
638End
639
640// TODO -- need to fill in correctly by determining this from the INTENT field
641//
642Function V_isTransFile(fname)
643        String fname
644       
645        Variable refnum,totalBytes
646        String testStr=""
647       
648//      testStr = V_getInstrumentName(fname)
649
650        if(cmpstr(testStr,"NG3-VSANS") == 0)            //wrong test
651                //testStr exists, ASSUMING it's a raw VSANS data file
652                Return(1)
653        else
654                //some other file
655                Return(0)
656        Endif
657End
658
659
660Function V_GetRunNumFromFile(item)
661        String item
662       
663        String str = V_GetRunNumStrFromFile(item)
664       
665        return(str2num(str))
666end
667
668
669// TODO -- the file name structure for VSANS file is undecided
670// so some of these base functions will need to change
671//
672//given a filename of a VSANS data filename of the form
673// sansNNNN.nxs.ngv
674//returns the run number "NNNN" as a STRING of (x) characters
675//
676// -- the run number incements from 1, so the number of digits is UNKNOWN
677// -- number starts at position [4] (the 5th character)
678// -- number ends with the character prior to the first "."
679//
680//returns "ABCD" as an invalid file number
681//
682// local function to aid in locating files by run number
683//
684Function/S V_GetRunNumStrFromFile(item)
685        String item
686        String invalid = "ABCD" //"ABCD" is not a valid run number, since it's text
687        Variable num=-1
688       
689        //find the "dot"
690        String runStr=""
691        Variable numChar = 4
692        Variable pos = strsearch(item,".",0)
693        if(pos == -1)
694                //"dot" not found
695                return (invalid)
696        else
697                //found, get the characters preceeding it, but still after the "sans" characters
698                if (pos-1 < 4)
699                        //not enough characters
700                        return (invalid)
701                else
702                        runStr = item[4,pos-1]
703                        return (runStr)
704                Endif
705        Endif
706End
707
708//Function attempts to find valid filename from partial name by checking for
709// the existence of the file on disk.
710// - checks as is
711// - strips spaces
712// - permutations of upper/lowercase
713//
714// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
715// since from marquee, the filename field (textread[0]) must be used, and can be a mix of                       //02JUL13
716// upper/lowercase letters, while the filename on the server (should) be all caps
717// now makes repeated calls to ValidFileString()
718//
719// returns a valid filename (No path prepended) or a null string
720//
721// called by any functions, both external and local
722//
723Function/S V_FindValidFilename(partialName)
724        String PartialName
725       
726        String retStr=""
727       
728        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
729        retStr = V_ValidFileString(partialName)
730        if(cmpstr(retStr,"") !=0)
731                //non-null return
732                return(retStr)
733        Endif
734       
735        //if the partial name is derived from the file header, there can be spaces at the beginning
736        //or in the middle of the filename - depending on the prefix and initials used
737        //
738        //remove any leading spaces from the name before starting
739        partialName = V_RemoveAllSpaces(partialName)
740       
741        //try name with no spaces
742        retStr = V_ValidFileString(partialName)
743        if(cmpstr(retStr,"") !=0)
744                //non-null return
745                return(retStr)
746        Endif
747       
748        //try all UPPERCASE
749        partialName = UpperStr(partialName)
750        retStr = V_ValidFileString(partialName)
751        if(cmpstr(retStr,"") !=0)
752                //non-null return
753                return(retStr)
754        Endif
755       
756        //try all lowercase (ret null if failure)
757        partialName = LowerStr(partialName)
758        retStr = V_ValidFileString(partialName)
759        if(cmpstr(retStr,"") !=0)
760                //non-null return
761                return(retStr)
762        else
763                return(retStr)
764        Endif
765End
766
767
768// Function checks for the existence of a file
769// partialName;vers (to account for VAX filenaming conventions)
770// The partial name is tried first with no version number
771//
772// *** the PATH is hard-wired to catPathName (which is assumed to exist)
773// version numers up to ;10 are tried
774// only the "name;vers" is returned if successful. The path is not prepended
775//
776// local function
777//
778// TODO -- is this really necessary anymore for the NON-VAX files of VSANS.
779// -- can this be made a pass-through, or will there be another function that is needed for VSANS?
780//
781Function/S V_ValidFileString(partialName)
782        String partialName
783       
784        String tempName = "",msg=""
785        Variable ii,refnum
786       
787        ii=0
788        do
789                if(ii==0)
790                        //first pass, try the partialName
791                        tempName = partialName
792                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
793                        if(V_flag == 0)
794                                //file exists
795                                Close refnum            //YES needed,
796                                break
797                        endif
798                else
799                        tempName = partialName + ";" + num2str(ii)
800                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
801                        if(V_flag == 0)
802                                //file exists
803                                Close refnum
804                                break
805                        endif
806                Endif
807                ii+=1
808                //print "ii=",ii
809        while(ii<11)
810        //go get the selected bits of information, using tempName, which exists
811        if(ii>=11)
812                //msg = partialName + " not found. is version number > 11?"
813                //DoAlert 0, msg
814                //PathInfo catPathName
815                //Print S_Path
816                Return ("")             //use null string as error condition
817        Endif
818       
819        Return (tempName)
820End
821
822//function to remove all spaces from names when searching for filenames
823//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
824//but the text field in the header WILL, if less than 3 characters were used for the
825//user's initials, and can have leading spaces if prefix was less than 5 characters
826//
827//returns a string identical to the original string, except with the interior spaces removed
828//
829// local function for file name manipulation
830//
831Function/S V_RemoveAllSpaces(str)
832        String str
833       
834        String tempstr = str
835        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
836        ii=0
837        do
838                len = strlen(tempStr)
839                spc = strsearch(tempStr," ",0)          //is the last character a space?
840                if (spc == -1)
841                        break           //no more spaces found, get out
842                endif
843                str = tempstr
844                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
845        While(1)        //should never be more than 2 or 3
846       
847        If(strlen(tempStr) < 1)
848                tempStr = ""            //be sure to return a null string if problem found
849        Endif
850       
851        //Print strlen(tempstr)
852       
853        Return(tempStr)
854               
855End
856
857// returns a list of raw data files in the catPathName directory on disk
858// - list is SEMICOLON-delimited
859//
860// TODO: decide how to do this...
861// (1)
862// checks each file in the directory to see if it is a RAW data file by
863// call to V_CheckIfRawData() which currently looks for the instrument name in the file.
864// -- CON - this is excruciatingly slow, and by checking a field in the file, has to load in the
865//  ENTIRE data file, and will load EVERY file in the folder. ugh.
866//
867// (2)
868// as was done for VAX files, look for a specific string in the file name as written by the acquisition
869//  (was .saN), now key on ".nxs.ngv"?
870//
871// called by PatchFiles.ipf, Tile_2D.ipf
872//
873Function/S V_GetRawDataFileList()
874       
875        //make sure that path exists
876        PathInfo catPathName
877        if (V_flag == 0)
878                Abort "Folder path does not exist - use Pick Path button on Main Panel"
879        Endif
880        String path = S_Path
881       
882        String list=IndexedFile(catPathName,-1,"????")
883        String newList="",item="",validName="",fullName=""
884        Variable num=ItemsInList(list,";"),ii
885       
886        for(ii=0;ii<num;ii+=1)
887                item = StringFromList(ii, list  ,";")
888
889                validName = V_FindValidFileName(item)
890                if(strlen(validName) != 0)              //non-null return from FindValidFileName()
891                        fullName = path + validName             
892
893        //method (1)                   
894//                      if(V_CheckIfRawData(item))
895//                              newlist += item + ";"
896//                      endif
897
898        //method (2)                   
899                        if( stringmatch(item,"*.nxs.ngv*") )
900                                newlist += item + ";"
901                        endif
902
903                       
904                endif
905                //print "ii=",ii
906        endfor
907        newList = SortList(newList,";",0)
908        return(newList)
909End
910
911//
912// TODO:
913// -- does this need to be more sophisticated?
914//
915// simple "not" of V_GetRawDataFileList()
916Function/S V_Get_NotRawDataFileList()
917       
918        //make sure that path exists
919        PathInfo catPathName
920        if (V_flag == 0)
921                Abort "Folder path does not exist - use Pick Path button on Main Panel"
922        Endif
923        String path = S_Path
924       
925        String list=IndexedFile(catPathName,-1,"????")
926        String newList="",item="",validName="",fullName=""
927        Variable num=ItemsInList(list,";"),ii
928       
929        for(ii=0;ii<num;ii+=1)
930                item = StringFromList(ii, list  ,";")
931
932//              validName = V_FindValidFileName(item)
933//              if(strlen(validName) != 0)              //non-null return from FindValidFileName()
934//                      fullName = path + validName             
935
936        //method (2)                   
937                        if( !stringmatch(item,"*.nxs.ngv*") )
938                                newlist += item + ";"
939                        endif
940
941                       
942//              endif
943                //print "ii=",ii
944        endfor
945        newList = SortList(newList,";",0)
946        return(newList)
947End
948
949
950//the following is a WaveMetrics procedure from <StrMatchList>
951// MatchList(matchStr,list,sep)
952// Returns the items of the list whose items match matchStr
953// The lists are separated by the sep character, usually ";"
954//
955// matchStr may be something like "abc", in which case it is identical to CmpStr
956// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
957//      "*abc" to match anything ending with "abc".
958// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
959//      the pattern.
960// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
961//
962Function/S V_MyMatchList(matchStr,list,sep)
963        String matchStr,list,sep
964        String item,outList=""
965        Variable n=strlen(list)
966        Variable en,st=0
967        do
968                en= strsearch(list,sep,st)
969                if( en < 0 )
970                        if( st < n-1 )
971                                en= n   // no trailing separator
972                                sep=""  // don't put sep in output, either
973                        else
974                                break   // no more items in list
975                        endif
976                endif
977                item=list[st,en-1]
978                if( V_MyStrMatch(matchStr,item) == 0 )
979                        outlist += item+sep
980                Endif
981                st=en+1
982        while (st < n ) // exit is by break, above
983        return outlist
984End
985
986//the following is a WaveMetrics procedure from <StrMatchList>
987// StrMatch(matchStr,str)
988// Returns 0 if the pattern in matchStr matches str, else it returns 1
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 V_MyStrMatch(matchStr,str)
998        String matchStr,str
999        Variable match = 1              // 0 means match
1000        Variable invert= strsearch(matchStr,"!",0) == 0
1001        if( invert )
1002                matchStr[0,0]=""        // remove the "!"
1003        endif
1004        Variable st=0,en=strlen(str)-1
1005        Variable starPos= strsearch(matchStr,"*",0)
1006        if( starPos >= 0 )      // have a star
1007                if( starPos == 0 )      // at start
1008                        matchStr[0,0]=""                                // remove star at start
1009                else                                    // at end
1010                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
1011                endif
1012                Variable len=strlen(matchStr)
1013                if( len > 0 )
1014                        if(starPos == 0)        // star at start, match must be at end
1015                                st=en-len+1
1016                        else
1017                                en=len-1        // star at end, match at start
1018                        endif
1019                else
1020                        str=""  // so that "*" matches anything
1021                endif
1022        endif
1023        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
1024        if( invert )
1025                match= 1-match
1026        endif
1027        return match
1028End
1029
1030
1031//input is a list of run numbers, and output is a list of filenames (not the full path)
1032//*** input list must be COMMA delimited***
1033//output is equivalent to selecting from the CAT table
1034//if some or all of the list items are valid filenames, keep them...
1035//if an error is encountered, notify of the offending element and return a null list
1036//
1037//output is COMMA delimited
1038//
1039// this routine is expecting that the "ask", "none" special cases are handled elsewhere
1040//and not passed here
1041//
1042// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
1043//
1044Function/S V_ParseRunNumberList(list)
1045        String list
1046       
1047        String newList="",item="",tempStr=""
1048        Variable num,ii,runNum
1049       
1050        //expand number ranges, if any
1051        list = V_ExpandNumRanges(list)
1052       
1053        num=itemsinlist(list,",")
1054       
1055        for(ii=0;ii<num;ii+=1)
1056                //get the item
1057                item = StringFromList(ii,list,",")
1058                //is it already a valid filename?
1059                tempStr=V_FindValidFilename(item) //returns filename if good, null if error
1060                if(strlen(tempstr)!=0)
1061                        //valid name, add to list
1062                        //Print "it's a file"
1063                        newList += tempStr + ","
1064                else
1065                        //not a valid name
1066                        //is it a number?
1067                        runNum=str2num(item)
1068                        //print runnum
1069                        if(numtype(runNum) != 0)
1070                                //not a number -  maybe an error                       
1071                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
1072                                return("")
1073                        else
1074                                //a run number or an error
1075                                tempStr = V_GetFileNameFromPathNoSemi( V_FindFileFromRunNumber(runNum) )
1076                                if(strlen(tempstr)==0)
1077                                        //file not found, error
1078                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
1079                                        return("")
1080                                else
1081                                        newList += tempStr + ","
1082                                endif
1083                        endif
1084                endif
1085        endfor          //loop over all items in list
1086       
1087        return(newList)
1088End
1089
1090//takes a comma delimited list that MAY contain number range, and
1091//expands any range of run numbers into a comma-delimited list...
1092//and returns the new list - if not a range, return unchanged
1093//
1094// local function
1095//
1096Function/S V_ExpandNumRanges(list)
1097        String list
1098       
1099        String newList="",dash="-",item,str
1100        Variable num,ii,hasDash
1101       
1102        num=itemsinlist(list,",")
1103//      print num
1104        for(ii=0;ii<num;ii+=1)
1105                //get the item
1106                item = StringFromList(ii,list,",")
1107                //does it contain a dash?
1108                hasDash = strsearch(item,dash,0)                //-1 if no dash found
1109                if(hasDash == -1)
1110                        //not a range, keep it in the list
1111                        newList += item + ","
1112                else
1113                        //has a dash (so it's a range), expand (or add null)
1114                        newList += V_ListFromDash(item)         
1115                endif
1116        endfor
1117       
1118        return newList
1119End
1120
1121//be sure to add a trailing comma to the return string...
1122//
1123// local function
1124//
1125Function/S V_ListFromDash(item)
1126        String item
1127       
1128        String numList="",loStr="",hiStr=""
1129        Variable lo,hi,ii
1130       
1131        loStr=StringFromList(0,item,"-")        //treat the range as a list
1132        hiStr=StringFromList(1,item,"-")
1133        lo=str2num(loStr)
1134        hi=str2num(hiStr)
1135        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
1136                numList=""
1137                return numList
1138        endif
1139        for(ii=lo;ii<=hi;ii+=1)
1140                numList += num2str(ii) + ","
1141        endfor
1142       
1143        Return numList
1144End
1145
1146//*********************
1147// List utilities
1148//*********************
1149Function/WAVE V_List2TextWave(list,sep,waveStr)
1150        String list,sep,waveStr
1151       
1152        Variable n= ItemsInList(list,sep)
1153        Make/O/T/N=(n) $waveStr= StringFromList(p,list,sep)
1154        return $waveStr
1155End
1156
1157Function/WAVE V_List2NumWave(list,sep,waveStr)
1158        String list,sep,waveStr
1159       
1160        Variable n= ItemsInList(list,sep)
1161        Make/O/D/N=(n) $waveStr= str2num( StringFromList(p,list,sep) )
1162        return $waveStr
1163End
1164
1165Function /S V_TextWave2List(w,sep)
1166        Wave/T w
1167        String sep
1168       
1169        String newList=""
1170        Variable n=numpnts(w),ii=0
1171        do
1172                newList += w[ii] + sep
1173                ii+=1
1174        while(ii<n)
1175        return(newList)
1176End
1177
1178//for numerical waves
1179Function/S V_NumWave2List(w,sep)
1180        Wave w
1181        String sep
1182       
1183        String newList="",temp=""
1184        Variable n=numpnts(w),ii=0,val
1185        do
1186                val=w[ii]
1187                temp=""
1188                sprintf temp,"%g",val
1189                newList += temp
1190                newList += sep
1191                ii+=1
1192        while(ii<n)
1193        return(newList)
1194End
Note: See TracBrowser for help on using the repository browser.