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

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

lots of changes here:
many little fixes to clean up TODO items and marke them DONE

changed the handling of the panel "gap" to split the gap evenly. Q-calculations have been re-verified with this change.

re-named the list of "bin Type" values, and added a few more choices. Streamlined how the averaging and plotting works with this list so that it can be more easily modified as different combinations of binning are envisioned. This resulted in a lot of excess code being cut out and replaced with cleaner logic. This change has also been verified to work as intended.

Attenuation is now always calculated from the table. The table also by (NEW) definition has values for the white beam (one waelength) and graphite (multiple possible wavelengths) where the wavelengths are artificially scaled (*1000) or *1e6) so that the interpolations can be done internally without the need for multiple attenuator tables.

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// x- load in the proper file
433// x- re-click the I(q) button
434// x- be sure that the globals are updated w/ filename
435// -- getting the file_name from the root: global is a poor choice.
436//     Need a better, more reliable solution than this
437// -- make a copy of "oldName" that is local and not the SVAR, as the SVAR changes
438//    when the next file is loaded in (if it's not in RawVSANS), resulting in a "skipped" file number
439//
440//displays next (or previous) file in series of run numbers
441//file is read from disk, if path is set and the file number is present
442//increment +1, adds 1 to run number, -1 subtracts one
443//
444// will automatically step a gap of 10 run numbers, but nothing larger. Don't want to loop too long
445// trying to find a file (frustrating), don't want to look past the end of the run numbers (waste)
446// -- may find a more elegant solution later.
447//
448Function V_LoadPlotAndDisplayRAW(increment)
449        Variable increment
450
451        Variable i,val
452        String filename,tmp,curFileName
453        //take the currently displayed RAW file
454        SVAR oldName = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
455        oldname = V_RemoveAllSpaces(oldname)            //
456        curFileName = oldName
457//      print oldName
458       
459        filename = oldname
460//      for (i = 0; i < abs(increment); i += 1)
461//              filename = GetPrevNextRawFile(filename,increment/abs(increment))
462//      endfor 
463        i = 1
464        val = increment
465        do
466//              print filename,val
467                filename = V_GetPrevNextRawFile(filename,val)
468//              print "new= ",filename
469               
470                val = i*increment
471                i+=1
472                tmp = ParseFilePath(0, filename, ":", 1, 0)
473
474//              print val,strlen(tmp),strlen(oldname)
475//              print cmpstr(tmp,oldname)
476
477                if(strlen(tmp) == 0)            //in some cases, a null string can be returned - handle gracefully
478                        return(0)
479                endif
480               
481        while( (cmpstr(tmp,curFileName) == 0) && i < 11)
482//      print filename
483       
484        // display the specified RAW data file
485        // this is the set of steps done in DisplayMainButtonProc(ctrlName) : ButtonControl
486        Variable err=   V_LoadHDF5Data(filename,"RAW")                  // load the data, set the global w/file name loaded
487//      Print "Load err = "+num2str(err)
488        if(!err)
489                SVAR hdfDF = root:file_name                     // last file loaded, may not be the safest way to pass
490                String folder = StringFromList(0,hdfDF,".")
491               
492                // this (in SANS) just passes directly to fRawWindowHook()
493                V_UpdateDisplayInformation("RAW")       // plot the data in whatever folder type
494               
495                // set the global to display ONLY if the load was called from here, not from the
496                // other routines that load data (to read in values)
497                SVAR gLastLoad = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
498                gLastLoad = hdfDF
499        endif
500
501        //
502        // x- update the 1D plotting as needed. these are SANS calls (OK for now, but will need to be better)
503        //do the average and plot (either the default, or what is on the panel currently)
504        SVAR type = root:Packages:NIST:VSANS:Globals:gCurDispType
505        type = "RAW"
506        V_PlotData_Panel()              // read the binType from the panel
507        Variable binType = V_GetBinningPopMode()
508        ControlInfo/W=V_1D_Data popup0
509        V_BinningModePopup("",binType,S_Value)          // does default circular binning and updates the graph
510
511
512        return(0)
513End
514
515
516// Return the full path:filename that represents the previous or next file.
517// Input is current filename and increment.
518// Increment should be -1 or 1
519// -1 => previous file
520// 1 => next file
521//
522// V_CheckIfRawData(fname)
523//
524Function/S V_GetPrevNextRawFile(curfilename, prevnext)
525        String curfilename
526        Variable prevnext
527
528        String filename
529       
530        //get the run number
531        Variable num = V_GetRunNumFromFile(curfilename)
532               
533        //find the next specified file by number
534        fileName = V_FindFileFromRunNumber(num+prevnext)
535
536        if(cmpstr(fileName,"")==0)
537                //null return, do nothing
538                fileName = V_FindFileFromRunNumber(num)         //returns the full path, not just curFileName
539        Endif
540
541        Return filename
542End
543
544
545//returns a string containing the full path to the file containing the
546//run number "num". The null string is returned if no valid file can be found
547//the path "catPathName" used and is hard-wired, will abort if this path does not exist
548//the file returned will be a RAW VSANS data file, other types of files are
549//filtered out.
550//
551//
552// -- with the run numbers incrementing from 1, there is no need to add leading zeros to the
553//    file names. simply add the number and go.
554//
555// called by Buttons.ipf and Transmission.ipf, and locally by parsing routines
556//
557Function/S V_FindFileFromRunNumber(num)
558        Variable num
559       
560        String fullName="",partialName="",item=""
561        //get list of raw data files in folder that match "num"
562
563        String numStr=""
564        numStr = num2str(num)
565
566        //make sure that path exists
567        PathInfo catPathName
568        String path = S_path
569        if (V_flag == 0)
570                Abort "folder path does not exist - use Pick Path button"
571        Endif
572        String list="",newList="",testStr=""
573       
574        list = IndexedFile(catPathName,-1,"????")       //get all files in folder
575        //find (the) one with the number in the run # location in the name
576        Variable numItems,ii,runFound,isRAW
577        numItems = ItemsInList(list,";")                //get the new number of items in the list
578        ii=0
579        do
580                //parse through the list in this order:
581                // 1 - does item contain run number (as a string) "TTTTTnnn.SAn_XXX_Tyyy"
582                // 2 - exclude by isRaw? (to minimize disk access)
583                item = StringFromList(ii, list  ,";" )
584                if(strlen(item) != 0)
585                        //find the run number, if it exists as a three character string
586                        testStr = V_GetRunNumStrFromFile(item)
587                        runFound= cmpstr(numStr,testStr)        //compare the three character strings, 0 if equal
588                        if(runFound == 0)
589                                //the run Number was found
590                                //build valid filename
591                                partialName = V_FindValidFileName(item)
592                                if(strlen(partialName) != 0)            //non-null return from FindValidFileName()
593                                        fullName = path + partialName
594                                        //check if RAW, if so,this must be the file!
595                                        isRAW = V_CheckIfRawData(fullName)
596                                        if(isRaw)
597                                                //print "is raw, ",fullname
598                                                //stop here
599                                                return(fullname)
600                                        Endif
601                                Endif
602                        Endif
603                Endif
604                ii+=1
605        while(ii<numItems)              //process all items in list
606        Return ("")     //null return if file not found in list
607End
608
609//
610//  x- for VSANS Nexus files, how do I quickly identify if a file is
611//   RAW VSANS data? I don't want to generate any errors, but I want to quickly
612//   weed out the reduced data sets, etc. from file catalogs.
613//      (check the instrument name...)
614
615// (DONE) x- as was written by SANS, this function is expecting fname to be the path:fileName
616// - but are the V_get() functions OK with getting a full path, and what do they
617//  do when they fail? I don't want them to spit up another open file dialog
618//
619// x- problem -- if "sans1234.abs" is passed, then V_getStringFromHDF5(fname,path,num)
620//  will remove the extension and look for the sans1234 folder -- which may or may not be present.
621//  If it is present, then sans1234 validates as RAW data -- which is incorrect!
622// x- so I need a way to exclude everything that does not have the proper extension...
623//
624//
625Function V_CheckIfRawData(fname)
626        String fname
627       
628        String testStr=""
629
630// check for the proper raw data extension
631        if( stringmatch(fname,"*.nxs.ngv*") )
632                // name appears OK, proceed
633                testStr = V_getInstrumentName(fname)
634
635                if(cmpstr(testStr,"NG3-VSANS") == 0)
636                        //testStr exists, ASSUMING it's a raw VSANS data file
637                        Return(1)
638                else
639                        //some other file
640                        Return(0)
641                Endif
642       
643        else
644                // not a proper raw VSANS file name
645                return(0)
646               
647        endif   
648       
649
650End
651
652//  x- need to fill in correctly by determining this from the INTENT field
653//
654Function V_isTransFile(fname)
655        String fname
656       
657        Variable refnum,totalBytes
658        String testStr=""
659       
660        testStr = V_getReduction_intent(fname)
661
662        if(cmpstr(testStr,"TRANSMISSION") == 0)         //
663                //yes, a transmission file
664                Return(1)
665        else
666                //some other file intent
667                Return(0)
668        Endif
669End
670
671
672Function V_GetRunNumFromFile(item)
673        String item
674       
675        String str = V_GetRunNumStrFromFile(item)
676       
677        return(str2num(str))
678end
679
680
681// (DONE) x- the file name structure for VSANS file is undecided
682// so some of these base functions will need to change
683//
684//given a filename of a VSANS data filename of the form
685// sansNNNN.nxs.ngv
686//returns the run number "NNNN" as a STRING of (x) characters
687//
688// -- the run number incements from 1, so the number of digits is UNKNOWN
689// -- number starts at position [4] (the 5th character)
690// -- number ends with the character prior to the first "."
691//
692//returns "ABCD" as an invalid file number
693//
694// local function to aid in locating files by run number
695//
696Function/S V_GetRunNumStrFromFile(item)
697        String item
698        String invalid = "ABCD" //"ABCD" is not a valid run number, since it's text
699        Variable num=-1
700       
701        //find the "dot"
702        String runStr=""
703        Variable numChar = 4
704        Variable pos = strsearch(item,".",0)
705        if(pos == -1)
706                //"dot" not found
707                return (invalid)
708        else
709                //found, get the characters preceeding it, but still after the "sans" characters
710                if (pos-1 < 4)
711                        //not enough characters
712                        return (invalid)
713                else
714                        runStr = item[4,pos-1]
715                        return (runStr)
716                Endif
717        Endif
718End
719
720//Function attempts to find valid filename from partial name by checking for
721// the existence of the file on disk.
722// - checks as is
723// - strips spaces
724// - permutations of upper/lowercase
725//
726// added 11/99 - uppercase and lowercase versions of the file are tried, if necessary
727// since from marquee, the filename field (textread[0]) must be used, and can be a mix of                       //02JUL13
728// upper/lowercase letters, while the filename on the server (should) be all caps
729// now makes repeated calls to ValidFileString()
730//
731// returns a valid filename (No path prepended) or a null string
732//
733// called by any functions, both external and local
734//
735Function/S V_FindValidFilename(partialName)
736        String PartialName
737       
738        String retStr=""
739       
740        //try name with no changes - to allow for ABS files that have spaces in the names 12APR04
741        retStr = V_ValidFileString(partialName)
742        if(cmpstr(retStr,"") !=0)
743                //non-null return
744                return(retStr)
745        Endif
746       
747        //if the partial name is derived from the file header, there can be spaces at the beginning
748        //or in the middle of the filename - depending on the prefix and initials used
749        //
750        //remove any leading spaces from the name before starting
751        partialName = V_RemoveAllSpaces(partialName)
752       
753        //try name with no spaces
754        retStr = V_ValidFileString(partialName)
755        if(cmpstr(retStr,"") !=0)
756                //non-null return
757                return(retStr)
758        Endif
759       
760        //try all UPPERCASE
761        partialName = UpperStr(partialName)
762        retStr = V_ValidFileString(partialName)
763        if(cmpstr(retStr,"") !=0)
764                //non-null return
765                return(retStr)
766        Endif
767       
768        //try all lowercase (ret null if failure)
769        partialName = LowerStr(partialName)
770        retStr = V_ValidFileString(partialName)
771        if(cmpstr(retStr,"") !=0)
772                //non-null return
773                return(retStr)
774        else
775                return(retStr)
776        Endif
777End
778
779
780// Function checks for the existence of a file
781// partialName;vers (to account for VAX filenaming conventions)
782// The partial name is tried first with no version number
783//
784// *** the PATH is hard-wired to catPathName (which is assumed to exist)
785// version numers up to ;10 are tried
786// only the "name;vers" is returned if successful. The path is not prepended
787//
788// local function
789//
790// TODO -- is this really necessary anymore for the NON-VAX files of VSANS.
791// -- can this be made a pass-through, or will there be another function that is needed for VSANS?
792//
793Function/S V_ValidFileString(partialName)
794        String partialName
795       
796        String tempName = "",msg=""
797        Variable ii,refnum
798       
799        ii=0
800        do
801                if(ii==0)
802                        //first pass, try the partialName
803                        tempName = partialName
804                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName     //Does open file (/Z flag)
805                        if(V_flag == 0)
806                                //file exists
807                                Close refnum            //YES needed,
808                                break
809                        endif
810                else
811                        tempName = partialName + ";" + num2str(ii)
812                        Open/Z/R/T="????TEXT"/P=catPathName refnum tempName
813                        if(V_flag == 0)
814                                //file exists
815                                Close refnum
816                                break
817                        endif
818                Endif
819                ii+=1
820                //print "ii=",ii
821        while(ii<11)
822        //go get the selected bits of information, using tempName, which exists
823        if(ii>=11)
824                //msg = partialName + " not found. is version number > 11?"
825                //DoAlert 0, msg
826                //PathInfo catPathName
827                //Print S_Path
828                Return ("")             //use null string as error condition
829        Endif
830       
831        Return (tempName)
832End
833
834//function to remove all spaces from names when searching for filenames
835//the filename (as saved) will never have interior spaces (TTTTTnnn_AB _Bnnn)
836//but the text field in the header WILL, if less than 3 characters were used for the
837//user's initials, and can have leading spaces if prefix was less than 5 characters
838//
839//returns a string identical to the original string, except with the interior spaces removed
840//
841// local function for file name manipulation
842//
843Function/S V_RemoveAllSpaces(str)
844        String str
845       
846        String tempstr = str
847        Variable ii,spc,len             //should never be more than 2 or 3 trailing spaces in a filename
848        ii=0
849        do
850                len = strlen(tempStr)
851                spc = strsearch(tempStr," ",0)          //is the last character a space?
852                if (spc == -1)
853                        break           //no more spaces found, get out
854                endif
855                str = tempstr
856                tempStr = str[0,(spc-1)] + str[(spc+1),(len-1)] //remove the space from the string
857        While(1)        //should never be more than 2 or 3
858       
859        If(strlen(tempStr) < 1)
860                tempStr = ""            //be sure to return a null string if problem found
861        Endif
862       
863        //Print strlen(tempstr)
864       
865        Return(tempStr)
866               
867End
868
869// returns a list of raw data files in the catPathName directory on disk
870// - list is SEMICOLON-delimited
871//
872//  decide how to do this...
873// (1)
874// checks each file in the directory to see if it is a RAW data file by
875// call to V_CheckIfRawData() which currently looks for the instrument name in the file.
876// -- CON - this is excruciatingly slow, and by checking a field in the file, has to load in the
877//  ENTIRE data file, and will load EVERY file in the folder. ugh.
878//
879// (2)
880// as was done for VAX files, look for a specific string in the file name as written by the acquisition
881//  (was .saN), now key on ".nxs.ngv"?
882//
883// ** use method (2), reading each file is just way too slow
884//
885//
886Function/S V_GetRawDataFileList()
887       
888        //make sure that path exists
889        PathInfo catPathName
890        if (V_flag == 0)
891                Abort "Folder path does not exist - use Pick Path button on Main Panel"
892        Endif
893        String path = S_Path
894       
895        String list=IndexedFile(catPathName,-1,"????")
896        String newList="",item="",validName="",fullName=""
897        Variable num=ItemsInList(list,";"),ii
898       
899        for(ii=0;ii<num;ii+=1)
900                item = StringFromList(ii, list  ,";")
901
902                validName = V_FindValidFileName(item)
903                if(strlen(validName) != 0)              //non-null return from FindValidFileName()
904                        fullName = path + validName             
905
906        //method (1)                   
907//                      if(V_CheckIfRawData(item))
908//                              newlist += item + ";"
909//                      endif
910
911        //method (2)                   
912                        if( stringmatch(item,"*.nxs.ngv*") )
913                                newlist += item + ";"
914                        endif
915
916                       
917                endif
918                //print "ii=",ii
919        endfor
920        newList = SortList(newList,";",0)
921        return(newList)
922End
923
924//
925//
926// x- does this need to be more sophisticated?
927//
928// simple "not" of V_GetRawDataFileList()
929Function/S V_Get_NotRawDataFileList()
930       
931        //make sure that path exists
932        PathInfo catPathName
933        if (V_flag == 0)
934                Abort "Folder path does not exist - use Pick Path button on Main Panel"
935        Endif
936        String path = S_Path
937       
938        String list=IndexedFile(catPathName,-1,"????")
939        String newList="",item="",validName="",fullName=""
940        Variable num=ItemsInList(list,";"),ii
941       
942        for(ii=0;ii<num;ii+=1)
943                item = StringFromList(ii, list  ,";")
944
945//              validName = V_FindValidFileName(item)
946//              if(strlen(validName) != 0)              //non-null return from FindValidFileName()
947//                      fullName = path + validName             
948
949        //method (2)                   
950                        if( !stringmatch(item,"*.nxs.ngv*") )
951                                newlist += item + ";"
952                        endif
953
954                       
955//              endif
956                //print "ii=",ii
957        endfor
958        newList = SortList(newList,";",0)
959        return(newList)
960End
961
962
963//the following is a WaveMetrics procedure from <StrMatchList>
964// MatchList(matchStr,list,sep)
965// Returns the items of the list whose items match matchStr
966// The lists are separated by the sep character, usually ";"
967//
968// matchStr may be something like "abc", in which case it is identical to CmpStr
969// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
970//      "*abc" to match anything ending with "abc".
971// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
972//      the pattern.
973// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
974//
975Function/S V_MyMatchList(matchStr,list,sep)
976        String matchStr,list,sep
977        String item,outList=""
978        Variable n=strlen(list)
979        Variable en,st=0
980        do
981                en= strsearch(list,sep,st)
982                if( en < 0 )
983                        if( st < n-1 )
984                                en= n   // no trailing separator
985                                sep=""  // don't put sep in output, either
986                        else
987                                break   // no more items in list
988                        endif
989                endif
990                item=list[st,en-1]
991                if( V_MyStrMatch(matchStr,item) == 0 )
992                        outlist += item+sep
993                Endif
994                st=en+1
995        while (st < n ) // exit is by break, above
996        return outlist
997End
998
999//the following is a WaveMetrics procedure from <StrMatchList>
1000// StrMatch(matchStr,str)
1001// Returns 0 if the pattern in matchStr matches str, else it returns 1
1002//
1003// matchStr may be something like "abc", in which case it is identical to CmpStr
1004// matchStr may also be "*" to match anything, "abc*" to match anything starting with "abc",
1005//      "*abc" to match anything ending with "abc".
1006// matchStr may also begin with "!" to indicate a match to anything not matching the rest of
1007//      the pattern.
1008// At most one "*" and one "!" are allowed in matchStr, otherwise the results are not guaranteed.
1009//
1010Function V_MyStrMatch(matchStr,str)
1011        String matchStr,str
1012        Variable match = 1              // 0 means match
1013        Variable invert= strsearch(matchStr,"!",0) == 0
1014        if( invert )
1015                matchStr[0,0]=""        // remove the "!"
1016        endif
1017        Variable st=0,en=strlen(str)-1
1018        Variable starPos= strsearch(matchStr,"*",0)
1019        if( starPos >= 0 )      // have a star
1020                if( starPos == 0 )      // at start
1021                        matchStr[0,0]=""                                // remove star at start
1022                else                                    // at end
1023                        matchStr[starPos,999999]=""     // remove star and rest of (ignored, illegal) pattern
1024                endif
1025                Variable len=strlen(matchStr)
1026                if( len > 0 )
1027                        if(starPos == 0)        // star at start, match must be at end
1028                                st=en-len+1
1029                        else
1030                                en=len-1        // star at end, match at start
1031                        endif
1032                else
1033                        str=""  // so that "*" matches anything
1034                endif
1035        endif
1036        match= !CmpStr(matchStr,str[st,en])==0  // 1 or 0
1037        if( invert )
1038                match= 1-match
1039        endif
1040        return match
1041End
1042
1043
1044//input is a list of run numbers, and output is a list of filenames (not the full path)
1045//*** input list must be COMMA delimited***
1046//output is equivalent to selecting from the CAT table
1047//if some or all of the list items are valid filenames, keep them...
1048//if an error is encountered, notify of the offending element and return a null list
1049//
1050//output is COMMA delimited
1051//
1052// this routine is expecting that the "ask", "none" special cases are handled elsewhere
1053//and not passed here
1054//
1055// called by Marquee.ipf, MultipleReduce.ipf, ProtocolAsPanel.ipf
1056//
1057Function/S V_ParseRunNumberList(list)
1058        String list
1059       
1060        String newList="",item="",tempStr=""
1061        Variable num,ii,runNum
1062       
1063        //expand number ranges, if any
1064        list = V_ExpandNumRanges(list)
1065       
1066        num=itemsinlist(list,",")
1067       
1068        for(ii=0;ii<num;ii+=1)
1069                //get the item
1070                item = StringFromList(ii,list,",")
1071                //is it already a valid filename?
1072                tempStr=V_FindValidFilename(item) //returns filename if good, null if error
1073                if(strlen(tempstr)!=0)
1074                        //valid name, add to list
1075                        //Print "it's a file"
1076                        newList += tempStr + ","
1077                else
1078                        //not a valid name
1079                        //is it a number?
1080                        runNum=str2num(item)
1081                        //print runnum
1082                        if(numtype(runNum) != 0)
1083                                //not a number -  maybe an error                       
1084                                DoAlert 0,"List item "+item+" is not a valid run number or filename. Please enter a valid number or filename."
1085                                return("")
1086                        else
1087                                //a run number or an error
1088                                tempStr = V_GetFileNameFromPathNoSemi( V_FindFileFromRunNumber(runNum) )
1089                                if(strlen(tempstr)==0)
1090                                        //file not found, error
1091                                        DoAlert 0,"List item "+item+" is not a valid run number. Please enter a valid number."
1092                                        return("")
1093                                else
1094                                        newList += tempStr + ","
1095                                endif
1096                        endif
1097                endif
1098        endfor          //loop over all items in list
1099       
1100        return(newList)
1101End
1102
1103//takes a comma delimited list that MAY contain number range, and
1104//expands any range of run numbers into a comma-delimited list...
1105//and returns the new list - if not a range, return unchanged
1106//
1107// local function
1108//
1109Function/S V_ExpandNumRanges(list)
1110        String list
1111       
1112        String newList="",dash="-",item,str
1113        Variable num,ii,hasDash
1114       
1115        num=itemsinlist(list,",")
1116//      print num
1117        for(ii=0;ii<num;ii+=1)
1118                //get the item
1119                item = StringFromList(ii,list,",")
1120                //does it contain a dash?
1121                hasDash = strsearch(item,dash,0)                //-1 if no dash found
1122                if(hasDash == -1)
1123                        //not a range, keep it in the list
1124                        newList += item + ","
1125                else
1126                        //has a dash (so it's a range), expand (or add null)
1127                        newList += V_ListFromDash(item)         
1128                endif
1129        endfor
1130       
1131        return newList
1132End
1133
1134//be sure to add a trailing comma to the return string...
1135//
1136// local function
1137//
1138Function/S V_ListFromDash(item)
1139        String item
1140       
1141        String numList="",loStr="",hiStr=""
1142        Variable lo,hi,ii
1143       
1144        loStr=StringFromList(0,item,"-")        //treat the range as a list
1145        hiStr=StringFromList(1,item,"-")
1146        lo=str2num(loStr)
1147        hi=str2num(hiStr)
1148        if( (numtype(lo) != 0) || (numtype(hi) !=0 ) || (lo > hi) )
1149                numList=""
1150                return numList
1151        endif
1152        for(ii=lo;ii<=hi;ii+=1)
1153                numList += num2str(ii) + ","
1154        endfor
1155       
1156        Return numList
1157End
1158
1159//*********************
1160// List utilities
1161//*********************
1162Function/WAVE V_List2TextWave(list,sep,waveStr)
1163        String list,sep,waveStr
1164       
1165        Variable n= ItemsInList(list,sep)
1166        Make/O/T/N=(n) $waveStr= StringFromList(p,list,sep)
1167        return $waveStr
1168End
1169
1170Function/WAVE V_List2NumWave(list,sep,waveStr)
1171        String list,sep,waveStr
1172       
1173        Variable n= ItemsInList(list,sep)
1174        Make/O/D/N=(n) $waveStr= str2num( StringFromList(p,list,sep) )
1175        return $waveStr
1176End
1177
1178Function /S V_TextWave2List(w,sep)
1179        Wave/T w
1180        String sep
1181       
1182        String newList=""
1183        Variable n=numpnts(w),ii=0
1184        do
1185                newList += w[ii] + sep
1186                ii+=1
1187        while(ii<n)
1188        return(newList)
1189End
1190
1191//for numerical waves
1192Function/S V_NumWave2List(w,sep)
1193        Wave w
1194        String sep
1195       
1196        String newList="",temp=""
1197        Variable n=numpnts(w),ii=0,val
1198        do
1199                val=w[ii]
1200                temp=""
1201                sprintf temp,"%g",val
1202                newList += temp
1203                newList += sep
1204                ii+=1
1205        while(ii<n)
1206        return(newList)
1207End
1208
1209
1210/////
1211// @ IgorExchange
1212//TicToc
1213//Posted April 16th, 2009 by bgallarda
1214//      ¥       in Programming 6.10.x
1215
1216////duplicated here -- for VSANS use
1217function v_tic()
1218        variable/G tictoc = startMSTimer
1219end
1220 
1221function v_toc()
1222        NVAR/Z tictoc
1223        variable ttTime = stopMSTimer(tictoc)
1224        printf "%g seconds\r", (ttTime/1e6)
1225        killvariables/Z tictoc
1226end
1227
1228
1229
1230////// methods for filtering out different lists of files.
1231
1232// testStr is the "intent" string, or grep string
1233// method is the method to use to find the file
1234// 0 = (default) is to use the file catalog (= fastest)
1235// 1 = Grep (not terribly slow)
1236// 2 = read every file (bad choice)
1237//
1238Function/S V_getFileIntentList(testStr,method)
1239        String testStr
1240        Variable method
1241       
1242        Variable ii,num
1243        String list="",item="",fname,newList,intent
1244
1245        // read every file...
1246        if(method == 2)
1247                PathInfo catPathName
1248                String path = S_path
1249                newList = V_GetRawDataFileList()
1250                num=ItemsInList(newList)
1251               
1252                for(ii=0;ii<num;ii+=1)
1253                        item=StringFromList(ii, newList , ";")
1254                        fname = path + item
1255                        intent = V_getReduction_intent(fname)
1256                        if(cmpstr(intent,testStr) == 0)
1257                                list += item + ";"
1258                        endif
1259                endfor 
1260        endif
1261       
1262        // use Grep
1263        if(method == 1)
1264                newList = V_GetRawDataFileList()
1265                num=ItemsInList(newList)
1266                for(ii=0;ii<num;ii+=1)
1267                        item=StringFromList(ii, newList , ";")
1268                        Grep/P=catPathName/Q/E=("(?i)"+testStr) item
1269                        if( V_value )   // at least one instance was found
1270        //                              Print "found ", item,ii
1271                                list += item + ";"
1272                        endif
1273                endfor 
1274       
1275        else
1276        // get the list from the file catalog
1277       
1278                WAVE/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
1279                WAVE/T intentW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Intent
1280               
1281                Variable np = numpnts(intentW)          //fileNameW is LONGER - so don't use numpnts(fileWave)
1282                for(ii=0;ii<np;ii+=1)
1283                        if(cmpstr(intentW[ii],testStr)==0)              //this is case-INSENSITIVE (necessary, since the case is unknown)
1284                                list += fileNameW[ii] + ";"
1285                        endif           
1286                endfor
1287               
1288                List = SortList(List,";",0)
1289        endif
1290       
1291        return(list)
1292end
1293
1294
1295// testStr is the "purpose" string, or grep string
1296// method is the method to use to find the file
1297// 0 = (default) is to use the file catalog (= fastest)
1298// 1 = Grep (not terribly slow)
1299// 2 = read every file (bad choice)
1300//
1301Function/S V_getFilePurposeList(testStr,method)
1302        String testStr
1303        Variable method
1304       
1305        Variable ii,num
1306        String list="",item="",fname,newList,purpose
1307
1308        // read every file...
1309        if(method == 2)
1310                PathInfo catPathName
1311                String path = S_path
1312                newList = V_GetRawDataFileList()
1313                num=ItemsInList(newList)
1314               
1315                for(ii=0;ii<num;ii+=1)
1316                        item=StringFromList(ii, newList , ";")
1317                        fname = path + item
1318                        purpose = V_getReduction_purpose(fname)
1319                        if(cmpstr(purpose,testStr) == 0)
1320                                list += item + ";"
1321                        endif
1322                endfor 
1323        endif
1324       
1325        // use Grep
1326        if(method == 1)
1327                newList = V_GetRawDataFileList()
1328                num=ItemsInList(newList)
1329                for(ii=0;ii<num;ii+=1)
1330                        item=StringFromList(ii, newList , ";")
1331                        Grep/P=catPathName/Q/E=("(?i)"+testStr) item
1332                        if( V_value )   // at least one instance was found
1333        //                              Print "found ", item,ii
1334                                list += item + ";"
1335                        endif
1336                endfor 
1337       
1338        else
1339        // get the list from the file catalog
1340       
1341                WAVE/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
1342                WAVE/T purposeW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Purpose
1343               
1344                Variable np = numpnts(purposeW)         //fileNameW is LONGER - so don't use numpnts(fileWave)
1345                for(ii=0;ii<np;ii+=1)
1346                        if(cmpstr(purposeW[ii],testStr)==0)             //this is case-INSENSITIVE (necessary, since the case is unknown)
1347                                list += fileNameW[ii] + ";"
1348                        endif           
1349                endfor
1350               
1351                List = SortList(List,";",0)
1352        endif
1353       
1354        return(list)
1355end
1356
1357
1358// match BOTH the intent and purpose
1359// -- needed to identify the SAMPLE + SCATTERING data files.
1360//
1361//
1362// method is the method to use to find the file (currently ignored, CAT is always used)
1363// 0 = (default) is to use the file catalog (= fastest)
1364// 1 = Grep (not terribly slow)
1365// 2 = read every file (bad choice)
1366//
1367Function/S V_getFileIntentPurposeList(intent,purpose,method)
1368        String intent,purpose
1369        Variable method
1370       
1371        Variable ii,num
1372        String list="",item="",fname,newList
1373
1374//      // read every file...
1375//      if(method == 2)
1376//              PathInfo catPathName
1377//              String path = S_path
1378//              newList = V_GetRawDataFileList()
1379//              num=ItemsInList(newList)
1380//             
1381//              for(ii=0;ii<num;ii+=1)
1382//                      item=StringFromList(ii, newList , ";")
1383//                      fname = path + item
1384//                      purpose = V_getReduction_purpose(fname)
1385//                      if(cmpstr(purpose,testStr) == 0)
1386//                              list += item + ";"
1387//                      endif
1388//              endfor 
1389//      endif
1390//     
1391//      // use Grep
1392//      if(method == 1)
1393//              newList = V_GetRawDataFileList()
1394//              num=ItemsInList(newList)
1395//              for(ii=0;ii<num;ii+=1)
1396//                      item=StringFromList(ii, newList , ";")
1397//                      Grep/P=catPathName/Q/E=("(?i)"+testStr) item
1398//                      if( V_value )   // at least one instance was found
1399//      //                              Print "found ", item,ii
1400//                              list += item + ";"
1401//                      endif
1402//              endfor 
1403//     
1404//      else
1405        // get the list from the file catalog
1406       
1407                WAVE/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
1408                WAVE/T purposeW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Purpose
1409                WAVE/T intentW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Intent
1410               
1411                Variable np = numpnts(purposeW)         //fileNameW is LONGER - so don't use numpnts(fileWave)
1412                for(ii=0;ii<np;ii+=1)
1413                        if(cmpstr(purposeW[ii],purpose)==0 && cmpstr(intentW[ii],intent)==0)            //this is case-INSENSITIVE (necessary, since the case is unknown)
1414                                list += fileNameW[ii] + ";"
1415                        endif           
1416                endfor
1417               
1418                List = SortList(List,";",0)
1419       
1420        return(list)
1421end
1422
1423
1424
Note: See TracBrowser for help on using the repository browser.