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

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

First pass at all of the get() and write() accessors for the Nexus VSANS file. The definition is still incomplete and untested, so these procedures will require complete verification, and some editing.

get and write are separated into their own files, so be sure to make the change in the pair if needed

File size: 9.7 KB
Line 
1#pragma rtGlobals=3             // Use modern global access method and strict wave access.
2
3
4
5//
6// Start to build up and test the r/w accessors for VSANS
7// (SANS has a template, VSANS does not, so just start from scratch here, since the
8// file structure will be different)
9//
10//
11
12
13// thought this would be useful, but the file name (folder) is stuck in the middle...
14Strconstant ksPathPrefix = "root:(folder):entry:entry1:"
15
16
17
18// passing null file string presents a dialog
19Macro Read_HDF5_Raw_No_Attributes()
20        V_LoadHDF5Data("")
21End
22
23Proc V_LoadHDF5Data(file)
24        String file
25
26        SetDataFolder root:     
27        Variable err= V_LoadHDF5_NoAtt(file)    // reads into current folder
28        SetDataFolder root:
29End
30
31
32// This loads for speed, since loading the attributes takes a LOT of time.
33//
34// this will load in the whole HDF file all at once.
35// Attributes are NOT loaded at all.
36//
37// TODO: remove the P=home restriction top make this more generic
38// -- get rid of bits leftover here that I don't need
39// -- be sure I'm using all of the correct flags in the HDF5LoadGroup operation
40//
41Function V_LoadHDF5_NoAtt(fileName, [hdf5Path])
42        String fileName, hdf5Path
43        if ( ParamIsDefault(hdf5Path) )
44                hdf5Path = "/"
45        endif
46
47        String status = ""
48
49        Variable fileID = 0
50        HDF5OpenFile/R/P=home/Z fileID as fileName              //read file from home directory?
51//      HDF5OpenFile/R/P=catPathName/Z fileID as fileName
52        if (V_Flag != 0)
53                return 0
54        endif
55
56        String/G root:file_path = S_path
57        String/G root:file_name = S_FileName
58       
59        if ( fileID == 0 )
60                Print fileName + ": could not open as HDF5 file"
61                return (0)
62        endif
63       
64//s_tic()               //fast
65       
66        SVAR tmpStr=root:file_name
67        fileName=tmpStr         //SRK - in case the file was chosen from a dialog
68       
69        //   read the data (too bad that HDF5LoadGroup does not read the attributes)
70        String base_name = StringFromList(0,FileName,".")
71        HDF5LoadGroup/Z/L=7/O/R/T=$base_name  :, fileID, hdf5Path               //      recursive
72        if ( V_Flag != 0 )
73                Print fileName + ": could not open as HDF5 file"
74                setdatafolder root:
75                return (0)
76        endif
77
78        HDF5CloseFile fileID
79       
80//s_toc()
81        return(0)
82end     
83
84
85// read a single real value
86// - fname passed in is the full path to the file on disk
87// - path is the path to the value in the HDF tree
88//
89// check to see if the value exists (It will be a wave)
90// -- if it does, return the value from the local folder
91// -- if not, read the file in, then return the value
92//
93Function V_getRealValueFromHDF5(fname,path)
94        String fname,path
95
96        String folderStr=""
97        Variable valExists=0
98       
99        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
100       
101        if(Exists("root:"+folderStr+":"+path))
102                valExists=1
103        endif
104       
105        if(!valExists)
106                //then read in the file
107                V_LoadHDF5_NoAtt(fname)
108        endif
109
110// this should exist now - if not, I need to see the error
111        Wave/Z w = $("root:"+folderStr+":"+path)
112       
113        if(WaveExists(w))
114                return(w[0])
115        else
116                return(-999999)
117        endif   
118End
119
120// Returns a wave reference, not just a single value
121// ---then you pick what you need from the wave
122//
123// - fname passed in is the full path to the file on disk
124// - path is the path to the value in the HDF tree
125//
126// check to see if the value exists (It will be a wave)
127// -- if it does, return the value from the local folder
128// -- if not, read the file in, then return the value
129//
130Function/WAVE V_getRealWaveFromHDF5(fname,path)
131        String fname,path
132
133        String folderStr=""
134        Variable valExists=0
135       
136        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
137       
138        if(Exists("root:"+folderStr+":"+path))
139                valExists=1
140        endif
141       
142        if(!valExists)
143                //then read in the file
144                V_LoadHDF5_NoAtt(fname)
145        endif
146
147// this should exist now - if not, I need to see the error
148        Wave wOut = $("root:"+folderStr+":"+path)
149       
150        return wOut
151       
152End
153
154//
155//   TODO
156// depricated? in HDF5 - store all of the values as real?
157// Igor sees no difference in real and integer variables (waves are different)
158// BUT-- Igor 7 will have integer variables
159//
160// truncate to integer before returning??
161//
162//////  integer values
163// reads 32 bit integer
164Function V_getIntegerFromHDF5(fname,path)
165        String fname                            //full path+name
166        String path                             //path to the hdf5 location
167       
168        Variable val = V_getRealValueFromHDF5(fname,path)
169       
170        val = round(val)
171        return(val)
172End
173
174
175// read a single string
176// - fname passed in is the full path to the file on disk
177// - path is the path to the value in the HDF tree
178// - num is the number of characters in the VAX string
179// check to see if the value exists (It will be a wave)
180// -- if it does, return the value from the local folder
181// -- if not, read the file in, then return the value
182//
183// TODO -- string could be checked for length, but returned right or wrong
184//
185Function/S V_getStringFromHDF5(fname,path,num)
186        String fname,path
187        Variable num
188
189        String folderStr=""
190        Variable valExists=0
191       
192        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
193       
194        if(Exists("root:"+folderStr+":"+path))
195                valExists=1
196        endif
197       
198        if(!valExists)
199                //then read in the file
200                V_LoadHDF5_NoAtt(fname)
201        endif
202
203// this should exist now - if not, I need to see the error
204        Wave/T/Z tw = $("root:"+folderStr+":"+path)
205       
206        if(WaveExists(tw))
207       
208        //      if(strlen(tw[0]) != num)
209        //              Print "string is not the specified length"
210        //      endif
211               
212                return(tw[0])
213        else
214                return("The specified wave does not exist: " + path)
215        endif
216End
217
218
219
220///////////////////////////////
221
222//
223//Write Wave 'wav' to hdf5 file 'fname'
224//Based on code from ANSTO (N. Hauser. nha 8/1/09)
225//
226// TODO:
227// -- figure out if this will write in the native format of the
228//     wave as passed in, or if it will only write as DP.
229// -- do I need to write separate functions for real, integer, etc.?
230//     
231// -- change the /P=home to the user-defined data path (which may be home)             
232//
233Function V_WriteWaveToHDF(fname, groupName, varName, wav)
234        String fname, groupName, varName
235        Wave wav
236       
237        variable err=0, fileID,groupID
238        String cDF = getDataFolder(1), temp
239        String NXentry_name
240       
241        try     
242                HDF5OpenFile/P=home /Z fileID  as fname  //open file read-write
243                if(!fileID)
244                        err = 1
245                        abort "HDF5 file does not exist"
246                endif
247               
248                //get the NXentry node name
249                HDF5ListGroup /TYPE=1 fileID, "/"
250                //remove trailing ; from S_HDF5ListGroup
251               
252                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
253               
254                NXentry_name = S_HDF5ListGroup
255                NXentry_name = ReplaceString(";",NXentry_name,"")
256                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
257                        err = 1
258                        abort "More than one entry under the root node. Ambiguous"
259                endif
260                //concatenate NXentry node name and groupName   
261                // SRK - NOV2015 - dropped this and require the full group name passed in
262//              groupName = "/" + NXentry_name + groupName
263                Print "groupName = ",groupName
264                HDF5OpenGroup /Z fileID , groupName, groupID
265
266                if(!groupID)
267                        HDF5CreateGroup /Z fileID, groupName, groupID
268                        //err = 1
269                        //abort "HDF5 group does not exist"
270                else
271                        // get attributes and save them
272                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
273                        //Wave attributes = S_HDF5ListAttributes
274                endif
275       
276                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
277                if (V_flag != 0)
278                        err = 1
279                        abort "Cannot save wave to HDF5 dataset " + varName
280                endif   
281               
282               
283                //attributes - something could be added here as optional parameters and flagged
284//              String attributes = "units"
285//              Make/O/T/N=1 tmp
286//              tmp[0] = "dimensionless"
287//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
288//              if (V_flag != 0)
289//                      err = 1
290//                      abort "Cannot save attributes to HDF5 dataset"
291//              endif   
292        catch
293
294        endtry
295
296// it is not necessary to close the group here. HDF5CloseFile will close the group as well     
297        if(groupID)
298                HDF5CloseGroup /Z groupID
299        endif
300       
301        if(fileID)
302                HDF5CloseFile /Z fileID
303        endif
304
305        setDataFolder $cDF
306        return err
307end
308
309//Write Wave 'wav' to hdf5 file 'fname'
310//Based on code from ANSTO (N. Hauser. nha 8/1/09)
311//
312// TODO
313//
314// -- change the /P=home to the user-defined data path (which may be home)             
315//
316Function V_WriteTextWaveToHDF(fname, groupName, varName, wav)
317        String fname, groupName, varName
318        Wave/T wav
319       
320        variable err=0, fileID,groupID
321        String cDF = getDataFolder(1), temp
322        String NXentry_name
323       
324        try     
325                HDF5OpenFile/P=home /Z fileID  as fname  //open file read-write
326                if(!fileID)
327                        err = 1
328                        abort "HDF5 file does not exist"
329                endif
330               
331                //get the NXentry node name
332                HDF5ListGroup /TYPE=1 fileID, "/"
333                //remove trailing ; from S_HDF5ListGroup
334               
335                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
336               
337                NXentry_name = S_HDF5ListGroup
338                NXentry_name = ReplaceString(";",NXentry_name,"")
339                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
340                        err = 1
341                        abort "More than one entry under the root node. Ambiguous"
342                endif
343
344                //concatenate NXentry node name and groupName
345                // SRK - NOV2015 - dropped this and require the full group name passed in
346//              groupName = "/" + NXentry_name + groupName
347                Print "groupName = ",groupName
348
349                HDF5OpenGroup /Z fileID , groupName, groupID
350
351                if(!groupID)
352                        HDF5CreateGroup /Z fileID, groupName, groupID
353                        //err = 1
354                        //abort "HDF5 group does not exist"
355                else
356                        // get attributes and save them
357                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
358                        //Wave attributes = S_HDF5ListAttributes
359                endif
360       
361                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
362                if (V_flag != 0)
363                        err = 1
364                        abort "Cannot save wave to HDF5 dataset " + varName
365                endif   
366               
367               
368                //attributes - something could be added here as optional parameters and flagged
369//              String attributes = "units"
370//              Make/O/T/N=1 tmp
371//              tmp[0] = "dimensionless"
372//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
373//              if (V_flag != 0)
374//                      err = 1
375//                      abort "Cannot save attributes to HDF5 dataset"
376//              endif   
377        catch
378
379        endtry
380       
381        if(groupID)
382                HDF5CloseGroup /Z groupID
383        endif
384       
385        if(fileID)
386                HDF5CloseFile /Z fileID
387        endif
388
389        setDataFolder $cDF
390        return err
391end
Note: See TracBrowser for help on using the repository browser.