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

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

a number of changes, mostly to allow everything to compile.

added conditional compile to ensure that XML code would not be compiled if VSANS was present, since it's not XML-aware.

modified V_MainPanel to avoid conflicts with the SANS version. There still may be some functions hidden in procedures that do not have the V_ prefix yet, but these are either for functions that should point to a common file, or procedures that have been hidden from the VSANS panel

modified saving of VSANS mask files so that they can still be saved from teh deom version where home path is not defined.

File size: 33.2 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 in V_MakeDataError() by duplicating dataW
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// ***NOTE***
467// The temperature block definitons inculde dupilcated groups. As of 7/27/17 (HDF 5 XOP version 1.24, in Igor 7.05)
468// these duplicated blocks are now handled "correctly" by reading in the multiple copies into
469// duplciated data folders. WM (Howard) modifed the XOP to accomodate this condition.
470// This is the R=2 flag for HDF5LoadGroup
471
472//// to skip DAS_logs. I need to generate all of the data folders myself
473//// must be an easier way to handle the different path syntax, but at least this works
474
475        String curDF = GetDataFolder(1)
476
477// load root/entry
478        hdf5path = "/entry"
479//      NewDataFolder/O $(curDF)
480        if(isFolder == -1)
481                NewDataFolder/O $(curDF+base_name)
482        endif
483        if(isFolder == -1)
484                NewDataFolder/O/S $(curDF+base_name+":entry")
485        else
486                // base_name is "", so get rid of the leading ":" on ":entry"
487                NewDataFolder/O/S $(curDF+base_name+"entry")
488        endif
489        HDF5LoadGroup/Z/L=7/O :, fileID, hdf5Path               //      NOT recursive
490
491
492        if(isFolder == -1)
493                NewDataFolder/O/S $(curDF+base_name+":entry:control")
494        else
495                NewDataFolder/O/S $(curDF+base_name+"entry:control")
496        endif
497        hdf5path = "/entry/control"
498        HDF5LoadGroup/Z/L=7/O/R=2  :, fileID, hdf5Path          //      YES recursive
499
500        if(isFolder == -1)
501                NewDataFolder/O/S $(curDF+base_name+":entry:instrument")
502        else
503                NewDataFolder/O/S $(curDF+base_name+"entry:instrument")
504        endif
505        hdf5path = "/entry/instrument"
506        HDF5LoadGroup/Z/L=7/O/R=2  :, fileID, hdf5Path          //      YES recursive
507
508        if(isFolder == -1)
509                NewDataFolder/O/S $(curDF+base_name+":entry:reduction")
510        else
511                NewDataFolder/O/S $(curDF+base_name+"entry:reduction")
512        endif   
513        hdf5path = "/entry/reduction"
514        HDF5LoadGroup/Z/L=7/O/R=2  :, fileID, hdf5Path          //      YES recursive
515
516        if(isFolder == -1)
517                NewDataFolder/O/S $(curDF+base_name+":entry:sample")
518        else
519                NewDataFolder/O/S $(curDF+base_name+"entry:sample")
520        endif   
521        hdf5path = "/entry/sample"
522        HDF5LoadGroup/Z/L=7/O/R=2  :, fileID, hdf5Path          //      YES recursive (This is the only one that may have duplicated groups)
523
524        if(isFolder == -1)
525                NewDataFolder/O/S $(curDF+base_name+":entry:user")
526        else
527                NewDataFolder/O/S $(curDF+base_name+"entry:user")
528        endif   
529        hdf5path = "/entry/user"
530        HDF5LoadGroup/Z/L=7/O/R=2  :, fileID, hdf5Path          //      YES recursive
531
532
533       
534        if ( V_Flag != 0 )
535                Print fileName + ": could not open as HDF5 file"
536                setdatafolder root:
537                return (1)
538        endif
539
540        HDF5CloseFile fileID
541       
542//v_toc()
543
544        // save a global string with the file name to be picked up for the status on the display
545        // this string can be carried around as the data is moved to other folders
546//      Print curDF+"gFileList"
547        String/G $(curDF+"gFileList") = fileName
548
549
550        SetDataFolder root:
551       
552        return(0)
553end     
554
555
556// read a single real value
557// - fname passed in is the full path to the file on disk --OR-- a WORK folder
558// - path is the path to the value in the HDF tree
559//
560/// -- if data requested from a WORK or VCALC folder:
561// check to see if the value exists (It will be a wave)
562// -- if it does, return the value from the local WORK folder
563//              if it does not exist, return DUMMY value
564//
565//// -- if data requested from a file:
566// check to see if the value exists locally in RawVSANS (It will be a wave)
567// -- if it does, return the value from the local folder
568// -- if not, read the file in, then return the value
569//
570//
571Function V_getRealValueFromHDF5(fname,path)
572        String fname,path
573
574        String folderStr=""
575        Variable valExists=0
576        Variable errorValue = -999999
577       
578        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
579
580// (1) if requesting data from a WORK folder, get it, or report error
581        Variable isWORKFolder = WhichListItem(fname,ksWorkFolderListShort+"VCALC;")
582        if(isWORKFolder != -1)          //requesting value from a WORK folder (not RawVSANS)
583        // check for a work folder first (note that "entry" is now NOT doubled)
584                if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
585                        Wave/Z w = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
586                        return(w[0])
587                else
588                        return(errorValue)
589                endif
590        endif
591
592
593        // (2) requesting from a file.
594        // look locally in RawVSANS if possible, or if not, load in the data from disk
595        // - if thee both fail, report an error
596        if(Exists(ksBaseDFPath+folderStr+":"+path))
597                valExists=1
598        endif
599       
600        if(!valExists)
601                //then read in the file, putting the data in RawVSANS
602                SetDataFolder ksBaseDFPath
603                V_LoadHDF5_NoAtt(fname,"")
604                SetDataFolder root:
605        endif
606
607// this should exist now - if not, I need to see the error
608        Wave/Z w = $(ksBaseDFPath+folderStr+":"+path)
609       
610        if(WaveExists(w))
611                return(w[0])
612        else
613                return(errorValue)
614        endif   
615End
616
617// Returns a wave reference, not just a single value
618// ---then you pick what you need from the wave
619//
620// - fname passed in is the full path to the file on disk
621// - path is the path to the value in the HDF tree
622//
623// check to see if the value exists (It will be a wave)
624// -- if it does, return the value from the local folder
625// -- if not, read the file in, then return the value
626//
627// if the wave is null, then that is returned, and the calling function is responsible
628//
629Function/WAVE V_getRealWaveFromHDF5(fname,path)
630        String fname,path
631
632        String folderStr=""
633        Variable valExists=0
634       
635        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
636
637// (1) if requesting data from a WORK folder, get it
638// no need to check for any existence, null return is OK
639        Variable isWORKFolder = WhichListItem(fname,ksWorkFolderListShort+"VCALC;")
640        if(isWORKFolder != -1)          //requesting value from a WORK folder (not RawVSANS)
641//      // check for a work folder first (note that "entry" is now NOT doubled)
642//              if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
643                        Wave/Z wOut = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
644                        return wOut
645        endif
646
647//// check for a work folder first (note that "entry" is NOT doubled)
648//      if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
649//              Wave wOut = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
650//              return wOut
651//      endif
652       
653// (2) requesting from a file
654        if(Exists(ksBaseDFPath+folderStr+":"+path))
655                valExists=1
656        endif
657
658        if(!valExists)
659                //then read in the file, putting the data in RawVSANS
660                SetDataFolder ksBaseDFPath
661                V_LoadHDF5_NoAtt(fname,"")
662                SetDataFolder root:
663        endif
664               
665// this should exist now - if not, I need to see the error
666        Wave wOut = $(ksBaseDFPath+folderStr+":"+path)
667       
668        return wOut
669       
670End
671
672// Returns a wave reference, not just a single value
673// ---then you pick what you need from the wave
674//
675// - fname passed in is the full path to the file on disk
676// - path is the path to the value in the HDF tree
677//
678// check to see if the value exists (It will be a wave)
679// -- if it does, return the value from the local folder
680// -- if not, read the file in, then return the value
681//
682// if the wave is null, then that is returned, and the calling function is responsible
683//
684Function/WAVE V_getTextWaveFromHDF5(fname,path)
685        String fname,path
686
687        String folderStr=""
688        Variable valExists=0
689       
690        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
691
692// (1) if requesting data from a WORK folder, get it
693// no need to check for any existence, null return is OK
694        Variable isWORKFolder = WhichListItem(fname,ksWorkFolderListShort+"VCALC;")
695        if(isWORKFolder != -1)          //requesting value from a WORK folder (not RawVSANS)
696//      // check for a work folder first (note that "entry" is now NOT doubled)
697//              if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
698                        Wave/Z/T wOut = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
699                        return wOut
700        endif
701       
702//// check for a work folder first (note that "entry" is NOT doubled)
703//      if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
704//              Wave/T wOut = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
705//              return wOut
706//      endif
707
708// (2) requesting from a file   
709        if(Exists(ksBaseDFPath+folderStr+":"+path))
710                valExists=1
711        endif
712       
713        if(!valExists)
714                //then read in the file, putting the data in RawVSANS
715                SetDataFolder ksBaseDFPath
716                V_LoadHDF5_NoAtt(fname,"")
717                SetDataFolder root:
718        endif
719
720// this should exist now - if not, I will see the error in the calling function
721        Wave/T/Z wOut = $(ksBaseDFPath+folderStr+":"+path)
722       
723        return wOut
724       
725End
726
727
728//
729//   TODO
730// depricated? in HDF5 - store all of the values as real?
731// Igor sees no difference in real and integer variables (waves are different)
732// BUT-- Igor 7 will have integer variables
733//
734// truncate to integer before returning??
735//
736//  TODO
737// write a "getIntegerWave" function??
738//
739//////  integer values
740// reads 32 bit integer
741Function V_getIntegerFromHDF5(fname,path)
742        String fname                            //full path+name
743        String path                             //path to the hdf5 location
744       
745        Variable val = V_getRealValueFromHDF5(fname,path)
746       
747        val = round(val)
748        return(val)
749End
750
751
752// read a single string
753// - fname passed in is the full path to the file on disk --OR-- a WORK folder
754// - path is the path to the value in the HDF tree
755// - num is the number of characters in the VAX string
756//
757/// -- if data requested from a WORK or VCALC folder:
758// check to see if the value exists (It will be a wave)
759// -- if it does, return the value from the local WORK folder
760//              if it does not exist, return DUMMY value
761//
762//// -- if data requested from a file:
763// check to see if the value exists locally in RawVSANS (It will be a wave)
764// -- if it does, return the value from the local folder
765// -- if not, read the file in, then return the value
766//
767// TODO -- string could be checked for length, but returned right or wrong
768//
769// -- currently num is completely ignored
770//
771Function/S V_getStringFromHDF5(fname,path,num)
772        String fname,path
773        Variable num
774
775        String folderStr=""
776        Variable valExists=0
777        String errorString = "The specified wave does not exist: " + path
778       
779        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
780
781// (1) if requesting data from a WORK folder, get it, or report error
782        Variable isWORKFolder = WhichListItem(fname,ksWorkFolderListShort+"VCALC;")
783        if(isWORKFolder != -1)          //requesting value from a WORK folder (not RawVSANS)
784        // check for a work folder first (note that "entry" is now NOT doubled)
785                if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
786                        Wave/Z/T tw = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
787                        return(tw[0])
788                else
789                        return(errorSTring)
790                endif
791        endif
792
793// (2) requesting from a file.
794// look locally in RawVSANS if possible, or if not, load in the data from disk
795// - if thee both fail, report an error
796        if(Exists(ksBaseDFPath+folderStr+":"+path))
797                valExists=1
798        endif
799
800        if(!valExists)
801                //then read in the file, putting the data in RawVSANS
802                SetDataFolder ksBaseDFPath
803                V_LoadHDF5_NoAtt(fname,"")
804                SetDataFolder root:
805        endif
806
807// this should exist now - if not, I need to see the error
808        Wave/T/Z tw = $(ksBaseDFPath+folderStr+":"+path)
809       
810        if(WaveExists(tw))
811       
812        //      if(strlen(tw[0]) != num)
813        //              Print "string is not the specified length"
814        //      endif
815               
816                return(tw[0])
817        else
818                return(errorString)
819        endif
820End
821
822
823
824///////////////////////////////
825
826//
827//Write Wave 'wav' to hdf5 file 'fname'
828//Based on code from ANSTO (N. Hauser. nha 8/1/09)
829//
830// TODO:
831// -- figure out if this will write in the native format of the
832//     wave as passed in, or if it will only write as DP.
833// -- do I need to write separate functions for real, integer, etc.?
834// -- the lines to create a missing group have been commented out to avoid filling
835//    in missing fields that should have been generated by the data writer. Need to make
836//    a separate function that will write and generate if needed, and use this in specific cases
837//    only if I really have to force it.
838//
839// --Attributes are not currently saved. Fix this, maybe make it optional? See the help file for
840//  DemoAttributes(w) example under the HDF5SaveData operation
841//     
842// -x change the /P=home to the user-defined data path (catPathName)           
843//
844Function V_WriteWaveToHDF(fname, groupName, varName, wav)
845        String fname, groupName, varName
846        Wave wav
847       
848       
849        // try a local folder first, then try to save to disk
850        //
851        String folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
852       
853        String localPath = "root:Packages:NIST:VSANS:"+folderStr//+":entry"
854        localPath += groupName + "/" + varName
855        // make everything colons for local data folders
856        localPath = ReplaceString("/", localPath, ":")
857       
858        Wave/Z w = $localPath
859        if(waveExists(w) == 1)
860                w = wav
861//              Print "write to local folder done"
862                return(0)               //we're done, get out
863        endif
864       
865       
866        // if the local wave did not exist, then we proceed to write to disk
867
868       
869        variable err=0, fileID,groupID
870        String cDF = getDataFolder(1), temp
871        String NXentry_name
872       
873        try     
874                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
875                if(!fileID)
876                        err = 1
877                        abort "HDF5 file does not exist"
878                endif
879               
880                //get the NXentry node name
881                HDF5ListGroup /TYPE=1 fileID, "/"
882                //remove trailing ; from S_HDF5ListGroup
883               
884                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
885               
886                NXentry_name = S_HDF5ListGroup
887                NXentry_name = ReplaceString(";",NXentry_name,"")
888                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
889                        err = 1
890                        abort "More than one entry under the root node. Ambiguous"
891                endif
892                //concatenate NXentry node name and groupName   
893                // SRK - NOV2015 - dropped this and require the full group name passed in
894//              groupName = "/" + NXentry_name + groupName
895                Print "groupName = ",groupName
896                HDF5OpenGroup /Z fileID , groupName, groupID
897
898                if(!groupID)
899                // don't create the group if the name isn't right -- throw up an error
900                        //HDF5CreateGroup /Z fileID, groupName, groupID
901                        err = 1
902                        HDF5CloseFile /Z fileID
903                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
904                        return(err)
905                else
906                        // get attributes and save them
907                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
908                        //Wave attributes = S_HDF5ListAttributes
909                endif
910       
911                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
912                if (V_flag != 0)
913                        err = 1
914                        abort "Cannot save wave to HDF5 dataset " + varName
915                endif   
916               
917               
918                //attributes - something could be added here as optional parameters and flagged
919//              String attributes = "units"
920//              Make/O/T/N=1 tmp
921//              tmp[0] = "dimensionless"
922//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
923//              if (V_flag != 0)
924//                      err = 1
925//                      abort "Cannot save attributes to HDF5 dataset"
926//              endif   
927        catch
928
929        endtry
930
931// it is not necessary to close the group here. HDF5CloseFile will close the group as well     
932        if(groupID)
933                HDF5CloseGroup /Z groupID
934        endif
935       
936        if(fileID)
937                HDF5CloseFile /Z fileID
938        endif
939
940        setDataFolder $cDF
941        return err
942end
943
944//Write Wave 'wav' to hdf5 file 'fname'
945//Based on code from ANSTO (N. Hauser. nha 8/1/09)
946//
947// TODO
948//
949// -x change the /P=home to the user-defined data path (catPathName)           
950//
951Function V_WriteTextWaveToHDF(fname, groupName, varName, wav)
952        String fname, groupName, varName
953        Wave/T wav
954
955        // try a local folder first, then try to save to disk
956        //
957        String folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
958       
959        String localPath = "root:Packages:NIST:VSANS:"+folderStr//+":entry"
960        localPath += groupName + "/" + varName
961        // make everything colons for local data folders
962        localPath = ReplaceString("/", localPath, ":")
963       
964        Wave/Z/T w = $localPath
965        if(waveExists(w) == 1)
966                w = wav
967                Print "write to local folder done"
968                return(0)               //we're done, get out
969        endif
970       
971       
972        // if the local wave did not exist, then we proceed to write to disk
973
974
975       
976        variable err=0, fileID,groupID
977        String cDF = getDataFolder(1), temp
978        String NXentry_name
979       
980        try     
981                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
982                if(!fileID)
983                        err = 1
984                        abort "HDF5 file does not exist"
985                endif
986               
987                //get the NXentry node name
988                HDF5ListGroup /TYPE=1 fileID, "/"
989                //remove trailing ; from S_HDF5ListGroup
990               
991                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
992               
993                NXentry_name = S_HDF5ListGroup
994                NXentry_name = ReplaceString(";",NXentry_name,"")
995                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
996                        err = 1
997                        abort "More than one entry under the root node. Ambiguous"
998                endif
999
1000                //concatenate NXentry node name and groupName
1001                // SRK - NOV2015 - dropped this and require the full group name passed in
1002//              groupName = "/" + NXentry_name + groupName
1003                Print "groupName = ",groupName
1004
1005                HDF5OpenGroup /Z fileID , groupName, groupID
1006
1007                if(!groupID)
1008                // don't create the group it the name isn't right -- throw up an error
1009                        //HDF5CreateGroup /Z fileID, groupName, groupID
1010                        err = 1
1011                        HDF5CloseFile /Z fileID
1012                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
1013                        return(err)
1014                else
1015                        // get attributes and save them
1016                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
1017                        //Wave attributes = S_HDF5ListAttributes
1018                endif
1019       
1020                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
1021                if (V_flag != 0)
1022                        err = 1
1023                        abort "Cannot save wave to HDF5 dataset " + varName
1024                endif   
1025               
1026               
1027                //attributes - something could be added here as optional parameters and flagged
1028//              String attributes = "units"
1029//              Make/O/T/N=1 tmp
1030//              tmp[0] = "dimensionless"
1031//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
1032//              if (V_flag != 0)
1033//                      err = 1
1034//                      abort "Cannot save attributes to HDF5 dataset"
1035//              endif   
1036        catch
1037
1038        endtry
1039       
1040        if(groupID)
1041                HDF5CloseGroup /Z groupID
1042        endif
1043       
1044        if(fileID)
1045                HDF5CloseFile /Z fileID
1046        endif
1047
1048        setDataFolder $cDF
1049        return err
1050end
1051
1052//////////////////////////////
1053//////////////////////////////
1054//////////////////////////////
1055
1056
1057
1058
1059
1060
1061//////////
1062//
1063// These procedures are needed to write out MASK and DIV files
1064//
1065////////
1066
1067
1068//
1069// saves a specified folder, with a given filename.
1070// saves to the home path
1071//
1072Proc Save_VSANS_file(dfPath, filename)
1073        String dfPath   ="root:VSANS_file"              // e.g., "root:FolderA" or ":"
1074        String filename = "Test_VSANS_file.h5"
1075       
1076        H_NXSANS_SaveGroupAsHDF5(dfPath, filename)
1077End
1078
1079
1080//     
1081// this is my procedure to save the folders to HDF5, once I've filled the folder tree
1082//
1083// this does NOT save attributes, but gets the folder structure correct
1084//
1085Function H_NXSANS_SaveGroupAsHDF5(dfPath, filename)
1086        String dfPath   // e.g., "root:FolderA" or ":"
1087        String filename
1088
1089        Variable result = 0     // 0 means no error
1090       
1091        Variable fileID
1092        PathInfo home
1093        if(V_flag == 1)
1094                HDF5CreateFile/P=home /O /Z fileID as filename
1095        else
1096                HDF5CreateFile /O/I /Z fileID as filename
1097        endif
1098        if (V_flag != 0)
1099                Print "HDF5CreateFile failed"
1100                return -1
1101        endif
1102
1103        HDF5SaveGroup /IGOR=0 /O /R /Z $dfPath, fileID, "."
1104//      HDF5SaveGroup /O /R /Z $dfPath, fileID, "."
1105        if (V_flag != 0)
1106                Print "HDF5SaveGroup failed"
1107                result = -1
1108        endif
1109       
1110        HDF5CloseFile fileID
1111
1112        return result
1113End
1114
Note: See TracBrowser for help on using the repository browser.