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

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

a few quick bug fixes

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.