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

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

LOTS of changes to accommodate the beam center being reported in cm rather than pixels. Required a lot of changes to VCALC (to fill in simulated data), and in the reading and interpreting of data for display, and most importantly, the calculation of q.

There may still be a few residual bugs with this. I am still re-testing with new sample data sets.

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