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

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

many minor changes after real VSANS data collected.

additional procedures added to allow easy correction of the incorrect header information from NICE.

Most notable addition is the pinhole resolution added to the calculation and the I(q) output. White beam is also treated (incorrectly) as a gaussian distrivution, but the results of smeared fitting look to be quite good.

Trimming and sorting routines are now (pinhole) resolution aware.

File identification routines have been updated to use the proper definitions of "purpose" and "intent". Both fields are now in the catalog, to allow for better sorting.

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