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

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

cleaning up a lot of the TODO items from the code.

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