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

Last change on this file since 1051 was 1051, checked in by srkline, 5 years ago

a lot of little changes:

changed the name of the Raw Data display procedure file (removed test)

lots of bug fixes, moving items from the macros menu to proper locations, getting the file status to display properly, some error checking, and cleaning up a few TODO items.

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