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

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

more changes, lots of files.

File size: 25.4 KB
Line 
1#pragma rtGlobals=3             // Use modern global access method and strict wave access.
2
3//
4// The base functions for R/W from HDF5 files.
5// All of the specific "get" and "write" functions call these base functions which are responsible
6// for all of the open/close mechanics.
7//
8// These VSANS file-specific functions are in:
9// V_HDF5_Read.ipf
10//               and
11// V_HDF5_Write.ipf
12//
13
14// data is read into:
15//      NewDataFolder/O/S root:Packages:NIST:VSANS:RawVSANS
16// so that the data folders of the raw data won't be lying around on the top level, looking like
17// 1D data sets and interfering.
18
19
20// the base data folder path where the raw data is loaded
21Strconstant ksBaseDFPath = "root:Packages:NIST:VSANS:RawVSANS:"
22
23// the list of WORK Folders
24Strconstant ksWorkFolderList = "RAW;SAM;EMP;BGD;COR;DIV;ABS;MSK;CAL;STO;SUB;DRK;ADJ;VCALC;RawVSANS;"
25
26
27// passing null file string presents a dialog
28Proc LoadFakeDIVData()
29        V_LoadHDF5Data("","DIV")
30End
31
32// passing null file string presents a dialog
33Proc LoadFakeMASKData()
34        V_LoadHDF5Data("","MSK")
35End
36
37// passing null file string presents a dialog
38Proc Read_HDF5_Raw_No_Attributes()
39        V_LoadHDF5Data("","RAW")
40End
41
42
43// TODO:
44//  x- move the initialization of the raw data folder to be in the as-yet unwritten initialization routine for
45// reduction. be sure that it's duplicated in the VCALC initialization too.
46// -- as needed, get rid of the FAKE redimension of the data from 3D->2D and from 128x128 to something else for VSANS
47//    This is a fake since I don't have anything close to correct fake data yet. (1/29/16)
48//
49// DONE: x- is there an extra "entry" heading? Am I adding this by mistake by setting base_name="entry" for RAW data?
50//                      x- as dumb as it is -- do I just leave it now, or break everything. On the plus side, removing the extra "entry"
51//          layer may catch a lot of the hard-wired junk that is present...
52//      extra entry layer is no longer generated for any WORK folders
53//
54Function V_LoadHDF5Data(file,folder)
55        String file,folder
56
57        String base_name,detStr
58        String destPath
59        Variable ii
60       
61        SetDataFolder $("root:Packages:NIST:VSANS:"+folder)
62        destPath = "root:Packages:NIST:VSANS:"+folder
63
64        Variable err= V_LoadHDF5_NoAtt(file,folder)     // reads into current folder
65       
66        // if RAW data, then generate the errors and linear data copy
67        // do this 9x
68        // then do any "massaging" needed to redimension, fake values, etc.
69        //
70        string tmpStr = "root:Packages:NIST:VSANS:RAW:entry:instrument:"
71
72        if(cmpstr(folder,"RAW")==0)
73       
74                // TODO -- once I get "real" data, get rid of this call to force the data to be proper dimensions.
75//              V_RedimFakeData()
76               
77                V_MakeDataWaves_DP(folder)
78//              V_FakeBeamCenters()
79//              V_FakeScaleToCenter()
80               
81
82                // makes data error and linear copy -- DP waves if V_MakeDataWaves_DP() called above
83                for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
84                        detStr = StringFromList(ii, ksDetectorListAll, ";")
85                        V_MakeDataError(tmpStr+"detector_"+detStr)     
86                endfor
87
88                // TODO
89                //  -- get rid of these fake calibration waves as "real" ones are filled in by NICE
90//              (currently does nothing)
91//              Execute "MakeFakeCalibrationWaves()"
92               
93                //              fMakeFakeCalibrationWaves()             //skips the alert
94
95
96                // TODO -- do I want to calculate the nonlinear x/y arrays and the q-values here?
97                // -- otherwise the mouse-over doesn't calculate the correct Q_values
98                // the display currently is not shifted or altered at all to account for the non-linearity
99                // or for display in q-values -- so why bother with this?
100                NVAR gDoNonLinearCor = root:Packages:NIST:VSANS:Globals:gDoNonLinearCor
101                // generate a distance matrix for each of the detectors
102                if (gDoNonLinearCor == 1)
103                        Print "Calculating Non-linear correction at RAW load time"// for "+ detStr
104                        for(ii=0;ii<ItemsInList(ksDetectorListNoB);ii+=1)
105                                detStr = StringFromList(ii, ksDetectorListNoB, ";")
106                                Wave w = V_getDetectorDataW(folder,detStr)
107        //                      Wave w_err = V_getDetectorDataErrW(fname,detStr)
108                                Wave w_calib = V_getDetTube_spatialCalib(folder,detStr)
109                                Variable tube_width = V_getDet_tubeWidth(folder,detStr)
110                                NonLinearCorrection(w,w_calib,tube_width,detStr,destPath)
111                               
112                               
113                                //(2.4) Convert the beam center values from pixels to mm
114                                // TODO -- there needs to be a permanent location for these values??
115                                //
116                                ConvertBeamCtr_to_mm(folder,detStr,destPath)
117                               
118                                // (2.5) Calculate the q-values
119                                // calculating q-values can't be done unless the non-linear corrections are calculated
120                                // so go ahead and put it in this loop.
121                                // TODO :
122                                // -- make sure that everything is present before the calculation
123                                // -- beam center must be properly defined in terms of real distance
124                                // -- distances/zero location/ etc. must be clearly documented for each detector
125                                //      ** this assumes that NonLinearCorrection() has been run to generate data_RealDistX and Y
126                                // ** this routine Makes the waves QTot, qx, qy, qz in each detector folder.
127                                //
128                                V_Detector_CalcQVals(folder,detStr,destPath)
129                               
130                        endfor
131                       
132                        //"B" is separate
133                        NonLinearCorrection_B(folder,"B",destPath)
134                        ConvertBeamCtr_to_mmB(folder,"B",destPath)
135                        V_Detector_CalcQVals(folder,"B",destPath)
136                       
137                else
138                        Print "Non-linear correction not done"
139                endif
140                                       
141                                       
142                /// END FAKE DATA CORRECTIONS           
143                       
144        endif
145       
146        SetDataFolder root:
147        return(err)
148End
149
150// fname is the folder = "RAW"
151Function V_MakeDataWaves_DP(fname)
152        String fname
153       
154        Variable ii
155        String detStr
156       
157        for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
158                detStr = StringFromList(ii, ksDetectorListAll, ";")
159                Wave w = V_getDetectorDataW(fname,detStr)
160//              Wave w_err = V_getDetectorDataErrW(fname,detStr)
161                Redimension/D w
162//              Redimension/D w_err
163        endfor
164       
165        return(0)
166End
167
168
169
170//
171// TODO -- this is all FAKED since all the data arrays are written to hdf as (1,128,128)
172//  -- try to fill in the bits from VCALC, if it exists (or force it)
173//
174// the SetScale parts may be useful later.
175//
176// This is NOT CALLED anymore.
177// the rescaling (SetScale) of the data sets is still done separately to a "fake" beam center
178Function V_RedimFakeData()
179       
180        // check for fake data in VCALC folder...
181        wave/Z tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_B:det_B"
182        if(WaveExists(tmpw) == 0)
183                Execute "VCALC_Panel()"
184        endif
185       
186        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_B
187        Wave det_B=data
188//      Redimension/N=(150,150)/E=1 det_B       
189        Redimension/D det_B
190        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_B:det_B"
191//      det_B=tmpw
192//      det_B += 2
193        Wave distance=distance
194        distance = VCALC_getSDD("B")*100                // to convert m to cm
195
196                       
197        Variable ctr=20,npix=128
198        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_MT
199        Wave det_MT=data
200//      Redimension/N=(npix,48)/E=1 det_MT
201        Redimension/D det_MT           
202        SetScale/I x -npix/2,npix/2,"",det_MT
203        SetScale/I y ctr,ctr+48,"",det_MT
204//      det_MT *= 10
205//      det_MT += 2
206        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_MT:det_MT"
207//      det_MT=tmpw
208//      det_MT += 2
209        Wave distance=distance
210        distance = VCALC_getSDD("MT")*100               // to convert m to cm
211
212       
213        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_MB
214        Wave det_MB=data
215//      Redimension/N=(npix,48)/E=1 det_MB             
216        Redimension/D det_MB
217        SetScale/I x -npix/2,npix/2,"",det_MB
218        SetScale/I y -ctr-48,-ctr,"",det_MB
219//      det_MB *= 5
220//      det_MB += 2
221        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_MB:det_MB"
222//      det_MB=tmpw
223//      det_MB += 2
224        Wave distance=distance
225        distance = VCALC_getSDD("MB")*100               // to convert m to cm
226
227       
228        ctr=30
229        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_ML
230        Wave det_ML=data
231//      Redimension/N=(48,npix)/E=1 det_ML             
232        Redimension/D det_ML
233        SetScale/I x -ctr-48,-ctr,"",det_ML
234        SetScale/I y -npix/2,npix/2,"",det_ML
235//      det_ML *= 2
236//      det_ML += 2
237        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_ML:det_ML"
238//      det_ML=tmpw
239//      det_ML += 2
240        Wave distance=distance
241        distance = VCALC_getSDD("ML")*100               // to convert m to cm
242
243               
244        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_MR
245        Wave det_MR=data
246//      Redimension/N=(48,npix)/E=1 det_MR             
247        Redimension/D det_MR
248        SetScale/I x ctr,ctr+48,"",det_MR
249        SetScale/I y -npix/2,npix/2,"",det_MR
250//      det_MR +=2
251        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_MR:det_MR"
252//      det_MR=tmpw
253//      det_MR += 2
254        Wave distance=distance
255        distance = VCALC_getSDD("MR")*100               // to convert m to cm
256       
257       
258        ctr=30
259        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FT
260        Wave det_FT=data
261//      Redimension/N=(npix,48)/E=1 det_FT             
262        Redimension/D det_FT
263        SetScale/I x -npix/2,npix/2,"",det_FT
264        SetScale/I y ctr,ctr+48,"",det_FT
265        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_FT:det_FT"
266//      det_FT=tmpw
267        Wave distance=distance
268        distance = VCALC_getSDD("FT")*100               // to convert m to cm
269
270
271        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FB
272        Wave det_FB=data
273//      Redimension/N=(npix,48)/E=1 det_FB             
274        Redimension/D det_FB
275        SetScale/I x -npix/2,npix/2,"",det_FB
276        SetScale/I y -ctr-48,-ctr,"",det_FB
277        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_FB:det_FB"
278//      det_FB=tmpw
279        Wave distance=distance
280        distance = VCALC_getSDD("FB")*100               // to convert m to cm
281
282                       
283        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FL
284        Wave det_FL=data
285//      Redimension/N=(48,npix)/E=1 det_FL             
286        Redimension/D det_FL
287        SetScale/I x -ctr-48,-ctr,"",det_FL
288        SetScale/I y -npix/2,npix/2,"",det_FL
289        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_FL:det_FL"
290//      det_FL=tmpw
291        Wave distance=distance
292        distance = VCALC_getSDD("FL")*100               // to convert m to cm
293
294       
295        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FR
296        Wave det_FR=data
297//      Redimension/N=(48,npix)/E=1 det_FR             
298        Redimension/D det_FR
299        SetScale/I x ctr,ctr+48,"",det_FR
300        SetScale/I y -npix/2,npix/2,"",det_FR
301        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_FR:det_FR"
302//      det_FR=tmpw
303        Wave distance=distance
304        distance = VCALC_getSDD("FR")*100               // to convert m to cm
305
306       
307// get rid of zeros
308//      det_FL += 2
309//      det_FR += 2
310//      det_FT += 2
311//      det_FB += 2
312
313
314// fake beam center values
315        V_putDet_beam_center_x("RAW","B",75)
316        V_putDet_beam_center_y("RAW","B",75)
317
318        V_putDet_beam_center_x("RAW","MB",64)
319        V_putDet_beam_center_y("RAW","MB",55)
320        V_putDet_beam_center_x("RAW","MT",64)
321        V_putDet_beam_center_y("RAW","MT",-8.7)
322        V_putDet_beam_center_x("RAW","MR",-8.1)
323        V_putDet_beam_center_y("RAW","MR",64)
324        V_putDet_beam_center_x("RAW","ML",55)
325        V_putDet_beam_center_y("RAW","ML",64)
326
327        V_putDet_beam_center_x("RAW","FB",64)
328        V_putDet_beam_center_y("RAW","FB",55)
329        V_putDet_beam_center_x("RAW","FT",64)
330        V_putDet_beam_center_y("RAW","FT",-8.7)
331        V_putDet_beam_center_x("RAW","FR",-8.1)
332        V_putDet_beam_center_y("RAW","FR",64)
333        V_putDet_beam_center_x("RAW","FL",55)
334        V_putDet_beam_center_y("RAW","FL",64)
335
336
337        V_RescaleToBeamCenter("RAW","MB",64,55)
338        V_RescaleToBeamCenter("RAW","MT",64,-8.7)
339        V_RescaleToBeamCenter("RAW","MR",-8.1,64)
340        V_RescaleToBeamCenter("RAW","ML",55,64)
341        V_RescaleToBeamCenter("RAW","FL",55,64)
342        V_RescaleToBeamCenter("RAW","FR",-8.1,64)
343        V_RescaleToBeamCenter("RAW","FT",64,-8.7)
344        V_RescaleToBeamCenter("RAW","FB",64,55)
345
346
347
348        return(0)
349End
350
351
352// This loads for speed, since loading the attributes takes a LOT of time.
353//
354// this will load in the whole HDF file all at once.
355// Attributes are NOT loaded at all.
356//
357// -- the Gateway function H5GW_ReadHDF5(parentFolder, fileName, [hdf5Path])
358//    reads in the attributes too, but is very slow
359//   -- the H5GW function is called by: H_HDF5Gate_Read_Raw(file)
360//
361// TODO:
362// -x remove the P=home restriction top make this more generic (replaced with catPathName from PickPath)
363// -- get rid of bits leftover here that I don't need
364// -- be sure I'm using all of the correct flags in the HDF5LoadGroup operation
365// -- settle on how the base_name is to be used. "entry" for the RAW, fileName for the "rawVSANS"?
366// x- error check for path existence
367//
368// passing in "" for base_name will take the name from the file name as selected
369//
370Function V_LoadHDF5_NoAtt(fileName,base_name)
371        String fileName, base_name
372       
373//      if ( ParamIsDefault(hdf5Path) )
374//              hdf5Path = "/"
375//      endif
376
377        PathInfo/S catPathName
378        if(V_flag == 0)
379                V_PickPath()
380        endif
381
382        String hdf5path = "/"           //always read from the top
383        String status = ""
384
385        Variable fileID = 0
386//      HDF5OpenFile/R/P=home/Z fileID as fileName              //read file from home directory?
387        HDF5OpenFile/R/P=catPathName/Z fileID as fileName
388        if (V_Flag != 0)
389                return 0
390        endif
391
392        String/G root:file_path = S_path
393        String/G root:file_name = S_FileName
394       
395        if ( fileID == 0 )
396                Print fileName + ": could not open as HDF5 file"
397                return (0)
398        endif
399       
400//s_tic()               //fast
401       
402        SVAR tmpStr=root:file_name
403        fileName=tmpStr         //SRK - in case the file was chosen from a dialog, I'll need access to the name later
404       
405        //   read the data (too bad that HDF5LoadGroup does not read the attributes)
406//      if(cmpstr(base_name,"") == 0)
407//              base_name = StringFromList(0,FileName,".")
408//      endif
409       
410        // if base_name is from my list of WORK folders, then base_name = ""
411        // use a stringSwitch? WhichListItem?
412        Variable isFolder = WhichListItem(base_name,ksWorkFolderList)
413        if(isFolder != -1)
414                base_name = ""
415        else
416                base_name = StringFromList(0,FileName,".")
417        endif
418       
419        HDF5LoadGroup/Z/L=7/O/R/T=$base_name  :, fileID, hdf5Path               //      recursive
420        if ( V_Flag != 0 )
421                Print fileName + ": could not open as HDF5 file"
422                setdatafolder root:
423                return (0)
424        endif
425
426        HDF5CloseFile fileID
427       
428//s_toc()
429        return(0)
430end     
431
432
433// read a single real value
434// - fname passed in is the full path to the file on disk
435// - path is the path to the value in the HDF tree
436//
437// check to see if the value exists (It will be a wave)
438// -- if it does, return the value from the local folder
439// -- if not, read the file in, then return the value
440//
441// TODO:
442// currently, the work folders have the following path - so passing in "RAW" as fname
443// will take some re-configuring.
444//  root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FL:distance
445// -- be sure this read from work folders is not broken in the future, and is passed to ALL of the
446//    top-level R/W routines. (Write is necessary ONLY for SIM data files. Patch is direct to disk.)
447Function V_getRealValueFromHDF5(fname,path)
448        String fname,path
449
450        String folderStr=""
451        Variable valExists=0
452       
453        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
454
455// check for a work folder first (note that "entry" is now NOT doubled)
456        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
457                Wave/Z w = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
458                return(w[0])
459        endif
460       
461        if(Exists(ksBaseDFPath+folderStr+":"+path))
462                valExists=1
463        endif
464       
465        if(!valExists)
466                //then read in the file, putting the data in RawVSANS
467                SetDataFolder ksBaseDFPath
468                V_LoadHDF5_NoAtt(fname,"")
469                SetDataFolder root:
470        endif
471
472// this should exist now - if not, I need to see the error
473        Wave/Z w = $(ksBaseDFPath+folderStr+":"+path)
474       
475        if(WaveExists(w))
476                return(w[0])
477        else
478                return(-999999)
479        endif   
480End
481
482// Returns a wave reference, not just a single value
483// ---then you pick what you need from the wave
484//
485// - fname passed in is the full path to the file on disk
486// - path is the path to the value in the HDF tree
487//
488// check to see if the value exists (It will be a wave)
489// -- if it does, return the value from the local folder
490// -- if not, read the file in, then return the value
491//
492Function/WAVE V_getRealWaveFromHDF5(fname,path)
493        String fname,path
494
495        String folderStr=""
496        Variable valExists=0
497       
498        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
499
500// check for a work folder first (note that "entry" is NOT doubled)
501        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
502                Wave wOut = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
503                return wOut
504        endif
505               
506        if(Exists(ksBaseDFPath+folderStr+":"+path))
507                valExists=1
508        endif
509
510        if(!valExists)
511                //then read in the file, putting the data in RawVSANS
512                SetDataFolder ksBaseDFPath
513                V_LoadHDF5_NoAtt(fname,"")
514                SetDataFolder root:
515        endif
516               
517// this should exist now - if not, I need to see the error
518        Wave wOut = $(ksBaseDFPath+folderStr+":"+path)
519       
520        return wOut
521       
522End
523
524// Returns a wave reference, not just a single value
525// ---then you pick what you need from the wave
526//
527// - fname passed in is the full path to the file on disk
528// - path is the path to the value in the HDF tree
529//
530// check to see if the value exists (It will be a wave)
531// -- if it does, return the value from the local folder
532// -- if not, read the file in, then return the value
533//
534Function/WAVE V_getTextWaveFromHDF5(fname,path)
535        String fname,path
536
537        String folderStr=""
538        Variable valExists=0
539       
540        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
541
542// check for a work folder first (note that "entry" is NOT doubled)
543        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
544                Wave/T wOut = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
545                return wOut
546        endif
547       
548        if(Exists(ksBaseDFPath+folderStr+":"+path))
549                valExists=1
550        endif
551       
552        if(!valExists)
553                //then read in the file, putting the data in RawVSANS
554                SetDataFolder ksBaseDFPath
555                V_LoadHDF5_NoAtt(fname,"")
556                SetDataFolder root:
557        endif
558
559// this should exist now - if not, I need to see the error
560        Wave/T wOut = $(ksBaseDFPath+folderStr+":"+path)
561       
562        return wOut
563       
564End
565
566
567//
568//   TODO
569// depricated? in HDF5 - store all of the values as real?
570// Igor sees no difference in real and integer variables (waves are different)
571// BUT-- Igor 7 will have integer variables
572//
573// truncate to integer before returning??
574//
575//  TODO
576// write a "getIntegerWave" function??
577//
578//////  integer values
579// reads 32 bit integer
580Function V_getIntegerFromHDF5(fname,path)
581        String fname                            //full path+name
582        String path                             //path to the hdf5 location
583       
584        Variable val = V_getRealValueFromHDF5(fname,path)
585       
586        val = round(val)
587        return(val)
588End
589
590
591// read a single string
592// - fname passed in is the full path to the file on disk
593// - path is the path to the value in the HDF tree
594// - num is the number of characters in the VAX string
595// check to see if the value exists (It will be a wave)
596// -- if it does, return the value from the local folder
597// -- if not, read the file in, then return the value
598//
599// TODO -- string could be checked for length, but returned right or wrong
600//
601// -- currently num is completely ignored
602//
603Function/S V_getStringFromHDF5(fname,path,num)
604        String fname,path
605        Variable num
606
607        String folderStr=""
608        Variable valExists=0
609       
610        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
611
612// check for a work folder first (note that "entry" is NOT doubled)
613        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
614                Wave/Z/T tw = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
615                return(tw[0])
616        endif
617       
618        if(Exists(ksBaseDFPath+folderStr+":"+path))
619                valExists=1
620        endif
621
622        if(!valExists)
623                //then read in the file, putting the data in RawVSANS
624                SetDataFolder ksBaseDFPath
625                V_LoadHDF5_NoAtt(fname,"")
626                SetDataFolder root:
627        endif
628
629// this should exist now - if not, I need to see the error
630        Wave/T/Z tw = $(ksBaseDFPath+folderStr+":"+path)
631       
632        if(WaveExists(tw))
633       
634        //      if(strlen(tw[0]) != num)
635        //              Print "string is not the specified length"
636        //      endif
637               
638                return(tw[0])
639        else
640                return("The specified wave does not exist: " + path)
641        endif
642End
643
644
645
646///////////////////////////////
647
648//
649//Write Wave 'wav' to hdf5 file 'fname'
650//Based on code from ANSTO (N. Hauser. nha 8/1/09)
651//
652// TODO:
653// -- figure out if this will write in the native format of the
654//     wave as passed in, or if it will only write as DP.
655// -- do I need to write separate functions for real, integer, etc.?
656// -- the lines to create a missing group have been commented out to avoid filling
657//    in missing fields that should have been generated by the data writer. Need to make
658//    a separate function that will write and generate if needed, and use this in specific cases
659//    only if I really have to force it.
660//
661// --Attributes are not currently saved. Fix this, maybe make it optional? See the help file for
662//  DemoAttributes(w) example under the HDF5SaveData operation
663//     
664// -x change the /P=home to the user-defined data path (catPathName)           
665//
666Function V_WriteWaveToHDF(fname, groupName, varName, wav)
667        String fname, groupName, varName
668        Wave wav
669       
670       
671        // try a local folder first, then try to save to disk
672        //
673        String folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
674       
675        String localPath = "root:Packages:NIST:VSANS:"+folderStr//+":entry"
676        localPath += groupName + "/" + varName
677        // make everything colons for local data folders
678        localPath = ReplaceString("/", localPath, ":")
679       
680        Wave/Z w = $localPath
681        if(waveExists(w) == 1)
682                w = wav
683                Print "write to local folder done"
684                return(0)               //we're done, get out
685        endif
686       
687       
688        // if the local wave did not exist, then we proceed to write to disk
689
690       
691        variable err=0, fileID,groupID
692        String cDF = getDataFolder(1), temp
693        String NXentry_name
694       
695        try     
696                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
697                if(!fileID)
698                        err = 1
699                        abort "HDF5 file does not exist"
700                endif
701               
702                //get the NXentry node name
703                HDF5ListGroup /TYPE=1 fileID, "/"
704                //remove trailing ; from S_HDF5ListGroup
705               
706                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
707               
708                NXentry_name = S_HDF5ListGroup
709                NXentry_name = ReplaceString(";",NXentry_name,"")
710                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
711                        err = 1
712                        abort "More than one entry under the root node. Ambiguous"
713                endif
714                //concatenate NXentry node name and groupName   
715                // SRK - NOV2015 - dropped this and require the full group name passed in
716//              groupName = "/" + NXentry_name + groupName
717                Print "groupName = ",groupName
718                HDF5OpenGroup /Z fileID , groupName, groupID
719
720                if(!groupID)
721                // don't create the group if the name isn't right -- throw up an error
722                        //HDF5CreateGroup /Z fileID, groupName, groupID
723                        err = 1
724                        HDF5CloseFile /Z fileID
725                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
726                        return(err)
727                else
728                        // get attributes and save them
729                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
730                        //Wave attributes = S_HDF5ListAttributes
731                endif
732       
733                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
734                if (V_flag != 0)
735                        err = 1
736                        abort "Cannot save wave to HDF5 dataset " + varName
737                endif   
738               
739               
740                //attributes - something could be added here as optional parameters and flagged
741//              String attributes = "units"
742//              Make/O/T/N=1 tmp
743//              tmp[0] = "dimensionless"
744//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
745//              if (V_flag != 0)
746//                      err = 1
747//                      abort "Cannot save attributes to HDF5 dataset"
748//              endif   
749        catch
750
751        endtry
752
753// it is not necessary to close the group here. HDF5CloseFile will close the group as well     
754        if(groupID)
755                HDF5CloseGroup /Z groupID
756        endif
757       
758        if(fileID)
759                HDF5CloseFile /Z fileID
760        endif
761
762        setDataFolder $cDF
763        return err
764end
765
766//Write Wave 'wav' to hdf5 file 'fname'
767//Based on code from ANSTO (N. Hauser. nha 8/1/09)
768//
769// TODO
770//
771// -x change the /P=home to the user-defined data path (catPathName)           
772//
773Function V_WriteTextWaveToHDF(fname, groupName, varName, wav)
774        String fname, groupName, varName
775        Wave/T wav
776
777        // try a local folder first, then try to save to disk
778        //
779        String folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
780       
781        String localPath = "root:Packages:NIST:VSANS:"+folderStr//+":entry"
782        localPath += groupName + "/" + varName
783        // make everything colons for local data folders
784        localPath = ReplaceString("/", localPath, ":")
785       
786        Wave/Z/T w = $localPath
787        if(waveExists(w) == 1)
788                w = wav
789                Print "write to local folder done"
790                return(0)               //we're done, get out
791        endif
792       
793       
794        // if the local wave did not exist, then we proceed to write to disk
795
796
797       
798        variable err=0, fileID,groupID
799        String cDF = getDataFolder(1), temp
800        String NXentry_name
801       
802        try     
803                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
804                if(!fileID)
805                        err = 1
806                        abort "HDF5 file does not exist"
807                endif
808               
809                //get the NXentry node name
810                HDF5ListGroup /TYPE=1 fileID, "/"
811                //remove trailing ; from S_HDF5ListGroup
812               
813                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
814               
815                NXentry_name = S_HDF5ListGroup
816                NXentry_name = ReplaceString(";",NXentry_name,"")
817                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
818                        err = 1
819                        abort "More than one entry under the root node. Ambiguous"
820                endif
821
822                //concatenate NXentry node name and groupName
823                // SRK - NOV2015 - dropped this and require the full group name passed in
824//              groupName = "/" + NXentry_name + groupName
825                Print "groupName = ",groupName
826
827                HDF5OpenGroup /Z fileID , groupName, groupID
828
829                if(!groupID)
830                // don't create the group it the name isn't right -- throw up an error
831                        //HDF5CreateGroup /Z fileID, groupName, groupID
832                        err = 1
833                        HDF5CloseFile /Z fileID
834                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
835                        return(err)
836                else
837                        // get attributes and save them
838                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
839                        //Wave attributes = S_HDF5ListAttributes
840                endif
841       
842                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
843                if (V_flag != 0)
844                        err = 1
845                        abort "Cannot save wave to HDF5 dataset " + varName
846                endif   
847               
848               
849                //attributes - something could be added here as optional parameters and flagged
850//              String attributes = "units"
851//              Make/O/T/N=1 tmp
852//              tmp[0] = "dimensionless"
853//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
854//              if (V_flag != 0)
855//                      err = 1
856//                      abort "Cannot save attributes to HDF5 dataset"
857//              endif   
858        catch
859
860        endtry
861       
862        if(groupID)
863                HDF5CloseGroup /Z groupID
864        endif
865       
866        if(fileID)
867                HDF5CloseFile /Z fileID
868        endif
869
870        setDataFolder $cDF
871        return err
872end
873
874//////////////////////////////
875//////////////////////////////
876//////////////////////////////
877
878
Note: See TracBrowser for help on using the repository browser.