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

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

Added procedures to increase the number of elements in a reduction protocol, to allow the trimming points to be added directly to the protocol.

The protocol can also now be written directly to the reduction block of the data file. This can serve as a record of what was used, and also for multiple reduction.

Although the protocol is not a NICE -generated block in the HDF file, there does not appear to be any issues with writing out this new wave to the data set, as long as I handle the error if I try to read it (since i't not there to begin with).

Protocol panel is now aware of this change, and the multiple reduce panel has been updated and added to the Inlcudes list.

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