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

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

changes to streamline the data plotting of 1D data, in preparation for different modes of combining detector panels. Also will allow better integration with protocols to combine 1D data, which can now be part of the protocol.

Other changes, but I can't remember whtat they were...

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