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

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

adding to the functionality of the data reduction protocol

getting the 1D plotting to work both as a standalone plot and part of the reduction protocol (where the choices are all made and fed in)

added log/lin toggle to 1D display. abc exponent scaling is fundamentally more messy, and has been shelved for now. Revisit if demand is there.

fixed bug in how raw data files are identified, to prevent .abs files from being incorrectly identified as raw (if same name before extension). Works correctly now, but may need tweak in future if naming scheme changes.

File size: 31.5 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// previous/next button needs these functions
395// as well as many other utilities that manipulate the data file names
396// and parse run numbers.
397//
398
399
400// TODO
401// x- load in the proper file
402// x- re-click the I(q) button
403// x- be sure that the globals are updated w/ filename
404// -- getting the file_name from the root: global is a poor choice.
405//     Need a better, more reliable solution than this
406// -- make a copy of "oldName" that is local and not the SVAR, as the SVAR changes
407//    when the next file is loaded in (if it's not in RawVSANS), resulting in a "skipped" file number
408//
409//displays next (or previous) file in series of run numbers
410//file is read from disk, if path is set and the file number is present
411//increment +1, adds 1 to run number, -1 subtracts one
412//
413// will automatically step a gap of 10 run numbers, but nothing larger. Don't want to loop too long
414// trying to find a file (frustrating), don't want to look past the end of the run numbers (waste)
415// -- may find a more elegant solution later.
416//
417Function V_LoadPlotAndDisplayRAW(increment)
418        Variable increment
419
420        Variable i,val
421        String filename,tmp,curFileName
422        //take the currently displayed RAW file
423        SVAR oldName = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
424        oldname = V_RemoveAllSpaces(oldname)            //
425        curFileName = oldName
426//      print oldName
427       
428        filename = oldname
429//      for (i = 0; i < abs(increment); i += 1)
430//              filename = GetPrevNextRawFile(filename,increment/abs(increment))
431//      endfor 
432        i = 1
433        val = increment
434        do
435//              print filename,val
436                filename = V_GetPrevNextRawFile(filename,val)
437//              print "new= ",filename
438               
439                val = i*increment
440                i+=1
441                tmp = ParseFilePath(0, filename, ":", 1, 0)
442
443//              print val,strlen(tmp),strlen(oldname)
444//              print cmpstr(tmp,oldname)
445
446                if(strlen(tmp) == 0)            //in some cases, a null string can be returned - handle gracefully
447                        return(0)
448                endif
449               
450        while( (cmpstr(tmp,curFileName) == 0) && i < 11)
451//      print filename
452       
453        // display the specified RAW data file
454        // this is the set of steps done in DisplayMainButtonProc(ctrlName) : ButtonControl
455        Variable err=   V_LoadHDF5Data(filename,"RAW")                  // load the data, set the global w/file name loaded
456//      Print "Load err = "+num2str(err)
457        if(!err)
458                SVAR hdfDF = root:file_name                     // last file loaded, may not be the safest way to pass
459                String folder = StringFromList(0,hdfDF,".")
460               
461                // this (in SANS) just passes directly to fRawWindowHook()
462                V_UpdateDisplayInformation("RAW")       // plot the data in whatever folder type
463               
464                // set the global to display ONLY if the load was called from here, not from the
465                // other routines that load data (to read in values)
466                SVAR gLastLoad = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
467                gLastLoad = hdfDF
468        endif
469
470        // TODO
471        // -- update the 1D plotting as needed. these are SANS calls (OK for now, but will need to be better)
472        //do the average and plot (either the default, or what is on the panel currently)
473        V_PlotData_Panel(-9999)         // read the binType from the panel
474       
475
476        return(0)
477End
478
479
480// Return the full path:filename that represents the previous or next file.
481// Input is current filename and increment.
482// Increment should be -1 or 1
483// -1 => previous file
484// 1 => next file
485//
486// V_CheckIfRawData(fname)
487//
488Function/S V_GetPrevNextRawFile(curfilename, prevnext)
489        String curfilename
490        Variable prevnext
491
492        String filename
493       
494        //get the run number
495        Variable num = V_GetRunNumFromFile(curfilename)
496               
497        //find the next specified file by number
498        fileName = V_FindFileFromRunNumber(num+prevnext)
499
500        if(cmpstr(fileName,"")==0)
501                //null return, do nothing
502                fileName = V_FindFileFromRunNumber(num)         //returns the full path, not just curFileName
503        Endif
504
505        Return filename
506End
507
508
509//returns a string containing the full path to the file containing the
510//run number "num". The null string is returned if no valid file can be found
511//the path "catPathName" used and is hard-wired, will abort if this path does not exist
512//the file returned will be a RAW VSANS data file, other types of files are
513//filtered out.
514//
515//
516// -- with the run numbers incrementing from 1, there is no need to add leading zeros to the
517//    file names. simply add the number and go.
518//
519// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
520//
521Function/S V_FindFileFromRunNumber(num)
522        Variable num
523       
524        String fullName="",partialName="",item=""
525        //get list of raw data files in folder that match "num"
526
527        String numStr=""
528        numStr = num2str(num)
529
530        //make sure that path exists
531        PathInfo catPathName
532        String path = S_path
533        if (V_flag == 0)
534                Abort "folder path does not exist - use Pick Path button"
535        Endif
536        String list="",newList="",testStr=""
537       
538        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
539        //find (the) one with the number in the run # location in the name
540        Variable numItems,ii,runFound,isRAW
541        numItems = ItemsInList(list,";")                //get the new number of items in the list
542        ii=0
543        do
544                //parse through the list in this order:
545                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
546                // 2 - exclude by isRaw? (to minimize disk access)
547                item = StringFromList(ii, list  ,";" )
548                if(strlen(item) != 0)
549                        //find the run number, if it exists as a three character string
550                        testStr = V_GetRunNumStrFromFile(item)
551                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
552                        if(runFound == 0)
553                                //the run Number was found
554                                //build valid filename
555                                partialName = V_FindValidFileName(item)
556                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
557                                        fullName = path + partialName
558                                        //check if RAW, if so,this must be the file!
559                                        isRAW = V_CheckIfRawData(fullName)
560                                        if(isRaw)
561                                                //print "is raw, ",fullname
562                                                //stop here
563                                                return(fullname)
564                                        Endif
565                                Endif
566                        Endif
567                Endif
568                ii+=1
569        while(ii<numItems)              //process all items in list
570        Return ("")     //null return if file not found in list
571End
572
573//
574// TODO x- for VSANS Nexus files, how do I quickly identify if a file is
575//   RAW VSANS data? I don't want to generate any errors, but I want to quickly
576//   weed out the reduced data sets, etc. from file catalogs.
577//      (check the instrument name...)
578
579// TODO -- as was written by SANS, this function is expecting fname to be the path:fileName
580// - but are the V_get() functions OK with getting a full path, and what do they
581//  do when they fail? I don't want them to spit up another open file dialog
582//
583// -- problem -- if "sans1234.abs" is passed, then V_getStringFromHDF5(fname,path,num)
584//  will remove the extension and look for the sans1234 folder -- which may or may not be present.
585//  If it is present, then sans1234 validates as RAW data -- which is incorrect!
586// -- so I need a way to exclude everything that does not have the proper extension...
587//
588//
589Function V_CheckIfRawData(fname)
590        String fname
591       
592        String testStr=""
593
594// check for the proper raw data extension
595        if( stringmatch(fname,"*.nxs.ngv*") )
596                // name appears OK, proceed
597                testStr = V_getInstrumentName(fname)
598
599                if(cmpstr(testStr,"NG3-VSANS") == 0)
600                        //testStr exists, ASSUMING it's a raw VSANS data file
601                        Return(1)
602                else
603                        //some other file
604                        Return(0)
605                Endif
606       
607        else
608                // not a proper raw VSANS file name
609                return(0)
610               
611        endif   
612       
613
614End
615
616// TODO -- need to fill in correctly by determining this from the INTENT field
617//
618Function V_isTransFile(fname)
619        String fname
620       
621        Variable refnum,totalBytes
622        String testStr=""
623       
624//      testStr = V_getInstrumentName(fname)
625
626        if(cmpstr(testStr,"NG3-VSANS") == 0)            //wrong test
627                //testStr exists, ASSUMING it's a raw VSANS data file
628                Return(1)
629        else
630                //some other file
631                Return(0)
632        Endif
633End
634
635
636Function V_GetRunNumFromFile(item)
637        String item
638       
639        String str = V_GetRunNumStrFromFile(item)
640       
641        return(str2num(str))
642end
643
644
645// TODO -- the file name structure for VSANS file is undecided
646// so some of these base functions will need to change
647//
648//given a filename of a VSANS data filename of the form
649// sansNNNN.nxs.ngv
650//returns the run number "NNNN" as a STRING of (x) characters
651//
652// -- the run number incements from 1, so the number of digits is UNKNOWN
653// -- number starts at position [4] (the 5th character)
654// -- number ends with the character prior to the first "."
655//
656//returns "ABCD" as an invalid file number
657//
658// local function to aid in locating files by run number
659//
660Function/S V_GetRunNumStrFromFile(item)
661        String item
662        String invalid = "ABCD" //"ABCD" is not a valid run number, since it's text
663        Variable num=-1
664       
665        //find the "dot"
666        String runStr=""
667        Variable numChar = 4
668        Variable pos = strsearch(item,".",0)
669        if(pos == -1)
670                //"dot" not found
671                return (invalid)
672        else
673                //found, get the characters preceeding it, but still after the "sans" characters
674                if (pos-1 < 4)
675                        //not enough characters
676                        return (invalid)
677                else
678                        runStr = item[4,pos-1]
679                        return (runStr)
680                Endif
681        Endif
682End
683
684//Function attempts to find valid filename from partial name by checking for
685// the existence of the file on disk.
686// - checks as is
687// - strips spaces
688// - permutations of upper/lowercase
689//
690// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
691// since from marquee, the filename field (textread[0]) must be used, and can be a mix of                       //02JUL13
692// upper/lowercase letters, while the filename on the server (should) be all caps
693// now makes repeated calls to ValidFileString()
694//
695// returns a valid filename (No path prepended) or a null string
696//
697// called by any functions, both external and local
698//
699Function/S V_FindValidFilename(partialName)
700        String PartialName
701       
702        String retStr=""
703       
704        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
705        retStr = V_ValidFileString(partialName)
706        if(cmpstr(retStr,"") !=0)
707                //non-null return
708                return(retStr)
709        Endif
710       
711        //if the partial name is derived from the file header, there can be spaces at the beginning
712        //or in the middle of the filename - depending on the prefix and initials used
713        //
714        //remove any leading spaces from the name before starting
715        partialName = V_RemoveAllSpaces(partialName)
716       
717        //try name with no spaces
718        retStr = V_ValidFileString(partialName)
719        if(cmpstr(retStr,"") !=0)
720                //non-null return
721                return(retStr)
722        Endif
723       
724        //try all UPPERCASE
725        partialName = UpperStr(partialName)
726        retStr = V_ValidFileString(partialName)
727        if(cmpstr(retStr,"") !=0)
728                //non-null return
729                return(retStr)
730        Endif
731       
732        //try all lowercase (ret null if failure)
733        partialName = LowerStr(partialName)
734        retStr = V_ValidFileString(partialName)
735        if(cmpstr(retStr,"") !=0)
736                //non-null return
737                return(retStr)
738        else
739                return(retStr)
740        Endif
741End
742
743
744// Function checks for the existence of a file
745// partialName;vers (to account for VAX filenaming conventions)
746// The partial name is tried first with no version number
747//
748// *** the PATH is hard-wired to catPathName (which is assumed to exist)
749// version numers up to ;10 are tried
750// only the "name;vers" is returned if successful. The path is not prepended
751//
752// local function
753//
754// TODO -- is this really necessary anymore for the NON-VAX files of VSANS.
755// -- can this be made a pass-through, or will there be another function that is needed for VSANS?
756//
757Function/S V_ValidFileString(partialName)
758        String partialName
759       
760        String tempName = "",msg=""
761        Variable ii,refnum
762       
763        ii=0
764        do
765                if(ii==0)
766                        //first pass, try the partialName
767                        tempName = partialName
768                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
769                        if(V_flag == 0)
770                                //file exists
771                                Close refnum            //YES needed,
772                                break
773                        endif
774                else
775                        tempName = partialName + ";" + num2str(ii)
776                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
777                        if(V_flag == 0)
778                                //file exists
779                                Close refnum
780                                break
781                        endif
782                Endif
783                ii+=1
784                //print "ii=",ii
785        while(ii<11)
786        //go get the selected bits of information, using tempName, which exists
787        if(ii>=11)
788                //msg = partialName + " not found. is version number > 11?"
789                //DoAlert 0, msg
790                //PathInfo catPathName
791                //Print S_Path
792                Return ("")             //use null string as error condition
793        Endif
794       
795        Return (tempName)
796End
797
798//function to remove all spaces from names when searching for filenames
799//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
800//but the text field in the header WILL, if less than 3 characters were used for the
801//user's initials, and can have leading spaces if prefix was less than 5 characters
802//
803//returns a string identical to the original string, except with the interior spaces removed
804//
805// local function for file name manipulation
806//
807Function/S V_RemoveAllSpaces(str)
808        String str
809       
810        String tempstr = str
811        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
812        ii=0
813        do
814                len = strlen(tempStr)
815                spc = strsearch(tempStr," ",0)          //is the last character a space?
816                if (spc == -1)
817                        break           //no more spaces found, get out
818                endif
819                str = tempstr
820                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
821        While(1)        //should never be more than 2 or 3
822       
823        If(strlen(tempStr) < 1)
824                tempStr = ""            //be sure to return a null string if problem found
825        Endif
826       
827        //Print strlen(tempstr)
828       
829        Return(tempStr)
830               
831End
832
833// returns a list of raw data files in the catPathName directory on disk
834// - list is SEMICOLON-delimited
835//
836// TODO: decide how to do this...
837// (1)
838// checks each file in the directory to see if it is a RAW data file by
839// call to V_CheckIfRawData() which currently looks for the instrument name in the file.
840// -- CON - this is excruciatingly slow, and by checking a field in the file, has to load in the
841//  ENTIRE data file, and will load EVERY file in the folder. ugh.
842//
843// (2)
844// as was done for VAX files, look for a specific string in the file name as written by the acquisition
845//  (was .saN), now key on ".nxs.ngv"?
846//
847// called by PatchFiles.ipf, Tile_2D.ipf
848//
849Function/S V_GetRawDataFileList()
850       
851        //make sure that path exists
852        PathInfo catPathName
853        if (V_flag == 0)
854                Abort "Folder path does not exist - use Pick Path button on Main Panel"
855        Endif
856        String path = S_Path
857       
858        String list=IndexedFile(catPathName,-1,"????")
859        String newList="",item="",validName="",fullName=""
860        Variable num=ItemsInList(list,";"),ii
861       
862        for(ii=0;ii<num;ii+=1)
863                item = StringFromList(ii, list  ,";")
864
865                validName = V_FindValidFileName(item)
866                if(strlen(validName) != 0)              //non-null return from FindValidFileName()
867                        fullName = path + validName             
868
869        //method (1)                   
870//                      if(V_CheckIfRawData(item))
871//                              newlist += item + ";"
872//                      endif
873
874        //method (2)                   
875                        if( stringmatch(item,"*.nxs.ngv*") )
876                                newlist += item + ";"
877                        endif
878
879                       
880                endif
881                //print "ii=",ii
882        endfor
883        newList = SortList(newList,";",0)
884        return(newList)
885End
886
887//
888// TODO:
889// -- does this need to be more sophisticated?
890//
891// simple "not" of V_GetRawDataFileList()
892Function/S V_Get_NotRawDataFileList()
893       
894        //make sure that path exists
895        PathInfo catPathName
896        if (V_flag == 0)
897                Abort "Folder path does not exist - use Pick Path button on Main Panel"
898        Endif
899        String path = S_Path
900       
901        String list=IndexedFile(catPathName,-1,"????")
902        String newList="",item="",validName="",fullName=""
903        Variable num=ItemsInList(list,";"),ii
904       
905        for(ii=0;ii<num;ii+=1)
906                item = StringFromList(ii, list  ,";")
907
908//              validName = V_FindValidFileName(item)
909//              if(strlen(validName) != 0)              //non-null return from FindValidFileName()
910//                      fullName = path + validName             
911
912        //method (2)                   
913                        if( !stringmatch(item,"*.nxs.ngv*") )
914                                newlist += item + ";"
915                        endif
916
917                       
918//              endif
919                //print "ii=",ii
920        endfor
921        newList = SortList(newList,";",0)
922        return(newList)
923End
924
925
926//the following is a WaveMetrics procedure from <StrMatchList>
927// MatchList(matchStr,list,sep)
928// Returns the items of the list whose items match matchStr
929// The lists are separated by the sep character, usually ";"
930//
931// matchStr may be something like "abc", in which case it is identical to CmpStr
932// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
933//      "*abc" to match anything ending with "abc".
934// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
935//      the pattern.
936// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
937//
938Function/S V_MyMatchList(matchStr,list,sep)
939        String matchStr,list,sep
940        String item,outList=""
941        Variable n=strlen(list)
942        Variable en,st=0
943        do
944                en= strsearch(list,sep,st)
945                if( en < 0 )
946                        if( st < n-1 )
947                                en= n   // no trailing separator
948                                sep=""  // don't put sep in output, either
949                        else
950                                break   // no more items in list
951                        endif
952                endif
953                item=list[st,en-1]
954                if( V_MyStrMatch(matchStr,item) == 0 )
955                        outlist += item+sep
956                Endif
957                st=en+1
958        while (st < n ) // exit is by break, above
959        return outlist
960End
961
962//the following is a WaveMetrics procedure from <StrMatchList>
963// StrMatch(matchStr,str)
964// Returns 0 if the pattern in matchStr matches str, else it returns 1
965//
966// matchStr may be something like "abc", in which case it is identical to CmpStr
967// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
968//      "*abc" to match anything ending with "abc".
969// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
970//      the pattern.
971// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
972//
973Function V_MyStrMatch(matchStr,str)
974        String matchStr,str
975        Variable match = 1              // 0 means match
976        Variable invert= strsearch(matchStr,"!",0) == 0
977        if( invert )
978                matchStr[0,0]=""        // remove the "!"
979        endif
980        Variable st=0,en=strlen(str)-1
981        Variable starPos= strsearch(matchStr,"*",0)
982        if( starPos >= 0 )      // have a star
983                if( starPos == 0 )      // at start
984                        matchStr[0,0]=""                                // remove star at start
985                else                                    // at end
986                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
987                endif
988                Variable len=strlen(matchStr)
989                if( len > 0 )
990                        if(starPos == 0)        // star at start, match must be at end
991                                st=en-len+1
992                        else
993                                en=len-1        // star at end, match at start
994                        endif
995                else
996                        str=""  // so that "*" matches anything
997                endif
998        endif
999        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
1000        if( invert )
1001                match= 1-match
1002        endif
1003        return match
1004End
1005
1006
1007//input is a list of run numbers, and output is a list of filenames (not the full path)
1008//*** input list must be COMMA delimited***
1009//output is equivalent to selecting from the CAT table
1010//if some or all of the list items are valid filenames, keep them...
1011//if an error is encountered, notify of the offending element and return a null list
1012//
1013//output is COMMA delimited
1014//
1015// this routine is expecting that the "ask", "none" special cases are handled elsewhere
1016//and not passed here
1017//
1018// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
1019//
1020Function/S V_ParseRunNumberList(list)
1021        String list
1022       
1023        String newList="",item="",tempStr=""
1024        Variable num,ii,runNum
1025       
1026        //expand number ranges, if any
1027        list = V_ExpandNumRanges(list)
1028       
1029        num=itemsinlist(list,",")
1030       
1031        for(ii=0;ii<num;ii+=1)
1032                //get the item
1033                item = StringFromList(ii,list,",")
1034                //is it already a valid filename?
1035                tempStr=V_FindValidFilename(item) //returns filename if good, null if error
1036                if(strlen(tempstr)!=0)
1037                        //valid name, add to list
1038                        //Print "it's a file"
1039                        newList += tempStr + ","
1040                else
1041                        //not a valid name
1042                        //is it a number?
1043                        runNum=str2num(item)
1044                        //print runnum
1045                        if(numtype(runNum) != 0)
1046                                //not a number -  maybe an error                       
1047                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
1048                                return("")
1049                        else
1050                                //a run number or an error
1051                                tempStr = V_GetFileNameFromPathNoSemi( V_FindFileFromRunNumber(runNum) )
1052                                if(strlen(tempstr)==0)
1053                                        //file not found, error
1054                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
1055                                        return("")
1056                                else
1057                                        newList += tempStr + ","
1058                                endif
1059                        endif
1060                endif
1061        endfor          //loop over all items in list
1062       
1063        return(newList)
1064End
1065
1066//takes a comma delimited list that MAY contain number range, and
1067//expands any range of run numbers into a comma-delimited list...
1068//and returns the new list - if not a range, return unchanged
1069//
1070// local function
1071//
1072Function/S V_ExpandNumRanges(list)
1073        String list
1074       
1075        String newList="",dash="-",item,str
1076        Variable num,ii,hasDash
1077       
1078        num=itemsinlist(list,",")
1079//      print num
1080        for(ii=0;ii<num;ii+=1)
1081                //get the item
1082                item = StringFromList(ii,list,",")
1083                //does it contain a dash?
1084                hasDash = strsearch(item,dash,0)                //-1 if no dash found
1085                if(hasDash == -1)
1086                        //not a range, keep it in the list
1087                        newList += item + ","
1088                else
1089                        //has a dash (so it's a range), expand (or add null)
1090                        newList += V_ListFromDash(item)         
1091                endif
1092        endfor
1093       
1094        return newList
1095End
1096
1097//be sure to add a trailing comma to the return string...
1098//
1099// local function
1100//
1101Function/S V_ListFromDash(item)
1102        String item
1103       
1104        String numList="",loStr="",hiStr=""
1105        Variable lo,hi,ii
1106       
1107        loStr=StringFromList(0,item,"-")        //treat the range as a list
1108        hiStr=StringFromList(1,item,"-")
1109        lo=str2num(loStr)
1110        hi=str2num(hiStr)
1111        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
1112                numList=""
1113                return numList
1114        endif
1115        for(ii=lo;ii<=hi;ii+=1)
1116                numList += num2str(ii) + ","
1117        endfor
1118       
1119        Return numList
1120End
1121
Note: See TracBrowser for help on using the repository browser.