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

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

moved dead time correction to before the solid angle correction, so that the dead time would be correcting counts, not counts per solid angle

added a routine to kill all of the waves and folders possible, if the overall DF kill failed. This is to prevent stray folders and waves from being present if different data files are loaded - since different data blocks are present for say, 3He data, data with temperature logging, etc.
This kill routine is used every time, before raw data is loaded, DIV or MASK loaded, or data is converted to WORK.

changed the "Save I(q)" button on the data display panel to save as ITX format, since the data has not been processed, and data can more easily be used for trimming input.

picking protocols in dialogs now excludes/includes appropriate waves

menus are consolidated

Fixed bug in SANS macros where the DRK[] item in the protocol could be null, and force the read of a DRK file, even if it was not desired.

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