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

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

bug fixes for the back detector dimensions and beam center (pixels)

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