source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_ReadWrite_HDF5.ipf @ 963

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

Updated the display of the "beam center finder" to better display the panels with an appropriate aspect ratio for the pixels.

Made the number of pixels (x,y) on each of the panels as globals, plus access functions. Large panels were coded for 256, but will likely be 128 pixels in reality. Make global for easy changes. Made sure that exsting functions used the global and were not hard-wired.

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