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

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

many additions.

Moved unused igor/nexus testing files to Vx_ prefix since they're garbage. Pulled out the useful bits for mask and div R/W and moved those to theire appropriate procedures.

Testing the simple correction of data, only tested basic subtraction. All of it still needs to be verified since I don't have any real header numbers and units yet.

Adjusted the columns on the file catalog to be more appropriate, and added a hook to allow loading of raw data files directly from the table and a popup contextual menu. May add more functionality to it later.

Corrected how the 1D data is plotted so that it correctly uses the binning type. I(q) save now also uses the binning as specified.

File size: 30.2 KB
Line 
1#pragma TextEncoding = "MacRoman"               // For details execute DisplayHelpTopic "The TextEncoding Pragma"
2#pragma rtGlobals=3             // Use modern global access method and strict wave access.
3
4//
5//              general utilities
6//
7// for use by multiple panels and packages
8
9
10//prompts user to choose the local folder that contains the SANS Data
11//only one folder can be used, and its path is catPathName (and is a NAME, not a string)
12//this will overwrite the path selection
13//returns 1 if no path selected as error condition, or if user cancelled
14Function V_PickPath()
15       
16        //set the global string to the selected pathname
17        NewPath/O/M="pick the SANS data folder" catPathName
18        if(V_Flag != 0)
19                return(1)               //user cancelled
20        endif
21       
22        PathInfo/S catPathName
23        String dum = S_path
24        String alertStr = ""
25        alertStr = "You must set the path to Charlotte through a Mapped Network Drive, not through the Network Neighborhood"
26        //alertStr += "  Please see the manual for details."
27        if (V_flag == 0)
28                //path does not exist - no folder selected
29                String/G root:Packges:NIST:VSANS:Globals:gCatPathStr = "no folder selected"
30                return(1)
31        else
32        // SRK 2016, for windows 10, try to eliminate this restriction 
33        //---- connecting through the network neighborhood seems to be perfectly fine except for
34        //     path issues with GBLoadWave, which only affects VAX data sets
35               
36//              print igorinfo(3)
37//              //set the global to the path (as a string)
38//              // need 4 \ since it is the escape character
39//              if(cmpstr("\\\\",dum[0,1])==0)  //Windows user going through network neighborhood
40//                      DoAlert 0,alertStr
41//                      KillPath catPathName
42//                      return(1)
43//              endif
44                String/G root:Packges:NIST:VSANS:Globals:gCatPathStr = dum
45                return(0)               //no error
46        endif
47       
48End
49
50//
51// entry from the Main Panel
52//
53Proc V_ChangeDisplay(type)
54        String type
55        Prompt type,"WORK data type to display",popup,"RAW;SAM;EMP;BGD;ADJ;"
56
57// make sure that data exists before passing this on...
58       
59        if(DataExists(type) > 0)
60                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 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 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 are (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 are (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                Execute "UpdateDisplayInformation(\"RAW\")"     // plot the data in whatever folder type
463               
464                FakeRestorePanelsButtonClick()          //so the panels display correctly
465                // set the global to display ONLY if the load was called from here, not from the
466                // other routines that load data (to read in values)
467                SVAR gLastLoad = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
468                gLastLoad = hdfDF
469        endif
470
471        // TODO
472        // -- update the 1D plotting as needed. these are SANS calls (OK for now, but will need to be better)
473        //do the average and plot (either the default, or what is on the panel currently)
474        V_PlotData_Panel()
475       
476
477        return(0)
478End
479
480
481// Return the full path:filename that represents the previous or next file.
482// Input is current filename and increment.
483// Increment should be -1 or 1
484// -1 => previous file
485// 1 => next file
486//
487// V_CheckIfRawData(fname)
488//
489Function/S V_GetPrevNextRawFile(curfilename, prevnext)
490        String curfilename
491        Variable prevnext
492
493        String filename
494       
495        //get the run number
496        Variable num = V_GetRunNumFromFile(curfilename)
497               
498        //find the next specified file by number
499        fileName = V_FindFileFromRunNumber(num+prevnext)
500
501        if(cmpstr(fileName,"")==0)
502                //null return, do nothing
503                fileName = V_FindFileFromRunNumber(num)         //returns the full path, not just curFileName
504        Endif
505
506        Return filename
507End
508
509
510//returns a string containing the full path to the file containing the
511//run number "num". The null string is returned if no valid file can be found
512//the path "catPathName" used and is hard-wired, will abort if this path does not exist
513//the file returned will be a RAW VSANS data file, other types of files are
514//filtered out.
515//
516//
517// -- with the run numbers incrementing from 1, there is no need to add leading zeros to the
518//    file names. simply add the number and go.
519//
520// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
521//
522Function/S V_FindFileFromRunNumber(num)
523        Variable num
524       
525        String fullName="",partialName="",item=""
526        //get list of raw data files in folder that match "num"
527
528        String numStr=""
529        numStr = num2str(num)
530
531        //make sure that path exists
532        PathInfo catPathName
533        String path = S_path
534        if (V_flag == 0)
535                Abort "folder path does not exist - use Pick Path button"
536        Endif
537        String list="",newList="",testStr=""
538       
539        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
540        //find (the) one with the number in the run # location in the name
541        Variable numItems,ii,runFound,isRAW
542        numItems = ItemsInList(list,";")                //get the new number of items in the list
543        ii=0
544        do
545                //parse through the list in this order:
546                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
547                // 2 - exclude by isRaw? (to minimize disk access)
548                item = StringFromList(ii, list  ,";" )
549                if(strlen(item) != 0)
550                        //find the run number, if it exists as a three character string
551                        testStr = V_GetRunNumStrFromFile(item)
552                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
553                        if(runFound == 0)
554                                //the run Number was found
555                                //build valid filename
556                                partialName = V_FindValidFileName(item)
557                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
558                                        fullName = path + partialName
559                                        //check if RAW, if so,this must be the file!
560                                        isRAW = V_CheckIfRawData(fullName)
561                                        if(isRaw)
562                                                //print "is raw, ",fullname
563                                                //stop here
564                                                return(fullname)
565                                        Endif
566                                Endif
567                        Endif
568                Endif
569                ii+=1
570        while(ii<numItems)              //process all items in list
571        Return ("")     //null return if file not found in list
572End
573
574//
575// TODO x- for VSANS Nexus files, how do I quickly identify if a file is
576//   RAW VSANS data? I don't want to generate any errors, but I want to quickly
577//   weed out the reduced data sets, etc. from file catalogs.
578//      (check the instrument name...)
579
580// TODO -- as was written by SANS, this function is expecting fname to be the path:fileName
581// - but are the V_get() functions OK with getting a full path, and what do they
582//  do when they fail? I don't want them to spit up another open file dialog
583//
584Function V_CheckIfRawData(fname)
585        String fname
586       
587        Variable refnum,totalBytes
588        String testStr=""
589       
590        testStr = V_getInstrumentName(fname)
591
592        if(cmpstr(testStr,"NG3-VSANS") == 0)
593                //testStr exists, ASSUMING it's a raw VSANS data file
594                Return(1)
595        else
596                //some other file
597                Return(0)
598        Endif
599End
600
601// TODO -- need to fill in correctly by determining this from the INTENT field
602//
603Function V_isTransFile(fname)
604        String fname
605       
606        Variable refnum,totalBytes
607        String testStr=""
608       
609//      testStr = V_getInstrumentName(fname)
610
611        if(cmpstr(testStr,"NG3-VSANS") == 0)            //wrong test
612                //testStr exists, ASSUMING it's a raw VSANS data file
613                Return(1)
614        else
615                //some other file
616                Return(0)
617        Endif
618End
619
620
621Function V_GetRunNumFromFile(item)
622        String item
623       
624        String str = V_GetRunNumStrFromFile(item)
625       
626        return(str2num(str))
627end
628
629
630// TODO -- the file name structure for VSANS file is undecided
631// so some of these base functions will need to change
632//
633//given a filename of a VSANS data filename of the form
634// sansNNNN.nxs.ngv
635//returns the run number "NNNN" as a STRING of (x) characters
636//
637// -- the run number incements from 1, so the number of digits is UNKNOWN
638// -- number starts at position [4] (the 5th character)
639// -- number ends with the character prior to the first "."
640//
641//returns "ABCD" as an invalid file number
642//
643// local function to aid in locating files by run number
644//
645Function/S V_GetRunNumStrFromFile(item)
646        String item
647        String invalid = "ABCD" //"ABCD" is not a valid run number, since it's text
648        Variable num=-1
649       
650        //find the "dot"
651        String runStr=""
652        Variable numChar = 4
653        Variable pos = strsearch(item,".",0)
654        if(pos == -1)
655                //"dot" not found
656                return (invalid)
657        else
658                //found, get the characters preceeding it, but still after the "sans" characters
659                if (pos-1 < 4)
660                        //not enough characters
661                        return (invalid)
662                else
663                        runStr = item[4,pos-1]
664                        return (runStr)
665                Endif
666        Endif
667End
668
669//Function attempts to find valid filename from partial name by checking for
670// the existence of the file on disk.
671// - checks as is
672// - strips spaces
673// - permutations of upper/lowercase
674//
675// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
676// since from marquee, the filename field (textread[0]) must be used, and can be a mix of                       //02JUL13
677// upper/lowercase letters, while the filename on the server (should) be all caps
678// now makes repeated calls to ValidFileString()
679//
680// returns a valid filename (No path prepended) or a null string
681//
682// called by any functions, both external and local
683//
684Function/S V_FindValidFilename(partialName)
685        String PartialName
686       
687        String retStr=""
688       
689        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
690        retStr = V_ValidFileString(partialName)
691        if(cmpstr(retStr,"") !=0)
692                //non-null return
693                return(retStr)
694        Endif
695       
696        //if the partial name is derived from the file header, there can be spaces at the beginning
697        //or in the middle of the filename - depending on the prefix and initials used
698        //
699        //remove any leading spaces from the name before starting
700        partialName = V_RemoveAllSpaces(partialName)
701       
702        //try name with no spaces
703        retStr = V_ValidFileString(partialName)
704        if(cmpstr(retStr,"") !=0)
705                //non-null return
706                return(retStr)
707        Endif
708       
709        //try all UPPERCASE
710        partialName = UpperStr(partialName)
711        retStr = V_ValidFileString(partialName)
712        if(cmpstr(retStr,"") !=0)
713                //non-null return
714                return(retStr)
715        Endif
716       
717        //try all lowercase (ret null if failure)
718        partialName = LowerStr(partialName)
719        retStr = V_ValidFileString(partialName)
720        if(cmpstr(retStr,"") !=0)
721                //non-null return
722                return(retStr)
723        else
724                return(retStr)
725        Endif
726End
727
728
729// Function checks for the existence of a file
730// partialName;vers (to account for VAX filenaming conventions)
731// The partial name is tried first with no version number
732//
733// *** the PATH is hard-wired to catPathName (which is assumed to exist)
734// version numers up to ;10 are tried
735// only the "name;vers" is returned if successful. The path is not prepended
736//
737// local function
738//
739// TODO -- is this really necessary anymore for the NON-VAX files of VSANS.
740// -- can this be made a pass-through, or will there be another function that is needed for VSANS?
741//
742Function/S V_ValidFileString(partialName)
743        String partialName
744       
745        String tempName = "",msg=""
746        Variable ii,refnum
747       
748        ii=0
749        do
750                if(ii==0)
751                        //first pass, try the partialName
752                        tempName = partialName
753                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
754                        if(V_flag == 0)
755                                //file exists
756                                Close refnum            //YES needed,
757                                break
758                        endif
759                else
760                        tempName = partialName + ";" + num2str(ii)
761                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
762                        if(V_flag == 0)
763                                //file exists
764                                Close refnum
765                                break
766                        endif
767                Endif
768                ii+=1
769                //print "ii=",ii
770        while(ii<11)
771        //go get the selected bits of information, using tempName, which exists
772        if(ii>=11)
773                //msg = partialName + " not found. is version number > 11?"
774                //DoAlert 0, msg
775                //PathInfo catPathName
776                //Print S_Path
777                Return ("")             //use null string as error condition
778        Endif
779       
780        Return (tempName)
781End
782
783//function to remove all spaces from names when searching for filenames
784//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
785//but the text field in the header WILL, if less than 3 characters were used for the
786//user's initials, and can have leading spaces if prefix was less than 5 characters
787//
788//returns a string identical to the original string, except with the interior spaces removed
789//
790// local function for file name manipulation
791//
792Function/S V_RemoveAllSpaces(str)
793        String str
794       
795        String tempstr = str
796        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
797        ii=0
798        do
799                len = strlen(tempStr)
800                spc = strsearch(tempStr," ",0)          //is the last character a space?
801                if (spc == -1)
802                        break           //no more spaces found, get out
803                endif
804                str = tempstr
805                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
806        While(1)        //should never be more than 2 or 3
807       
808        If(strlen(tempStr) < 1)
809                tempStr = ""            //be sure to return a null string if problem found
810        Endif
811       
812        //Print strlen(tempstr)
813       
814        Return(tempStr)
815               
816End
817
818// returns a list of raw data files in the catPathName directory on disk
819// - list is SEMICOLON-delimited
820//
821// TODO: decide how to do this...
822// (1)
823// checks each file in the directory to see if it is a RAW data file by
824// call to V_CheckIfRawData() which currently looks for the instrument name in the file.
825// -- CON - this is excruciatingly slow, and by checking a field in the file, has to load in the
826//  ENTIRE data file, and will load EVERY file in the folder. ugh.
827//
828// (2)
829// as was done for VAX files, look for a specific string in the file name as written by the acquisition
830//  (was .saN), now key on ".nxs.ngv"?
831//
832// called by PatchFiles.ipf, Tile_2D.ipf
833//
834Function/S V_GetRawDataFileList()
835       
836        //make sure that path exists
837        PathInfo catPathName
838        if (V_flag == 0)
839                Abort "Folder path does not exist - use Pick Path button on Main Panel"
840        Endif
841        String path = S_Path
842       
843        String list=IndexedFile(catPathName,-1,"????")
844        String newList="",item="",validName="",fullName=""
845        Variable num=ItemsInList(list,";"),ii
846       
847        for(ii=0;ii<num;ii+=1)
848                item = StringFromList(ii, list  ,";")
849
850                validName = V_FindValidFileName(item)
851                if(strlen(validName) != 0)              //non-null return from FindValidFileName()
852                        fullName = path + validName             
853
854        //method (1)                   
855//                      if(V_CheckIfRawData(item))
856//                              newlist += item + ";"
857//                      endif
858
859        //method (2)                   
860                        if( stringmatch(item,"*.nxs.ngv*") )
861                                newlist += item + ";"
862                        endif
863
864                       
865                endif
866                //print "ii=",ii
867        endfor
868        newList = SortList(newList,";",0)
869        return(newList)
870End
871
872
873//the following is a WaveMetrics procedure from <StrMatchList>
874// MatchList(matchStr,list,sep)
875// Returns the items of the list whose items match matchStr
876// The lists are separated by the sep character, usually ";"
877//
878// matchStr may be something like "abc", in which case it is identical to CmpStr
879// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
880//      "*abc" to match anything ending with "abc".
881// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
882//      the pattern.
883// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
884//
885Function/S V_MyMatchList(matchStr,list,sep)
886        String matchStr,list,sep
887        String item,outList=""
888        Variable n=strlen(list)
889        Variable en,st=0
890        do
891                en= strsearch(list,sep,st)
892                if( en < 0 )
893                        if( st < n-1 )
894                                en= n   // no trailing separator
895                                sep=""  // don't put sep in output, either
896                        else
897                                break   // no more items in list
898                        endif
899                endif
900                item=list[st,en-1]
901                if( V_MyStrMatch(matchStr,item) == 0 )
902                        outlist += item+sep
903                Endif
904                st=en+1
905        while (st < n ) // exit is by break, above
906        return outlist
907End
908
909//the following is a WaveMetrics procedure from <StrMatchList>
910// StrMatch(matchStr,str)
911// Returns 0 if the pattern in matchStr matches str, else it returns 1
912//
913// matchStr may be something like "abc", in which case it is identical to CmpStr
914// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
915//      "*abc" to match anything ending with "abc".
916// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
917//      the pattern.
918// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
919//
920Function V_MyStrMatch(matchStr,str)
921        String matchStr,str
922        Variable match = 1              // 0 means match
923        Variable invert= strsearch(matchStr,"!",0) == 0
924        if( invert )
925                matchStr[0,0]=""        // remove the "!"
926        endif
927        Variable st=0,en=strlen(str)-1
928        Variable starPos= strsearch(matchStr,"*",0)
929        if( starPos >= 0 )      // have a star
930                if( starPos == 0 )      // at start
931                        matchStr[0,0]=""                                // remove star at start
932                else                                    // at end
933                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
934                endif
935                Variable len=strlen(matchStr)
936                if( len > 0 )
937                        if(starPos == 0)        // star at start, match must be at end
938                                st=en-len+1
939                        else
940                                en=len-1        // star at end, match at start
941                        endif
942                else
943                        str=""  // so that "*" matches anything
944                endif
945        endif
946        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
947        if( invert )
948                match= 1-match
949        endif
950        return match
951End
952
953
954//input is a list of run numbers, and output is a list of filenames (not the full path)
955//*** input list must be COMMA delimited***
956//output is equivalent to selecting from the CAT table
957//if some or all of the list items are valid filenames, keep them...
958//if an error is encountered, notify of the offending element and return a null list
959//
960//output is COMMA delimited
961//
962// this routine is expecting that the "ask", "none" special cases are handled elsewhere
963//and not passed here
964//
965// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
966//
967Function/S V_ParseRunNumberList(list)
968        String list
969       
970        String newList="",item="",tempStr=""
971        Variable num,ii,runNum
972       
973        //expand number ranges, if any
974        list = V_ExpandNumRanges(list)
975       
976        num=itemsinlist(list,",")
977       
978        for(ii=0;ii<num;ii+=1)
979                //get the item
980                item = StringFromList(ii,list,",")
981                //is it already a valid filename?
982                tempStr=V_FindValidFilename(item) //returns filename if good, null if error
983                if(strlen(tempstr)!=0)
984                        //valid name, add to list
985                        //Print "it's a file"
986                        newList += tempStr + ","
987                else
988                        //not a valid name
989                        //is it a number?
990                        runNum=str2num(item)
991                        //print runnum
992                        if(numtype(runNum) != 0)
993                                //not a number -  maybe an error                       
994                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
995                                return("")
996                        else
997                                //a run number or an error
998                                tempStr = V_GetFileNameFromPathNoSemi( V_FindFileFromRunNumber(runNum) )
999                                if(strlen(tempstr)==0)
1000                                        //file not found, error
1001                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
1002                                        return("")
1003                                else
1004                                        newList += tempStr + ","
1005                                endif
1006                        endif
1007                endif
1008        endfor          //loop over all items in list
1009       
1010        return(newList)
1011End
1012
1013//takes a comma delimited list that MAY contain number range, and
1014//expands any range of run numbers into a comma-delimited list...
1015//and returns the new list - if not a range, return unchanged
1016//
1017// local function
1018//
1019Function/S V_ExpandNumRanges(list)
1020        String list
1021       
1022        String newList="",dash="-",item,str
1023        Variable num,ii,hasDash
1024       
1025        num=itemsinlist(list,",")
1026//      print num
1027        for(ii=0;ii<num;ii+=1)
1028                //get the item
1029                item = StringFromList(ii,list,",")
1030                //does it contain a dash?
1031                hasDash = strsearch(item,dash,0)                //-1 if no dash found
1032                if(hasDash == -1)
1033                        //not a range, keep it in the list
1034                        newList += item + ","
1035                else
1036                        //has a dash (so it's a range), expand (or add null)
1037                        newList += V_ListFromDash(item)         
1038                endif
1039        endfor
1040       
1041        return newList
1042End
1043
1044//be sure to add a trailing comma to the return string...
1045//
1046// local function
1047//
1048Function/S V_ListFromDash(item)
1049        String item
1050       
1051        String numList="",loStr="",hiStr=""
1052        Variable lo,hi,ii
1053       
1054        loStr=StringFromList(0,item,"-")        //treat the range as a list
1055        hiStr=StringFromList(1,item,"-")
1056        lo=str2num(loStr)
1057        hi=str2num(hiStr)
1058        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
1059                numList=""
1060                return numList
1061        endif
1062        for(ii=lo;ii<=hi;ii+=1)
1063                numList += num2str(ii) + ","
1064        endfor
1065       
1066        Return numList
1067End
1068
Note: See TracBrowser for help on using the repository browser.