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

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

changes to handle an arbitrary run number, rather than insisting on 3 or 4 digits.

fix to SANS file catalog where the last file name was cleared from the table, if there are no extra non-raw data files present. not a typical case, but it can happen.

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