source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/VC_HDF5_VSANS_Utils.ipf @ 958

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

more changes to the procedures and panel to allow fitting of each panel to determine the beam center.

File size: 14.2 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2
3//
4// This file has lots of utility procedures to be able to read/write
5// test HDF5 files for SANS and VSANS in Nexus format
6//
7// It doesn't have the NICE logs, but has everything that I
8// can think of here.
9//
10
11//
12// There's an odd sequence of steps that need to be done to use HDFGateway
13// to most easily write out attributes, and be able to read then back in.
14// Rather awkward, but it works without me needing to go nuts with an atomistic
15// understanding of HDF5. This is necessary for me to be able to write out
16// Nexus files, which is important both for testing, and for simulation.
17//
18// This is done as a set of macros that need to be applied in a specific sequence
19// in order to be able to generate HDF5___xref
20// Ideally, the HDF5___xref wave can be saved/imported to make proper saving possible
21// once the "tree" is finalized.
22//
23//
24// The basic saving routines are here, just as Proc rather than Macro menu clutter
25//
26
27
28// Next... think of all of R/W access needed
29//
30// the simple read/write works...
31// linear_data does not seem to need to be transposed at all
32//
33//  -- this seems too easy. what am I doing wrong? Is something getting garbled when I
34// write back any single values back to the file
35//
36// -- try a string value next
37// -- then start to write the generic get/write functions
38//
39
40//
41// do I ditch the RealsRead/IntegersRead/TextRead? It makes little sense now.
42// maybe copy a "dataInfo" folder/subfolders. can't keep them all (bloat)
43// but then what about multiple files added together?
44//
45
46
47
48Macro Setup_VSANS_Struct()
49
50        // lays out the tree and fills with dummy values
51        H_Setup_VSANS_Structure()
52       
53        // writes in the attributes
54        H_Fill_VSANS_Attributes()
55       
56        // fill in with VCALC simulation bits
57        H_Fill_VSANS_wSim()
58       
59End
60
61Macro Save_VSANS_Nexus(fileName)
62        String fileName="Test_VSANS_file"
63
64        // save as HDF5 (no attributes saved yet)
65        Save_VSANS_file("root:VSANS_file", fileName+".h5")
66       
67        // read in a data file using the gateway-- reads from the home path
68        H_HDF5Gate_Read_Raw(fileName+".h5")
69       
70        // after reading in a "partial" file using the gateway (to generate the xref)
71        // Save the xref to disk (for later use)
72        Save_HDF5___xref("root:"+fileName,"HDF5___xref")
73       
74        // after you've generated the HDF5___xref, load it in and copy it
75        // to the necessary folder location.
76        Copy_HDF5___xref("root:VSANS_file", "HDF5___xref")
77       
78        // writes out the contents of a data folder using the gateway
79        H_HDF5Gate_Write_Raw("root:VSANS_file", fileName+".h5")
80
81        // re-load the data file using the gateway-- reads from the home path
82        // now with attributes
83        H_HDF5Gate_Read_Raw(fileName+".h5")
84       
85End
86
87
88
89Macro Setup_SANS_Struct()
90
91        // lays out the tree and fills with dummy values
92        H_Setup_SANS_Structure()
93       
94        // writes in the attributes
95        H_Fill_SANS_Attributes()
96       
97        // fill in with VCALC simulation bits
98        H_Fill_SANS_wSim()
99
100End
101
102Macro Save_SANS_Nexus(fileName)
103        String fileName="Test_SANS_file"
104       
105        // save as HDF5 (no attributes saved yet) (save_VSANS is actually generic HDF...)
106        Save_VSANS_file("root:SANS_file", fileName+".h5")
107       
108        // read in a data file using the gateway-- reads from the home path
109        H_HDF5Gate_Read_Raw(fileName+".h5")
110       
111        // after reading in a "partial" file using the gateway (to generate the xref)
112        // Save the xref to disk (for later use)
113        Save_HDF5___xref("root:"+fileName,"HDF5___xref")
114       
115        // after you've generated the HDF5___xref, load it in and copy it
116        // to the necessary folder location.
117        Copy_HDF5___xref("root:SANS_file", "HDF5___xref")
118       
119        // writes out the contents of a data folder using the gateway
120        H_HDF5Gate_Write_Raw("root:SANS_file", fileName+".h5")
121
122        // re-load the data file using the gateway-- reads from the home path
123        // now with attributes
124        H_HDF5Gate_Read_Raw(fileName+".h5")
125
126
127End
128
129
130// TODO
131// currently, there are no dummy fill values or attributes for the fake DIV file
132//
133Macro Setup_VSANS_DIV_Struct()
134
135        // lays out the tree and fills with dummy values
136        H_Setup_VSANS_DIV_Structure()
137       
138        // writes in the attributes
139//      H_Fill_VSANS_Attributes()
140       
141        // fill in with VCALC simulation bits
142//      H_Fill_VSANS_wSim()
143       
144End
145
146Macro Save_VSANS_DIV_Nexus(fileName)
147        String fileName="Test_VSANS_DIV_file"
148
149        // save as HDF5 (no attributes saved yet)
150        Save_VSANS_file("root:VSANS_DIV_file", fileName+".h5")
151       
152        // read in a data file using the gateway-- reads from the home path
153        H_HDF5Gate_Read_Raw(fileName+".h5")
154       
155        // after reading in a "partial" file using the gateway (to generate the xref)
156        // Save the xref to disk (for later use)
157        Save_HDF5___xref("root:"+fileName,"HDF5___xref")
158       
159        // after you've generated the HDF5___xref, load it in and copy it
160        // to the necessary folder location.
161        Copy_HDF5___xref("root:VSANS_DIV_file", "HDF5___xref")
162       
163        // writes out the contents of a data folder using the gateway
164        H_HDF5Gate_Write_Raw("root:VSANS_DIV_file", fileName+".h5")
165
166        // re-load the data file using the gateway-- reads from the home path
167        // now with attributes
168        H_HDF5Gate_Read_Raw(fileName+".h5")
169       
170End
171
172
173
174
175
176
177
178
179
180
181
182
183
184//
185// saves a specified folder, with a given filename.
186// saves to the home path
187//
188Proc Save_VSANS_file(dfPath, filename)
189        String dfPath   ="root:VSANS_file"              // e.g., "root:FolderA" or ":"
190        String filename = "Test_VSANS_file.h5"
191       
192        H_NXSANS_SaveGroupAsHDF5(dfPath, filename)
193End
194
195
196//     
197// this is my procedure to save the folders to HDF5, once I've filled the folder tree
198//
199// this does NOT save attributes, but gets the fodler structure correct
200//
201Function H_NXSANS_SaveGroupAsHDF5(dfPath, filename)
202        String dfPath   // e.g., "root:FolderA" or ":"
203        String filename
204
205        Variable result = 0     // 0 means no error
206       
207        Variable fileID
208        HDF5CreateFile/P=home /O /Z fileID as filename
209        if (V_flag != 0)
210                Print "HDF5CreateFile failed"
211                return -1
212        endif
213
214        HDF5SaveGroup /IGOR=0 /O /R /Z $dfPath, fileID, "."
215//      HDF5SaveGroup /O /R /Z $dfPath, fileID, "."
216        if (V_flag != 0)
217                Print "HDF5SaveGroup failed"
218                result = -1
219        endif
220       
221        HDF5CloseFile fileID
222
223        return result
224End
225
226
227//
228// writes out the contents of a data folder using the gateway
229// -- the HDF5___xref wave must be present at the toep level for it to
230//    write out anything.
231//
232Proc H_HDF5Gate_Write_Raw(dfPath, filename)
233        String dfPath   ="root:VSANS_file"              // e.g., "root:FolderA" or ":"
234        String filename = "Test_VSANS_file.h5"
235       
236        // Check our work so far.
237        // If something prints, there was an error above.
238        print H5GW_ValidateFolder(dfPath)
239
240        print H5GW_WriteHDF5(dfPath, filename)
241       
242        SetDataFolder root:
243End
244
245//
246// read in a data file using the gateway
247//
248// reads from the home path
249//
250Proc H_HDF5Gate_Read_Raw(file)
251        String file
252//      NewDataFolder/O/S root:newdata
253        Print H5GW_ReadHDF5("", file)   // reads into current folder
254        SetDataFolder root:
255End
256
257
258//
259// after reading in a "partial" file using the gateway (to generate the xref)
260// Save the xref to disk (for later use)
261//
262Proc Save_HDF5___xref(dfPath, filename)
263        String dfPath   ="root:VSANS_file"              // e.g., "root:FolderA" or ":"
264        String filename = "HDF5___xref"
265
266        Save/T/P=home $(dfPath+":HDF5___xref") as "HDF5___xref.itx"
267
268//      Copy_HDF5___xref(dfPath, filename)
269       
270        SetDataFolder root:
271End
272
273//
274// after you've generated the HDF5___xref, load it in and copy it to
275// the necessary folder location.
276// - then all is set to *really* write out the file correctly, including the attributes
277//
278Proc Copy_HDF5___xref(dfPath, filename)
279        String dfPath   ="root:VSANS_file"              // e.g., "root:FolderA" or ":"
280        String filename = "HDF5___xref"
281
282        if(exists(filename) != 1)
283                //load it in   
284                LoadWave/T/P=home/O "HDF5___xref.itx"
285        endif
286       
287        Duplicate/O HDF5___xref, $(dfPath+":HDF5___xref")
288       
289        SetDataFolder root:
290End
291
292
293
294//////// testing procedures, may be of use, maybe not //////////////
295
296
297//////// Two procedures that test out Pete Jemain's HDF5Gateway
298//
299// This works fine, but it may not be terribly compatible with the way NICE will eventually
300// write out the data files. I'll have very little control over that and I'll need to cobble together
301// a bunch of fixes to cover up their mistakes.
302//
303// Using Nick Hauser's code as a starting point may be a lot more painful, but more flexible in the end.
304//
305// I'm completely baffled about what to do with attributes. Are they needed, is this the best way to deal
306// with them, do I care about reading them in, and if I do, why?
307//
308Proc H_HDF5Gate_WriteTest()
309
310        // create the folder structure
311        NewDataFolder/O/S root:mydata
312        NewDataFolder/O sasentry
313        NewDataFolder/O :sasentry:sasdata
314
315        // create the waves
316        Make/O :sasentry:sasdata:I0
317        Make/O :sasentry:sasdata:Q0
318
319        Make/O/N=0 Igor___folder_attributes
320        Make/O/N=0 :sasentry:Igor___folder_attributes
321        Make/O/N=0 :sasentry:sasdata:Igor___folder_attributes
322
323        // create the attributes
324        Note/K Igor___folder_attributes, "producer=IgorPro\rNX_class=NXroot"
325        Note/K :sasentry:Igor___folder_attributes, "NX_class=NXentry"
326        Note/K :sasentry:sasdata:Igor___folder_attributes, "NX_class=NXdata"
327        Note/K :sasentry:sasdata:I0, "units=1/cm\rsignal=1\rtitle=reduced intensity"
328        Note/K :sasentry:sasdata:Q0, "units=1/A\rtitle=|scattering vector|"
329
330        // create the cross-reference mapping
331        Make/O/T/N=(5,2) HDF5___xref
332        Edit/K=0 'HDF5___xref';DelayUpdate
333        HDF5___xref[0][1] = ":"
334        HDF5___xref[1][1] = ":sasentry"
335        HDF5___xref[2][1] = ":sasentry:sasdata"
336        HDF5___xref[3][1] = ":sasentry:sasdata:I0"
337        HDF5___xref[4][1] = ":sasentry:sasdata:Q0"
338        HDF5___xref[0][0] = "/"
339        HDF5___xref[1][0] = "/sasentry"
340        HDF5___xref[2][0] = "/sasentry/sasdata"
341        HDF5___xref[3][0] = "/sasentry/sasdata/I"
342        HDF5___xref[4][0] = "/sasentry/sasdata/Q"
343
344        // Check our work so far.
345        // If something prints, there was an error above.
346        print H5GW_ValidateFolder("root:mydata")
347
348        // set I0 and Q0 to your data
349
350        print H5GW_WriteHDF5("root:mydata", "mydata.h5")
351       
352        SetDataFolder root:
353End
354
355
356//
357// given a filename of a SANS data filename of the form
358// name.anything
359// returns the name as a string without the ".fbdfasga" extension
360//
361// returns the input string if a "." can't be found (maybe it wasn't there)
362//
363Function/S H_RemoveDotExtension(item)
364        String item
365        String invalid = item   //
366        Variable num=-1
367       
368        //find the "dot"
369        String runStr=""
370        Variable pos = strsearch(item,".",0)
371        if(pos == -1)
372                //"dot" not found
373                return (invalid)
374        else
375                //found, get all of the characters preceeding it
376                runStr = item[0,pos-1]
377                return (runStr)
378        Endif
379End
380
381
382//
383// Writing attributes to a group and to a dataset.
384// example from the WM documentation for HDF5SaveData
385//
386Function DemoAttributes(w)
387        Wave w
388
389        Variable result = 0     // 0 means no error
390       
391        // Create file
392        Variable fileID
393        HDF5CreateFile/P=home /O /Z fileID as "Test.h5"
394        if (V_flag != 0)
395                Print "HDF5CreateFile failed"
396                return -1
397        endif
398
399        // Write an attribute to the root group
400        Make /FREE /T /N=1 groupAttribute = "This is a group attribute"
401        HDF5SaveData /A="GroupAttribute" groupAttribute, fileID, "/"
402       
403        // Save wave as dataset
404        HDF5SaveData /O /Z w, fileID    // Uses wave name as dataset name
405        if (V_flag != 0)
406                Print "HDF5SaveData failed"
407                result = -1
408        endif
409
410        // Write an attribute to the dataset
411        Make /FREE /T /N=1 datasetAttribute = "This is a dataset attribute"
412        String datasetName = NameOfWave(w)
413        HDF5SaveData /A="DatasetAttribute" datasetAttribute, fileID, datasetName
414
415        HDF5CloseFile fileID
416       
417        return result
418End     // The attribute waves are automatically killed since they are free waves
419
420
421
422//     
423//Function H_Test_HDFWriteTrans(fname,val)
424//      String fname
425//      Variable val
426//     
427//     
428//      String str
429//      PathInfo home
430//      str = S_path
431//     
432//      H_WriteTransmissionToHeader(str+fname,val)
433//     
434//      return(0)
435//End
436//
437//Function H_WriteTransmissionToHeader(fname,trans)
438//      String fname
439//      Variable trans
440//     
441//      Make/O/D/N=1 wTmpWrite
442//      String groupName = "/Sample"    //      /Run1/Sample becomes groupName /Run1/Run1/Sample
443//      String varName = "TRNS"
444//      wTmpWrite[0] = trans //
445//
446//      variable err
447//      err = HDFWrite_Wave(fname, groupName, varName, wTmpWrite)
448//      KillWaves wTmpWrite
449//     
450//      //err not handled here
451//             
452//      return(0)
453//End
454
455
456
457Function H_Test_ListAttributes(fname,groupName)
458        String fname,groupName
459        Variable trans
460       
461//      Make/O/D/N=1 wTmpWrite
462//      String groupName = "/Sample"    //      /Run1/Sample becomes groupName /Run1/Run1/Sample
463//      String varName = "TRNS"
464//      wTmpWrite[0] = trans //
465        String str
466        PathInfo home
467        str = S_path
468       
469        variable err
470        err = H_HDF_ListAttributes(str+fname, groupName)
471       
472        //err not handled here
473               
474        return(0)
475End
476
477Function H_HDF_ListAttributes(fname, groupName)
478        String fname, groupName
479       
480        variable err=0, fileID,groupID
481        String cDF = getDataFolder(1), temp
482        String NXentry_name, attrValue=""
483       
484        STRUCT HDF5DataInfo di  // Defined in HDF5 Browser.ipf.
485        InitHDF5DataInfo(di)    // Initialize structure.
486       
487        try     
488                HDF5OpenFile /Z fileID  as fname  //open file read-write
489                if(!fileID)
490                        err = 1
491                        abort "HDF5 file does not exist"
492                endif
493               
494                HDF5OpenGroup /Z fileID , groupName, groupID
495
496        //      (QUOKKA) !! At the moment, there is no entry for sample thickness in our data file
497        //      therefore create new HDF5 group to enable write / patch command
498        //      comment out the following group creation once thickness appears in revised file
499       
500                if(!groupID)
501                        HDF5CreateGroup /Z fileID, groupName, groupID
502                        //err = 1
503                        //abort "HDF5 group does not exist"
504                else
505
506//                      HDF5AttributeInfo(fileID, "/", 1, "file_name", 0, di)
507                        HDF5AttributeInfo(fileID, "/", 1, "NeXus_version", 0, di)
508                        Print di
509
510//                      see the HDF5 Browser  for how to get the actual <value> of the attribute. See GetPreviewString in
511//        or in FillGroupAttributesList or in FillDatasetAttributesList (from FillLists)
512//                      it seems to be ridiculously complex to get such a simple bit of information - the HDF5BrowserData STRUCT
513//                      needs to be filled first. Ugh.
514                        attrValue = GetPreviewString(fileID, 1, di, "/entry", "cucumber")
515                        Print "attrValue = ",attrValue
516                       
517                       
518                        //get attributes and save them
519                        HDF5ListAttributes/TYPE=1 /Z fileID, groupName          //TYPE=1 means that we're referencing a group, not a dataset
520                        Print "S_HDF5ListAttributes = ", S_HDF5ListAttributes
521                       
522                        // passing the groupID works too, then the group name is not needed                     
523                        HDF5ListAttributes/TYPE=1 /Z groupID, "."               //TYPE=1 means that we're referencing a group, not a dataset
524                        Print "S_HDF5ListAttributes = ", S_HDF5ListAttributes
525                endif
526        catch
527
528                // catch any aborts here
529               
530        endtry
531       
532        if(groupID)
533                HDF5CloseGroup /Z groupID
534        endif
535       
536        if(fileID)
537                HDF5CloseFile /Z fileID
538        endif
539
540        setDataFolder $cDF
541        return err
542end
543
544
545/////////////// end of the testing procedures ////////////////
Note: See TracBrowser for help on using the repository browser.