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

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

cleanup of TODO items in code, no noteworthy changes

prepare a test release package for the January startup of VSANS, not a general release (since no changes to SANS or USANS)

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