source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_HDF5_RW_Utils.ipf @ 971

Last change on this file since 971 was 971, checked in by srkline, 7 years ago

Filling in missing "dummy" functions when XML xop is not present.

Added new V_ procedures for the beginning of the reduction steps - initialization, main panel, preferences, and a menu. These are lifted directly from the SANS routines and much still needs to be modified.

File size: 13.1 KB
Line 
1#pragma rtGlobals=3             // Use modern global access method and strict wave access.
2
3//
4// The base functions for R/W from HDF5 files.
5// All of the specific "get" and "write" functions call these base functions which are responsible
6// for all of the open/close mechanics.
7//
8// These VSANS file-specific functions are in:
9// V_HDF5_Read.ipf
10//               and
11// V_HDF5_Write.ipf
12//
13
14// data is read into:
15//      NewDataFolder/O/S root:Packages:NIST:VSANS:RawVSANS
16// so that the data folders of the raw data won't be lying around on the top level, looking like
17// 1D data sets and interfering.
18
19
20// the base data folder path where the raw data is loaded
21Strconstant ksBaseDFPath = "root:Packages:NIST:VSANS:RawVSANS:"
22
23
24
25// passing null file string presents a dialog
26Macro Read_HDF5_Raw_No_Attributes()
27        V_LoadHDF5Data("")
28End
29
30// TODO -- move the initializtion of the raw data folder to be in the as-yet unwritten initialization routine for
31// reduction. be sure that it's duplicated in the VCALC initialization too.
32//
33Proc V_LoadHDF5Data(file)
34        String file
35
36        NewDataFolder/O/S root:Packages:NIST:VSANS:RawVSANS
37//      SetDataFolder root:
38        Variable err= V_LoadHDF5_NoAtt(file)    // reads into current folder
39        SetDataFolder root:
40End
41
42
43// This loads for speed, since loading the attributes takes a LOT of time.
44//
45// this will load in the whole HDF file all at once.
46// Attributes are NOT loaded at all.
47//
48// TODO: remove the P=home restriction top make this more generic
49// -- get rid of bits leftover here that I don't need
50// -- be sure I'm using all of the correct flags in the HDF5LoadGroup operation
51//
52Function V_LoadHDF5_NoAtt(fileName, [hdf5Path])
53        String fileName, hdf5Path
54        if ( ParamIsDefault(hdf5Path) )
55                hdf5Path = "/"
56        endif
57
58        String status = ""
59
60        Variable fileID = 0
61        HDF5OpenFile/R/P=home/Z fileID as fileName              //read file from home directory?
62//      HDF5OpenFile/R/P=catPathName/Z fileID as fileName
63        if (V_Flag != 0)
64                return 0
65        endif
66
67        String/G root:file_path = S_path
68        String/G root:file_name = S_FileName
69       
70        if ( fileID == 0 )
71                Print fileName + ": could not open as HDF5 file"
72                return (0)
73        endif
74       
75//s_tic()               //fast
76       
77        SVAR tmpStr=root:file_name
78        fileName=tmpStr         //SRK - in case the file was chosen from a dialog
79       
80        //   read the data (too bad that HDF5LoadGroup does not read the attributes)
81        String base_name = StringFromList(0,FileName,".")
82        HDF5LoadGroup/Z/L=7/O/R/T=$base_name  :, fileID, hdf5Path               //      recursive
83        if ( V_Flag != 0 )
84                Print fileName + ": could not open as HDF5 file"
85                setdatafolder root:
86                return (0)
87        endif
88
89        HDF5CloseFile fileID
90       
91//s_toc()
92        return(0)
93end     
94
95
96// read a single real value
97// - fname passed in is the full path to the file on disk
98// - path is the path to the value in the HDF tree
99//
100// check to see if the value exists (It will be a wave)
101// -- if it does, return the value from the local folder
102// -- if not, read the file in, then return the value
103//
104Function V_getRealValueFromHDF5(fname,path)
105        String fname,path
106
107        String folderStr=""
108        Variable valExists=0
109       
110        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
111       
112        if(Exists(ksBaseDFPath+folderStr+":"+path))
113                valExists=1
114        endif
115       
116        if(!valExists)
117                //then read in the file
118                V_LoadHDF5_NoAtt(fname)
119        endif
120
121// this should exist now - if not, I need to see the error
122        Wave/Z w = $(ksBaseDFPath+folderStr+":"+path)
123       
124        if(WaveExists(w))
125                return(w[0])
126        else
127                return(-999999)
128        endif   
129End
130
131// Returns a wave reference, not just a single value
132// ---then you pick what you need from the wave
133//
134// - fname passed in is the full path to the file on disk
135// - path is the path to the value in the HDF tree
136//
137// check to see if the value exists (It will be a wave)
138// -- if it does, return the value from the local folder
139// -- if not, read the file in, then return the value
140//
141Function/WAVE V_getRealWaveFromHDF5(fname,path)
142        String fname,path
143
144        String folderStr=""
145        Variable valExists=0
146       
147        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
148       
149        if(Exists(ksBaseDFPath+folderStr+":"+path))
150                valExists=1
151        endif
152       
153        if(!valExists)
154                //then read in the file
155                V_LoadHDF5_NoAtt(fname)
156        endif
157
158// this should exist now - if not, I need to see the error
159        Wave wOut = $(ksBaseDFPath+folderStr+":"+path)
160       
161        return wOut
162       
163End
164
165// Returns a wave reference, not just a single value
166// ---then you pick what you need from the wave
167//
168// - fname passed in is the full path to the file on disk
169// - path is the path to the value in the HDF tree
170//
171// check to see if the value exists (It will be a wave)
172// -- if it does, return the value from the local folder
173// -- if not, read the file in, then return the value
174//
175Function/WAVE V_getTextWaveFromHDF5(fname,path)
176        String fname,path
177
178        String folderStr=""
179        Variable valExists=0
180       
181        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
182       
183        if(Exists(ksBaseDFPath+folderStr+":"+path))
184                valExists=1
185        endif
186       
187        if(!valExists)
188                //then read in the file
189                V_LoadHDF5_NoAtt(fname)
190        endif
191
192// this should exist now - if not, I need to see the error
193        Wave/T wOut = $(ksBaseDFPath+folderStr+":"+path)
194       
195        return wOut
196       
197End
198
199
200//
201//   TODO
202// depricated? in HDF5 - store all of the values as real?
203// Igor sees no difference in real and integer variables (waves are different)
204// BUT-- Igor 7 will have integer variables
205//
206// truncate to integer before returning??
207//
208//  TODO
209// write a "getIntegerWave" function??
210//
211//////  integer values
212// reads 32 bit integer
213Function V_getIntegerFromHDF5(fname,path)
214        String fname                            //full path+name
215        String path                             //path to the hdf5 location
216       
217        Variable val = V_getRealValueFromHDF5(fname,path)
218       
219        val = round(val)
220        return(val)
221End
222
223
224// read a single string
225// - fname passed in is the full path to the file on disk
226// - path is the path to the value in the HDF tree
227// - num is the number of characters in the VAX string
228// check to see if the value exists (It will be a wave)
229// -- if it does, return the value from the local folder
230// -- if not, read the file in, then return the value
231//
232// TODO -- string could be checked for length, but returned right or wrong
233//
234Function/S V_getStringFromHDF5(fname,path,num)
235        String fname,path
236        Variable num
237
238        String folderStr=""
239        Variable valExists=0
240       
241        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
242       
243        if(Exists(ksBaseDFPath+folderStr+":"+path))
244                valExists=1
245        endif
246       
247        if(!valExists)
248                //then read in the file
249                V_LoadHDF5_NoAtt(fname)
250        endif
251
252// this should exist now - if not, I need to see the error
253        Wave/T/Z tw = $(ksBaseDFPath+folderStr+":"+path)
254       
255        if(WaveExists(tw))
256       
257        //      if(strlen(tw[0]) != num)
258        //              Print "string is not the specified length"
259        //      endif
260               
261                return(tw[0])
262        else
263                return("The specified wave does not exist: " + path)
264        endif
265End
266
267
268
269///////////////////////////////
270
271//
272//Write Wave 'wav' to hdf5 file 'fname'
273//Based on code from ANSTO (N. Hauser. nha 8/1/09)
274//
275// TODO:
276// -- figure out if this will write in the native format of the
277//     wave as passed in, or if it will only write as DP.
278// -- do I need to write separate functions for real, integer, etc.?
279//     
280// -- change the /P=home to the user-defined data path (which may be home)             
281//
282Function V_WriteWaveToHDF(fname, groupName, varName, wav)
283        String fname, groupName, varName
284        Wave wav
285       
286        variable err=0, fileID,groupID
287        String cDF = getDataFolder(1), temp
288        String NXentry_name
289       
290        try     
291                HDF5OpenFile/P=home /Z fileID  as fname  //open file read-write
292                if(!fileID)
293                        err = 1
294                        abort "HDF5 file does not exist"
295                endif
296               
297                //get the NXentry node name
298                HDF5ListGroup /TYPE=1 fileID, "/"
299                //remove trailing ; from S_HDF5ListGroup
300               
301                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
302               
303                NXentry_name = S_HDF5ListGroup
304                NXentry_name = ReplaceString(";",NXentry_name,"")
305                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
306                        err = 1
307                        abort "More than one entry under the root node. Ambiguous"
308                endif
309                //concatenate NXentry node name and groupName   
310                // SRK - NOV2015 - dropped this and require the full group name passed in
311//              groupName = "/" + NXentry_name + groupName
312                Print "groupName = ",groupName
313                HDF5OpenGroup /Z fileID , groupName, groupID
314
315                if(!groupID)
316                // don't create the group it the name isn't right -- throw up an error
317                        //HDF5CreateGroup /Z fileID, groupName, groupID
318                        err = 1
319                        HDF5CloseFile /Z fileID
320                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
321                        return(err)
322                else
323                        // get attributes and save them
324                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
325                        //Wave attributes = S_HDF5ListAttributes
326                endif
327       
328                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
329                if (V_flag != 0)
330                        err = 1
331                        abort "Cannot save wave to HDF5 dataset " + varName
332                endif   
333               
334               
335                //attributes - something could be added here as optional parameters and flagged
336//              String attributes = "units"
337//              Make/O/T/N=1 tmp
338//              tmp[0] = "dimensionless"
339//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
340//              if (V_flag != 0)
341//                      err = 1
342//                      abort "Cannot save attributes to HDF5 dataset"
343//              endif   
344        catch
345
346        endtry
347
348// it is not necessary to close the group here. HDF5CloseFile will close the group as well     
349        if(groupID)
350                HDF5CloseGroup /Z groupID
351        endif
352       
353        if(fileID)
354                HDF5CloseFile /Z fileID
355        endif
356
357        setDataFolder $cDF
358        return err
359end
360
361//Write Wave 'wav' to hdf5 file 'fname'
362//Based on code from ANSTO (N. Hauser. nha 8/1/09)
363//
364// TODO
365//
366// -- change the /P=home to the user-defined data path (which may be home)             
367//
368Function V_WriteTextWaveToHDF(fname, groupName, varName, wav)
369        String fname, groupName, varName
370        Wave/T wav
371       
372        variable err=0, fileID,groupID
373        String cDF = getDataFolder(1), temp
374        String NXentry_name
375       
376        try     
377                HDF5OpenFile/P=home /Z fileID  as fname  //open file read-write
378                if(!fileID)
379                        err = 1
380                        abort "HDF5 file does not exist"
381                endif
382               
383                //get the NXentry node name
384                HDF5ListGroup /TYPE=1 fileID, "/"
385                //remove trailing ; from S_HDF5ListGroup
386               
387                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
388               
389                NXentry_name = S_HDF5ListGroup
390                NXentry_name = ReplaceString(";",NXentry_name,"")
391                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
392                        err = 1
393                        abort "More than one entry under the root node. Ambiguous"
394                endif
395
396                //concatenate NXentry node name and groupName
397                // SRK - NOV2015 - dropped this and require the full group name passed in
398//              groupName = "/" + NXentry_name + groupName
399                Print "groupName = ",groupName
400
401                HDF5OpenGroup /Z fileID , groupName, groupID
402
403                if(!groupID)
404                // don't create the group it the name isn't right -- throw up an error
405                        //HDF5CreateGroup /Z fileID, groupName, groupID
406                        err = 1
407                        HDF5CloseFile /Z fileID
408                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
409                        return(err)
410                else
411                        // get attributes and save them
412                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
413                        //Wave attributes = S_HDF5ListAttributes
414                endif
415       
416                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
417                if (V_flag != 0)
418                        err = 1
419                        abort "Cannot save wave to HDF5 dataset " + varName
420                endif   
421               
422               
423                //attributes - something could be added here as optional parameters and flagged
424//              String attributes = "units"
425//              Make/O/T/N=1 tmp
426//              tmp[0] = "dimensionless"
427//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
428//              if (V_flag != 0)
429//                      err = 1
430//                      abort "Cannot save attributes to HDF5 dataset"
431//              endif   
432        catch
433
434        endtry
435       
436        if(groupID)
437                HDF5CloseGroup /Z groupID
438        endif
439       
440        if(fileID)
441                HDF5CloseFile /Z fileID
442        endif
443
444        setDataFolder $cDF
445        return err
446end
447
448//////////////////////////////
449//////////////////////////////
450//////////////////////////////
451
452Function V_KillNamedDataFolder(fname)
453        String fname
454       
455        Variable err=0
456       
457        String folderStr = V_GetFileNameFromPathNoSemi(fname)
458        folderStr = V_RemoveDotExtension(folderStr)
459       
460        KillDataFolder/Z $(ksBaseDFPath+folderStr)
461        err = V_flag
462       
463        return(err)
464end
465
466//given a filename of a SANS data filename of the form
467// name.anything
468//returns the name as a string without the ".fbdfasga" extension
469//
470// returns the input string if a"." can't be found (maybe it wasn't there"
471Function/S V_RemoveDotExtension(item)
472        String item
473        String invalid = item   //
474        Variable num=-1
475       
476        //find the "dot"
477        String runStr=""
478        Variable pos = strsearch(item,".",0)
479        if(pos == -1)
480                //"dot" not found
481                return (invalid)
482        else
483                //found, get all of the characters preceeding it
484                runStr = item[0,pos-1]
485                return (runStr)
486        Endif
487End
488
489//returns a string containing filename (WITHOUT the ;vers)
490//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
491//with the folders separated by colons
492//
493// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
494//
495Function/S V_GetFileNameFromPathNoSemi(fullPath)
496        String fullPath
497       
498        Variable offset1,offset2
499        String filename=""
500        //String PartialPath
501        offset1 = 0
502        do
503                offset2 = StrSearch(fullPath, ":", offset1)
504                if (offset2 == -1)                              // no more colons ?
505                        fileName = FullPath[offset1,strlen(FullPath) ]
506                        //PartialPath = FullPath[0, offset1-1]
507                        break
508                endif
509                offset1 = offset2+1
510        while (1)
511       
512        //remove version number from name, if it's there - format should be: filename;N
513        filename =  StringFromList(0,filename,";")              //returns null if error
514       
515        Return filename
516End
Note: See TracBrowser for help on using the repository browser.