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

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

more changes, lots of files.

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