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

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

Significant changes to the base READ of individual data fields from data files. Now, if the field requested is from a WORK file, and it does not exist, an error condition is returned (or a null wave). Calling procedures are responsible for handling errors. This prevents a string of open file dialogs if fields are missing from a file if they were never in the file to begin with (like sensor logs, polarization hardware, etc.)

New get/write calls were added for the updated temperature sensor fields.

group_ID is now only in the sample block, not the duplicated in the reduction block, and is correctly a number not a string.

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