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

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

added Annular averaging routine. still need writer, and link with protocols.

replaced tic/toc with v_tic/v_toc to avoid missing functions

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//v_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//v_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.