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

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

more changes, filling in functionality of the initial data correction

File size: 19.6 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2
3//
4// This file has utility procedures to be able to read/write
5// test HDF5 (from Igor) for SANS and VSANS in Nexus format
6//
7// It is predominantly to be able to WRITE a full Nexus file from Igor
8// -- this is only necessary to be able to write out "fake" VSANS files from VCALC
9//    since I need a "template" of the Nexus folder structure to start from and fill in
10//
11// It doesn't reproduce the NICE logs, but will leave a spece for them if
12// it is read in and is part of the xref.
13//
14// It may be easier to hard-wire my own folder definition (NewDataFolder)
15// that is MY Nexus file to write out and use that as the base case
16// rather than rely on Pete's code, which is terribly slow for writing.
17// Attributes are the issue, but it may be unimportant if they are missing.
18//
19
20
21
22//
23// There's an odd sequence of steps that need to be done to use HDFGateway
24// to most easily write out attributes, and be able to read then back in.
25// Rather awkward, but it works without me needing to go nuts with an atomistic
26// understanding of HDF5. This is necessary for me to be able to write out
27// Nexus files, which is important both for testing, and for simulation.
28//
29// This is done as a set of macros that need to be applied in a specific sequence
30// in order to be able to generate HDF5___xref
31// Ideally, the HDF5___xref wave can be saved/imported to make proper saving possible
32// once the "tree" is finalized.
33//
34//
35// The basic saving routines are here, just as Proc rather than Macro menu clutter
36//
37
38
39// Next... think of all of R/W access needed
40//
41// the simple read/write works...
42// linear_data does not seem to need to be transposed at all
43//
44//  -- this seems too easy. what am I doing wrong? Is something getting garbled when I
45// write back any single values back to the file
46//
47// -- try a string value next
48// -- then start to write the generic get/write functions
49//
50
51//
52// do I ditch the RealsRead/IntegersRead/TextRead? It makes little sense now.
53// maybe copy a "dataInfo" folder/subfolders. can't keep them all (bloat)
54// but then what about multiple files added together?
55//
56
57Menu "VSANS"
58        SubMenu "Nexus File Testing"
59                "Fill_Nexus_V_Template"
60                "Save_Nexus_V_Template"
61                "Load_Nexus_V_Template"
62                "-"
63                "IgorOnly_Setup_VSANS_Struct"
64                "IgorOnly_Save_VSANS_Nexus"
65                "IgorOnly_Setup_SANS_Struct"
66                "IgorOnly_Save_SANS_Struct"
67                "Setup_VSANS_DIV_Struct"
68                "Save_VSANS_DIV_Nexus"
69        End
70End
71
72
73Proc Load_Nexus_V_Template()
74        H_HDF5Gate_Read_Raw("")
75        String tmpStr=root:file_name  //SRK - so I can get the file name that was loaded
76       
77// this is the folder name
78        String base_name = StringFromList(0,File_Name,".")
79        RenameDataFolder $("root:"+base_name), V_Nexus_Template
80End
81
82
83Proc Fill_Nexus_V_Template()
84        H_Fill_VSANS_Template_wSim()
85End
86
87
88Proc Save_Nexus_V_Template()
89        H_HDF5Gate_Write_Raw("root:V_Nexus_Template:","")
90End
91
92
93
94
95
96
97
98
99
100
101
102
103
104/////////////////////////////
105
106/////////////below is largely depricated, ugly dance to be able to "fake" a file from Igor
107// which was not complete anyways.
108
109
110
111Proc IgorOnly_Setup_VSANS_Struct()
112
113        // lays out the tree and fills with dummy values
114        H_Setup_VSANS_Structure()
115       
116        // writes in the attributes
117        H_Fill_VSANS_Attributes()
118       
119        // fill in with VCALC simulation bits
120        H_Fill_VSANS_wSim()
121       
122End
123
124Proc IgorOnly_Save_VSANS_Nexus(fileName)
125        String fileName="Test_VSANS_file"
126
127        // save as HDF5 (no attributes saved yet)
128        Save_VSANS_file("root:VSANS_file", fileName+".h5")
129       
130        // read in a data file using the gateway-- reads from the home path
131        H_HDF5Gate_Read_Raw(fileName+".h5")
132       
133        // after reading in a "partial" file using the gateway (to generate the xref)
134        // Save the xref to disk (for later use)
135        Save_HDF5___xref("root:"+fileName,"HDF5___xref")
136       
137        // after you've generated the HDF5___xref, load it in and copy it
138        // to the necessary folder location.
139        Copy_HDF5___xref("root:VSANS_file", "HDF5___xref")
140       
141        // writes out the contents of a data folder using the gateway
142        H_HDF5Gate_Write_Raw("root:VSANS_file", fileName+".h5")
143
144        // re-load the data file using the gateway-- reads from the home path
145        // now with attributes
146        H_HDF5Gate_Read_Raw(fileName+".h5")
147       
148End
149
150
151
152Proc IgorOnly_Setup_SANS_Struct()
153
154        // lays out the tree and fills with dummy values
155        H_Setup_SANS_Structure()
156       
157        // writes in the attributes
158        H_Fill_SANS_Attributes()
159       
160        // fill in with VCALC simulation bits
161        H_Fill_SANS_wSim()
162
163End
164
165Proc IgorOnly_Save_SANS_Nexus(fileName)
166        String fileName="Test_SANS_file"
167       
168        // save as HDF5 (no attributes saved yet) (save_VSANS is actually generic HDF...)
169        Save_VSANS_file("root:SANS_file", fileName+".h5")
170       
171        // read in a data file using the gateway-- reads from the home path
172        H_HDF5Gate_Read_Raw(fileName+".h5")
173       
174        // after reading in a "partial" file using the gateway (to generate the xref)
175        // Save the xref to disk (for later use)
176        Save_HDF5___xref("root:"+fileName,"HDF5___xref")
177       
178        // after you've generated the HDF5___xref, load it in and copy it
179        // to the necessary folder location.
180        Copy_HDF5___xref("root:SANS_file", "HDF5___xref")
181       
182        // writes out the contents of a data folder using the gateway
183        H_HDF5Gate_Write_Raw("root:SANS_file", fileName+".h5")
184
185        // re-load the data file using the gateway-- reads from the home path
186        // now with attributes
187        H_HDF5Gate_Read_Raw(fileName+".h5")
188
189
190End
191
192
193
194// TODO
195// currently, there are no dummy fill values or attributes for the fake DIV file
196//
197Proc Setup_VSANS_DIV_Struct()
198
199        // lays out the tree and fills with dummy values
200        H_Setup_VSANS_DIV_Structure()
201       
202        // writes in the attributes
203//      H_Fill_VSANS_Attributes()
204       
205        // fill in with VCALC simulation bits
206//      H_Fill_VSANS_wSim()
207       
208End
209
210Proc Save_VSANS_DIV_Nexus(fileName)
211        String fileName="Test_VSANS_DIV_file"
212
213        // save as HDF5 (no attributes saved yet)
214        Save_VSANS_file("root:VSANS_DIV_file", fileName+".h5")
215       
216        // read in a data file using the gateway-- reads from the home path
217        H_HDF5Gate_Read_Raw(fileName+".h5")
218       
219        // after reading in a "partial" file using the gateway (to generate the xref)
220        // Save the xref to disk (for later use)
221        Save_HDF5___xref("root:"+fileName,"HDF5___xref")
222       
223        // after you've generated the HDF5___xref, load it in and copy it
224        // to the necessary folder location.
225        Copy_HDF5___xref("root:VSANS_DIV_file", "HDF5___xref")
226       
227        // writes out the contents of a data folder using the gateway
228        H_HDF5Gate_Write_Raw("root:VSANS_DIV_file", fileName+".h5")
229
230        // re-load the data file using the gateway-- reads from the home path
231        // now with attributes
232        H_HDF5Gate_Read_Raw(fileName+".h5")
233       
234End
235
236////////////// fake DIV file tests
237//
238//
239//      Make/O/T/N=1    file_name       = "VSANS_DIV_test.h5"
240//
241// simple generation of a fake div file. for sans, nothing other than the creation date was written to the
242// file header. nothing more is needed (possibly)
243//
244// TODO -- I want to re-visit the propagation of errors in the DIV file. No errors are ever calculated/saved
245//   during the generation of the file, but there's no reason it couldn't. the idea is that the plex
246//   is counted so long that the errors are insignificant compared to the data errors, but that may not
247//   always be the case. A bit of math may prove this. or not. Plus, the situation for VSANS may be different.
248//
249//
250// TODO -- make the number of pixels GLOBAL
251// TODO -- there will be lots of work to do to develop the procedures necessary to actually generate the
252//      9 data sets to become the DIV file contents. More complexity here than for the simple SANS case.
253//
254Proc H_Setup_VSANS_DIV_Structure()
255       
256        NewDataFolder/O/S root:VSANS_DIV_file           
257
258        NewDataFolder/O/S root:VSANS_DIV_file:entry     
259                Make/O/T/N=1    title   = "This is a fake DIV file for VSANS"
260                Make/O/T/N=1    start_date      = "2015-02-28T08:15:30-5:00"
261                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument         
262                        Make/O/T/N=1    name    = "NG3_VSANS"
263                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_B       
264                        Make/O/D/N=(320,320)    data    = abs(gnoise(10))
265                        Make/O/D/N=(320,320)    linear_data_error       = 0.01*abs(gnoise(10))
266                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_MR             
267                        Make/O/D/N=(48,128)     data    = abs(gnoise(10))
268                        Make/O/D/N=(48,128)     linear_data_error       = 0.01*abs(gnoise(10))
269                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_ML             
270                        Make/O/D/N=(48,128)     data    = abs(gnoise(10))
271                        Make/O/D/N=(48,128)     linear_data_error       = 0.01*abs(gnoise(10))
272                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_MT             
273                        Make/O/D/N=(128,48)     data    = abs(gnoise(10))
274                        Make/O/D/N=(128,48)     linear_data_error       = 0.01*abs(gnoise(10))
275                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_MB             
276                        Make/O/D/N=(128,48)     data    = abs(gnoise(10))
277                        Make/O/D/N=(128,48)     linear_data_error       = 0.01*abs(gnoise(10))
278                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_FR             
279                        Make/O/D/N=(48,128)     data    = abs(gnoise(10))
280                        Make/O/D/N=(48,128)     linear_data_error       = 0.01*abs(gnoise(10))
281                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_FL             
282                        Make/O/D/N=(48,128)     data    = abs(gnoise(10))
283                        Make/O/D/N=(48,128)     linear_data_error       = 0.01*abs(gnoise(10))
284                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_FT             
285                        Make/O/D/N=(128,48)     data    = abs(gnoise(10))
286                        Make/O/D/N=(128,48)     linear_data_error       = 0.01*abs(gnoise(10))
287                NewDataFolder/O/S root:VSANS_DIV_file:entry:instrument:detector_FB             
288                        Make/O/D/N=(128,48)     data    = abs(gnoise(10))
289                        Make/O/D/N=(128,48)     linear_data_error       = 0.01*abs(gnoise(10))
290                       
291        SetDataFolder root:
292
293End
294
295
296
297
298
299
300
301
302
303
304
305
306
307//
308// saves a specified folder, with a given filename.
309// saves to the home path
310//
311Proc Save_VSANS_file(dfPath, filename)
312        String dfPath   ="root:VSANS_file"              // e.g., "root:FolderA" or ":"
313        String filename = "Test_VSANS_file.h5"
314       
315        H_NXSANS_SaveGroupAsHDF5(dfPath, filename)
316End
317
318
319//     
320// this is my procedure to save the folders to HDF5, once I've filled the folder tree
321//
322// this does NOT save attributes, but gets the folder structure correct
323//
324Function H_NXSANS_SaveGroupAsHDF5(dfPath, filename)
325        String dfPath   // e.g., "root:FolderA" or ":"
326        String filename
327
328        Variable result = 0     // 0 means no error
329       
330        Variable fileID
331        HDF5CreateFile/P=home /O /Z fileID as filename
332        if (V_flag != 0)
333                Print "HDF5CreateFile failed"
334                return -1
335        endif
336
337        HDF5SaveGroup /IGOR=0 /O /R /Z $dfPath, fileID, "."
338//      HDF5SaveGroup /O /R /Z $dfPath, fileID, "."
339        if (V_flag != 0)
340                Print "HDF5SaveGroup failed"
341                result = -1
342        endif
343       
344        HDF5CloseFile fileID
345
346        return result
347End
348
349// passing null file string presents a dialog
350// these two procedures will use the full Xrefs, so they can write out full
351// files. They are, however, slow
352Proc Read_Nexus_Xref()
353        H_HDF5Gate_Read_Raw("")
354End
355
356Proc Write_Nexus_Xref()
357        H_HDF5Gate_Write_Raw()
358End
359
360//
361// writes out the contents of a data folder using the gateway
362// -- the HDF5___xref wave must be present at the top level for it to
363//    write out anything.
364//
365Proc H_HDF5Gate_Write_Raw(dfPath,filename)
366        String dfPath   = "root:"       // e.g., "root:FolderA" or ":"
367        String filename = "Test_VSANS_file.h5"
368//      Prompt dfPath, "Data Folder",popup,H_GetAList(4)       
369//      Prompt fileName, "File name"
370       
371//      DoPrompt "Folder and file to write", dfPath,fileName
372        // Check our work so far.
373        // If something prints, there was an error above.
374        print H5GW_ValidateFolder(dfPath)
375
376        print H5GW_WriteHDF5(dfPath, filename)
377       
378        SetDataFolder root:
379End
380
381//
382// read in a data file using the gateway
383//
384// reads from the home path
385//
386Proc H_HDF5Gate_Read_Raw(file)
387        String file
388       
389//      NewDataFolder/O/S root:newdata
390        Print H5GW_ReadHDF5("", file)   // reads into current folder
391        SetDataFolder root:
392End
393
394
395
396// this is in PlotUtils, but duplicated here
397// utility used in the "PlotSmeared...() macros to get a list of data folders
398//
399//1:    Waves.
400//2:    Numeric variables.
401//3:    String variables.
402//4:    Data folders.
403Function/S H_GetAList(type)
404        Variable type
405       
406        SetDataFolder root:
407       
408        String objName,str=""
409        Variable index = 0
410        do
411                objName = GetIndexedObjName(":", type, index)
412                if (strlen(objName) == 0)
413                        break
414                endif
415                //Print objName
416                str += objName + ";"
417                index += 1
418        while(1)
419       
420        // remove myGlobals, Packages, etc. from the folder list
421        if(type==4)
422                str = RemoveFromList("myGlobals", str , ";" )
423                str = RemoveFromList("Packages", str, ";")
424        endif
425       
426        return(str)
427End
428
429//
430// after reading in a "partial" file using the gateway (to generate the xref)
431// Save the xref to disk (for later use)
432//
433Proc Save_HDF5___xref(dfPath, filename)
434        String dfPath   ="root:VSANS_file"              // e.g., "root:FolderA" or ":"
435        String filename = "HDF5___xref"
436
437        Save/T/P=home $(dfPath+":HDF5___xref") as "HDF5___xref.itx"
438
439//      Copy_HDF5___xref(dfPath, filename)
440       
441        SetDataFolder root:
442End
443
444//
445// after you've generated the HDF5___xref, load it in and copy it to
446// the necessary folder location.
447// - then all is set to *really* write out the file correctly, including the attributes
448//
449Proc Copy_HDF5___xref(dfPath, filename)
450        String dfPath   ="root:VSANS_file"              // e.g., "root:FolderA" or ":"
451        String filename = "HDF5___xref"
452
453        if(exists(filename) != 1)
454                //load it in   
455                LoadWave/T/P=home/O "HDF5___xref.itx"
456        endif
457       
458        Duplicate/O HDF5___xref, $(dfPath+":HDF5___xref")
459       
460        SetDataFolder root:
461End
462
463
464
465//////// testing procedures, may be of use, maybe not //////////////
466
467
468//////// Two procedures that test out Pete Jemain's HDF5Gateway
469//
470// This works fine, but it may not be terribly compatible with the way NICE will eventually
471// write out the data files. I'll have very little control over that and I'll need to cobble together
472// a bunch of fixes to cover up their mistakes.
473//
474// Using Nick Hauser's code as a starting point may be a lot more painful, but more flexible in the end.
475//
476// I'm completely baffled about what to do with attributes. Are they needed, is this the best way to deal
477// with them, do I care about reading them in, and if I do, why?
478//
479Proc H_HDF5Gate_WriteTest()
480
481        // create the folder structure
482        NewDataFolder/O/S root:mydata
483        NewDataFolder/O sasentry
484        NewDataFolder/O :sasentry:sasdata
485
486        // create the waves
487        Make/O :sasentry:sasdata:I0
488        Make/O :sasentry:sasdata:Q0
489
490        Make/O/N=0 Igor___folder_attributes
491        Make/O/N=0 :sasentry:Igor___folder_attributes
492        Make/O/N=0 :sasentry:sasdata:Igor___folder_attributes
493
494        // create the attributes
495        Note/K Igor___folder_attributes, "producer=IgorPro\rNX_class=NXroot"
496        Note/K :sasentry:Igor___folder_attributes, "NX_class=NXentry"
497        Note/K :sasentry:sasdata:Igor___folder_attributes, "NX_class=NXdata"
498        Note/K :sasentry:sasdata:I0, "units=1/cm\rsignal=1\rtitle=reduced intensity"
499        Note/K :sasentry:sasdata:Q0, "units=1/A\rtitle=|scattering vector|"
500
501        // create the cross-reference mapping
502        Make/O/T/N=(5,2) HDF5___xref
503        Edit/K=0 'HDF5___xref';DelayUpdate
504        HDF5___xref[0][1] = ":"
505        HDF5___xref[1][1] = ":sasentry"
506        HDF5___xref[2][1] = ":sasentry:sasdata"
507        HDF5___xref[3][1] = ":sasentry:sasdata:I0"
508        HDF5___xref[4][1] = ":sasentry:sasdata:Q0"
509        HDF5___xref[0][0] = "/"
510        HDF5___xref[1][0] = "/sasentry"
511        HDF5___xref[2][0] = "/sasentry/sasdata"
512        HDF5___xref[3][0] = "/sasentry/sasdata/I"
513        HDF5___xref[4][0] = "/sasentry/sasdata/Q"
514
515        // Check our work so far.
516        // If something prints, there was an error above.
517        print H5GW_ValidateFolder("root:mydata")
518
519        // set I0 and Q0 to your data
520
521        print H5GW_WriteHDF5("root:mydata", "mydata.h5")
522       
523        SetDataFolder root:
524End
525
526
527//
528// given a filename of a SANS data filename of the form
529// name.anything
530// returns the name as a string without the ".fbdfasga" extension
531//
532// returns the input string if a "." can't be found (maybe it wasn't there)
533//
534Function/S H_RemoveDotExtension(item)
535        String item
536        String invalid = item   //
537        Variable num=-1
538       
539        //find the "dot"
540        String runStr=""
541        Variable pos = strsearch(item,".",0)
542        if(pos == -1)
543                //"dot" not found
544                return (invalid)
545        else
546                //found, get all of the characters preceeding it
547                runStr = item[0,pos-1]
548                return (runStr)
549        Endif
550End
551
552
553//
554// Writing attributes to a group and to a dataset.
555// example from the WM documentation for HDF5SaveData
556//
557Function DemoAttributes(w)
558        Wave w
559
560        Variable result = 0     // 0 means no error
561       
562        // Create file
563        Variable fileID
564        HDF5CreateFile/P=home /O /Z fileID as "Test.h5"
565        if (V_flag != 0)
566                Print "HDF5CreateFile failed"
567                return -1
568        endif
569
570        // Write an attribute to the root group
571        Make /FREE /T /N=1 groupAttribute = "This is a group attribute"
572        HDF5SaveData /A="GroupAttribute" groupAttribute, fileID, "/"
573       
574        // Save wave as dataset
575        HDF5SaveData /O /Z w, fileID    // Uses wave name as dataset name
576        if (V_flag != 0)
577                Print "HDF5SaveData failed"
578                result = -1
579        endif
580
581        // Write an attribute to the dataset
582        Make /FREE /T /N=1 datasetAttribute = "This is a dataset attribute"
583        String datasetName = NameOfWave(w)
584        HDF5SaveData /A="DatasetAttribute" datasetAttribute, fileID, datasetName
585
586        HDF5CloseFile fileID
587       
588        return result
589End     // The attribute waves are automatically killed since they are free waves
590
591
592
593//     
594//Function H_Test_HDFWriteTrans(fname,val)
595//      String fname
596//      Variable val
597//     
598//     
599//      String str
600//      PathInfo home
601//      str = S_path
602//     
603//      H_WriteTransmissionToHeader(str+fname,val)
604//     
605//      return(0)
606//End
607//
608//Function H_WriteTransmissionToHeader(fname,trans)
609//      String fname
610//      Variable trans
611//     
612//      Make/O/D/N=1 wTmpWrite
613//      String groupName = "/Sample"    //      /Run1/Sample becomes groupName /Run1/Run1/Sample
614//      String varName = "TRNS"
615//      wTmpWrite[0] = trans //
616//
617//      variable err
618//      err = HDFWrite_Wave(fname, groupName, varName, wTmpWrite)
619//      KillWaves wTmpWrite
620//     
621//      //err not handled here
622//             
623//      return(0)
624//End
625
626
627
628Function H_Test_ListAttributes(fname,groupName)
629        String fname,groupName
630        Variable trans
631       
632//      Make/O/D/N=1 wTmpWrite
633//      String groupName = "/Sample"    //      /Run1/Sample becomes groupName /Run1/Run1/Sample
634//      String varName = "TRNS"
635//      wTmpWrite[0] = trans //
636        String str
637        PathInfo home
638        str = S_path
639       
640        variable err
641        err = H_HDF_ListAttributes(str+fname, groupName)
642       
643        //err not handled here
644               
645        return(0)
646End
647
648Function H_HDF_ListAttributes(fname, groupName)
649        String fname, groupName
650       
651        variable err=0, fileID,groupID
652        String cDF = getDataFolder(1), temp
653        String NXentry_name, attrValue=""
654       
655        STRUCT HDF5DataInfo di  // Defined in HDF5 Browser.ipf.
656        InitHDF5DataInfo(di)    // Initialize structure.
657       
658        try     
659                HDF5OpenFile /Z fileID  as fname  //open file read-write
660                if(!fileID)
661                        err = 1
662                        abort "HDF5 file does not exist"
663                endif
664               
665                HDF5OpenGroup /Z fileID , groupName, groupID
666
667        //      (QUOKKA) !! At the moment, there is no entry for sample thickness in our data file
668        //      therefore create new HDF5 group to enable write / patch command
669        //      comment out the following group creation once thickness appears in revised file
670       
671                if(!groupID)
672                        HDF5CreateGroup /Z fileID, groupName, groupID
673                        //err = 1
674                        //abort "HDF5 group does not exist"
675                else
676
677//                      HDF5AttributeInfo(fileID, "/", 1, "file_name", 0, di)
678                        HDF5AttributeInfo(fileID, "/", 1, "NeXus_version", 0, di)
679                        Print di
680
681//                      see the HDF5 Browser  for how to get the actual <value> of the attribute. See GetPreviewString in
682//        or in FillGroupAttributesList or in FillDatasetAttributesList (from FillLists)
683//                      it seems to be ridiculously complex to get such a simple bit of information - the HDF5BrowserData STRUCT
684//                      needs to be filled first. Ugh.
685                        attrValue = GetPreviewString(fileID, 1, di, "/entry", "cucumber")
686                        Print "attrValue = ",attrValue
687                       
688                       
689                        //get attributes and save them
690                        HDF5ListAttributes/TYPE=1 /Z fileID, groupName          //TYPE=1 means that we're referencing a group, not a dataset
691                        Print "S_HDF5ListAttributes = ", S_HDF5ListAttributes
692                       
693                        // passing the groupID works too, then the group name is not needed                     
694                        HDF5ListAttributes/TYPE=1 /Z groupID, "."               //TYPE=1 means that we're referencing a group, not a dataset
695                        Print "S_HDF5ListAttributes = ", S_HDF5ListAttributes
696                endif
697        catch
698
699                // catch any aborts here
700               
701        endtry
702       
703        if(groupID)
704                HDF5CloseGroup /Z groupID
705        endif
706       
707        if(fileID)
708                HDF5CloseFile /Z fileID
709        endif
710
711        setDataFolder $cDF
712        return err
713end
714
715
716/////////////// end of the testing procedures ////////////////
Note: See TracBrowser for help on using the repository browser.