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

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

ADDED:

included common NCNR procedures for the PlotManager?, to allow plotting of 1D data sets using a familiar interface

greatly expanded Patch functionality to include input in the multiple sections of the Nexus file, including separate panels to handle patching of waves to the file - needed for non-linear coefficients, dead time, and XY beam centers. All patch operations are expandable as more fields become necessary to patch.

removed bug of group_id being defined in /reduction and in /sample (removed R/W that referenced /reduction)

added panel to "isolate" a single detector panel, allowing the corrections to be applied/removed/recalculated as needed to directly see their effects.

linked new procedures to their appropriate action buttons

Added more data fields (label, intent, etc.) to the VCALC to Nexus data writer to get more realistic values into the fake data files for testing

Added VCALC simulation functions with EMP and BGD in anticipation of testing the CORRECT step

more little bug and documentation fixes which I can't remember, but they are all important...

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