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

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

Updating the patch panel for the VSANS variables, a first pass at including the essential values, and a section that has per-detector values.

Still needs to be fully stress tested to be sure that it does all of read/write operations correctly.

adjusted the "last file loaded" global variable that is displayed on the data display to only update when a file is loaded for display, not when any file is loaded for the catalog, or for the patch panel.

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