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

Last change on this file since 989 was 989, checked in by srkline, 7 years ago

more additions to HDF reader to work with the Nexus definition

Additions to SANS event mode processing to allow proper processing of large data streams. Data was inproperly saved after decimation without correcting for the decimation. Instead, use decimation for screening, and bin the full data (splits) on the fly.

File size: 26.5 KB
Line 
1#pragma rtGlobals=3             // Use modern global access method and strict wave access.
2
3//
4// The base functions for R/W from HDF5 files.
5// All of the specific "get" and "write" functions call these base functions which are responsible
6// for all of the open/close mechanics.
7//
8// These VSANS file-specific functions are in:
9// V_HDF5_Read.ipf
10//               and
11// V_HDF5_Write.ipf
12//
13
14// data is read into:
15//      NewDataFolder/O/S root:Packages:NIST:VSANS:RawVSANS
16// so that the data folders of the raw data won't be lying around on the top level, looking like
17// 1D data sets and interfering.
18
19
20// the base data folder path where the raw data is loaded
21Strconstant ksBaseDFPath = "root:Packages:NIST:VSANS:RawVSANS:"
22
23
24// passing null file string presents a dialog
25Macro LoadFakeDIVData()
26        V_LoadHDF5Data("","DIV")
27End
28
29// passing null file string presents a dialog
30Proc Read_HDF5_Raw_No_Attributes()
31        V_LoadHDF5Data("","RAW")
32End
33
34
35// TODO:
36//  x- move the initialization of the raw data folder to be in the as-yet unwritten initialization routine for
37// reduction. be sure that it's duplicated in the VCALC initialization too.
38// -- as needed, get rid of the FAKE redimension of the data from 3D->2D and from 128x128 to something else for VSANS
39//    This is a fake since I don't have anything close to correct fake data yet. (1/29/16)
40//
41// TODO: -- is there an extra "entry" heading? Am I adding this by mistake by setting base_name="entry" for RAW data?
42//                      -- as dumb as it is -- do I just leave it now, or break everything. On the plus side, removing the extra "entry"
43//          layer may catch a lot of the hard-wired junk that is present...
44Function V_LoadHDF5Data(file,folder)
45        String file,folder
46
47        String base_name,detStr
48        String destPath
49        Variable ii
50       
51        SetDataFolder $("root:Packages:NIST:VSANS:"+folder)
52        destPath = "root:Packages:NIST:VSANS:"+folder
53
54        if(cmpstr(folder,"RAW")==0)
55                base_name="entry"
56//              base_name="RAW"         // this acts as a flag to remove the duplicate "entry" level
57        else
58        // null will use the file name as the top level (above entry)
59                base_name=""            //TODO -- remove this / change behavior in V_LoadHDF5_NoAtt()
60        endif
61       
62        Variable err= V_LoadHDF5_NoAtt(file,base_name)  // reads into current folder
63       
64        // if RAW data, then generate the errors and linear data copy
65        // do this 9x
66        // then do any "massaging" needed to redimension, fake values, etc.
67        //
68        string tmpStr = "root:Packages:NIST:VSANS:RAW:entry:entry:instrument:"
69
70        if(cmpstr(folder,"RAW")==0)
71       
72                // TODO -- once I get "real" data, get rid of this call to force the data to be proper dimensions.
73                V_RedimFakeData()
74
75                // makes data error and linear copy -- DP waves if V_RedimFakeData() called above
76                for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
77                        detStr = StringFromList(ii, ksDetectorListAll, ";")
78                        V_MakeDataError(tmpStr+"detector_"+detStr)     
79                endfor
80
81
82                // TODO -- for the "real" data, may need a step in here to convert integer detector data to DP, or I'll
83                //          get really odd results from the calculations, and may not even notice.
84                // !!!! Where do I actually do this? - this is currently done in Raw_to_work()
85                // -- is is better to do here, right as the data is loaded?
86                // TODO -- some of this is done in V_RedimFakeData() above - which will disappear once I get real data
87
88       
89                // TODO
90                //  -- get rid of these fake calibration waves as "real" ones are filled in by NICE
91               
92                Execute "MakeFakeCalibrationWaves()"
93               
94                //              fMakeFakeCalibrationWaves()             //skips the alert
95
96
97                // TODO -- do I want to calculate the nonlinear x/y arrays and the q-values here?
98                // -- otherwise the mouse-over doesn't calculate the correct Q_values
99                // the display currently is not shifted or altered at all to account for the non-linearity
100                // or for display in q-values -- so why bother with this?
101                NVAR gDoNonLinearCor = root:Packages:NIST:VSANS:Globals:gDoNonLinearCor
102                // generate a distance matrix for each of the detectors
103                if (gDoNonLinearCor == 1)
104                        Print "Calculating Non-linear correction at RAW load time"// for "+ detStr
105                        for(ii=0;ii<ItemsInList(ksDetectorListNoB);ii+=1)
106                                detStr = StringFromList(ii, ksDetectorListNoB, ";")
107                                Wave w = V_getDetectorDataW(folder,detStr)
108        //                      Wave w_err = V_getDetectorDataErrW(fname,detStr)
109                                Wave w_calib = V_getDetTube_spatialCalib(folder,detStr)
110                                Variable tube_width = V_getDet_tubeWidth(folder,detStr)
111                                NonLinearCorrection(w,w_calib,tube_width,detStr,destPath)
112                               
113                               
114                                //(2.4) Convert the beam center values from pixels to mm
115                                // TODO -- there needs to be a permanent location for these values??
116                                //
117                                ConvertBeamCtr_to_mm(folder,detStr,destPath)
118                               
119                                // (2.5) Calculate the q-values
120                                // calculating q-values can't be done unless the non-linear corrections are calculated
121                                // so go ahead and put it in this loop.
122                                // TODO :
123                                // -- make sure that everything is present before the calculation
124                                // -- beam center must be properly defined in terms of real distance
125                                // -- distances/zero location/ etc. must be clearly documented for each detector
126                                //      ** this assumes that NonLinearCorrection() has been run to generate data_RealDistX and Y
127                                // ** this routine Makes the waves QTot, qx, qy, qz in each detector folder.
128                                //
129                                V_Detector_CalcQVals(folder,detStr,destPath)
130                               
131                        endfor
132                       
133                        //"B" is separate
134                        NonLinearCorrection_B(folder,"B",destPath)
135                        ConvertBeamCtr_to_mmB(folder,"B",destPath)
136                        V_Detector_CalcQVals(folder,"B",destPath)
137                       
138                else
139                        Print "Non-linear correction not done"
140                endif
141                                       
142                                       
143                /// END FAKE DATA CORRECTIONS           
144                       
145        endif
146       
147        SetDataFolder root:
148        return(err)
149End
150
151//
152// TODO -- this is all FAKED since all the data arrays are written to hdf as (1,128,128)
153//  -- try to fill in the bits from VCALC, if it exists (or force it)
154//
155// the SetScale parts may be useful later.
156//
157Function V_RedimFakeData()
158       
159        // check for fake data in VCALC folder...
160        wave/Z tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_B:det_B"
161        if(WaveExists(tmpw) == 0)
162                Execute "VCALC_Panel()"
163        endif
164       
165        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_B
166        Wave det_B=data
167//      Redimension/N=(150,150)/E=1 det_B       
168        Redimension/D det_B
169        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_B:det_B"
170//      det_B=tmpw
171//      det_B += 2
172        Wave distance=distance
173        distance = VCALC_getSDD("B")*100                // to convert m to cm
174
175                       
176        Variable ctr=20,npix=128
177        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_MT
178        Wave det_MT=data
179//      Redimension/N=(npix,48)/E=1 det_MT
180        Redimension/D det_MT           
181        SetScale/I x -npix/2,npix/2,"",det_MT
182        SetScale/I y ctr,ctr+48,"",det_MT
183//      det_MT *= 10
184//      det_MT += 2
185        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_MT:det_MT"
186//      det_MT=tmpw
187//      det_MT += 2
188        Wave distance=distance
189        distance = VCALC_getSDD("MT")*100               // to convert m to cm
190
191       
192        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_MB
193        Wave det_MB=data
194//      Redimension/N=(npix,48)/E=1 det_MB             
195        Redimension/D det_MB
196        SetScale/I x -npix/2,npix/2,"",det_MB
197        SetScale/I y -ctr-48,-ctr,"",det_MB
198//      det_MB *= 5
199//      det_MB += 2
200        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_MB:det_MB"
201//      det_MB=tmpw
202//      det_MB += 2
203        Wave distance=distance
204        distance = VCALC_getSDD("MB")*100               // to convert m to cm
205
206       
207        ctr=30
208        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_ML
209        Wave det_ML=data
210//      Redimension/N=(48,npix)/E=1 det_ML             
211        Redimension/D det_ML
212        SetScale/I x -ctr-48,-ctr,"",det_ML
213        SetScale/I y -npix/2,npix/2,"",det_ML
214//      det_ML *= 2
215//      det_ML += 2
216        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_ML:det_ML"
217//      det_ML=tmpw
218//      det_ML += 2
219        Wave distance=distance
220        distance = VCALC_getSDD("ML")*100               // to convert m to cm
221
222               
223        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_MR
224        Wave det_MR=data
225//      Redimension/N=(48,npix)/E=1 det_MR             
226        Redimension/D det_MR
227        SetScale/I x ctr,ctr+48,"",det_MR
228        SetScale/I y -npix/2,npix/2,"",det_MR
229//      det_MR +=2
230        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_MR:det_MR"
231//      det_MR=tmpw
232//      det_MR += 2
233        Wave distance=distance
234        distance = VCALC_getSDD("MR")*100               // to convert m to cm
235       
236       
237        ctr=30
238        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FT
239        Wave det_FT=data
240//      Redimension/N=(npix,48)/E=1 det_FT             
241        Redimension/D det_FT
242        SetScale/I x -npix/2,npix/2,"",det_FT
243        SetScale/I y ctr,ctr+48,"",det_FT
244        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_FT:det_FT"
245//      det_FT=tmpw
246        Wave distance=distance
247        distance = VCALC_getSDD("FT")*100               // to convert m to cm
248
249
250        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FB
251        Wave det_FB=data
252//      Redimension/N=(npix,48)/E=1 det_FB             
253        Redimension/D det_FB
254        SetScale/I x -npix/2,npix/2,"",det_FB
255        SetScale/I y -ctr-48,-ctr,"",det_FB
256        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_FB:det_FB"
257//      det_FB=tmpw
258        Wave distance=distance
259        distance = VCALC_getSDD("FB")*100               // to convert m to cm
260
261                       
262        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FL
263        Wave det_FL=data
264//      Redimension/N=(48,npix)/E=1 det_FL             
265        Redimension/D det_FL
266        SetScale/I x -ctr-48,-ctr,"",det_FL
267        SetScale/I y -npix/2,npix/2,"",det_FL
268        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_FL:det_FL"
269//      det_FL=tmpw
270        Wave distance=distance
271        distance = VCALC_getSDD("FL")*100               // to convert m to cm
272
273       
274        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FR
275        Wave det_FR=data
276//      Redimension/N=(48,npix)/E=1 det_FR             
277        Redimension/D det_FR
278        SetScale/I x ctr,ctr+48,"",det_FR
279        SetScale/I y -npix/2,npix/2,"",det_FR
280        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_FR:det_FR"
281//      det_FR=tmpw
282        Wave distance=distance
283        distance = VCALC_getSDD("FR")*100               // to convert m to cm
284
285       
286// get rid of zeros
287//      det_FL += 2
288//      det_FR += 2
289//      det_FT += 2
290//      det_FB += 2
291
292
293// fake beam center values
294        V_putDet_beam_center_x("RAW","B",75)
295        V_putDet_beam_center_y("RAW","B",75)
296
297
298        V_putDet_beam_center_x("RAW","MB",64)
299        V_putDet_beam_center_y("RAW","MB",55)
300        V_putDet_beam_center_x("RAW","MT",64)
301        V_putDet_beam_center_y("RAW","MT",-8.7)
302        V_putDet_beam_center_x("RAW","MR",-8.1)
303        V_putDet_beam_center_y("RAW","MR",64)
304        V_putDet_beam_center_x("RAW","ML",55)
305        V_putDet_beam_center_y("RAW","ML",64)
306
307        V_putDet_beam_center_x("RAW","FB",64)
308        V_putDet_beam_center_y("RAW","FB",55)
309        V_putDet_beam_center_x("RAW","FT",64)
310        V_putDet_beam_center_y("RAW","FT",-8.7)
311        V_putDet_beam_center_x("RAW","FR",-8.1)
312        V_putDet_beam_center_y("RAW","FR",64)
313        V_putDet_beam_center_x("RAW","FL",55)
314        V_putDet_beam_center_y("RAW","FL",64)
315
316
317
318
319
320
321        V_RescaleToBeamCenter("RAW","MB",64,55)
322        V_RescaleToBeamCenter("RAW","MT",64,-8.7)
323        V_RescaleToBeamCenter("RAW","MR",-8.1,64)
324        V_RescaleToBeamCenter("RAW","ML",55,64)
325        V_RescaleToBeamCenter("RAW","FL",55,64)
326        V_RescaleToBeamCenter("RAW","FR",-8.1,64)
327        V_RescaleToBeamCenter("RAW","FT",64,-8.7)
328        V_RescaleToBeamCenter("RAW","FB",64,55)
329
330
331
332        return(0)
333End
334
335
336// This loads for speed, since loading the attributes takes a LOT of time.
337//
338// this will load in the whole HDF file all at once.
339// Attributes are NOT loaded at all.
340//
341// -- the Gateway function H5GW_ReadHDF5(parentFolder, fileName, [hdf5Path])
342//    reads in the attributes too, but is very slow
343//   -- the H5GW function is called by: H_HDF5Gate_Read_Raw(file)
344//
345// TODO:
346// -x remove the P=home restriction top make this more generic (replaced with catPathName from PickPath)
347// -- get rid of bits leftover here that I don't need
348// -- be sure I'm using all of the correct flags in the HDF5LoadGroup operation
349// -- settle on how the base_name is to be used. "entry" for the RAW, fileName for the "rawVSANS"?
350// x- error check for path existence
351//
352// passing in "" for base_name will take the name from the file name as selected
353//
354Function V_LoadHDF5_NoAtt(fileName,base_name)
355        String fileName, base_name
356       
357//      if ( ParamIsDefault(hdf5Path) )
358//              hdf5Path = "/"
359//      endif
360
361        PathInfo/S catPathName
362        if(V_flag == 0)
363                V_PickPath()
364        endif
365
366        String hdf5path = "/"           //always read from the top
367        String status = ""
368
369        Variable fileID = 0
370//      HDF5OpenFile/R/P=home/Z fileID as fileName              //read file from home directory?
371        HDF5OpenFile/R/P=catPathName/Z fileID as fileName
372        if (V_Flag != 0)
373                return 0
374        endif
375
376        String/G root:file_path = S_path
377        String/G root:file_name = S_FileName
378       
379        if ( fileID == 0 )
380                Print fileName + ": could not open as HDF5 file"
381                return (0)
382        endif
383       
384//s_tic()               //fast
385       
386        SVAR tmpStr=root:file_name
387        fileName=tmpStr         //SRK - in case the file was chosen from a dialog, I'll need access to the name later
388       
389        //   read the data (too bad that HDF5LoadGroup does not read the attributes)
390        if(cmpstr(base_name,"") == 0)
391                base_name = StringFromList(0,FileName,".")
392        endif
393        if(cmpstr(base_name,"RAW") == 0)
394                base_name = ""
395        endif
396        //base_name = "entry"
397       
398        HDF5LoadGroup/Z/L=7/O/R/T=$base_name  :, fileID, hdf5Path               //      recursive
399        if ( V_Flag != 0 )
400                Print fileName + ": could not open as HDF5 file"
401                setdatafolder root:
402                return (0)
403        endif
404
405        HDF5CloseFile fileID
406       
407//s_toc()
408        return(0)
409end     
410
411
412// read a single real value
413// - fname passed in is the full path to the file on disk
414// - path is the path to the value in the HDF tree
415//
416// check to see if the value exists (It will be a wave)
417// -- if it does, return the value from the local folder
418// -- if not, read the file in, then return the value
419//
420// TODO:
421// currently, the work folders have the following path - so passing in "RAW" as fname
422// will take some re-configuring.
423//  root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FL:distance
424// -- be sure this read from work folders is not broken in the future, and is passed to ALL of the
425//    top-level R/W routines. (Write is necessary ONLY for SIM data files. Patch is direct to disk.)
426Function V_getRealValueFromHDF5(fname,path)
427        String fname,path
428
429        String folderStr=""
430        Variable valExists=0
431       
432        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
433
434// check for a work folder first (note that "entry" is doubled)
435        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
436                Wave/Z w = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
437                return(w[0])
438        endif
439       
440        if(Exists(ksBaseDFPath+folderStr+":"+path))
441                valExists=1
442        endif
443       
444        if(!valExists)
445                //then read in the file
446                V_LoadHDF5_NoAtt(fname,"")
447        endif
448
449// this should exist now - if not, I need to see the error
450        Wave/Z w = $(ksBaseDFPath+folderStr+":"+path)
451       
452        if(WaveExists(w))
453                return(w[0])
454        else
455                return(-999999)
456        endif   
457End
458
459// Returns a wave reference, not just a single value
460// ---then you pick what you need from the wave
461//
462// - fname passed in is the full path to the file on disk
463// - path is the path to the value in the HDF tree
464//
465// check to see if the value exists (It will be a wave)
466// -- if it does, return the value from the local folder
467// -- if not, read the file in, then return the value
468//
469Function/WAVE V_getRealWaveFromHDF5(fname,path)
470        String fname,path
471
472        String folderStr=""
473        Variable valExists=0
474       
475        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
476
477// check for a work folder first (note that "entry" is doubled)
478        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
479                Wave wOut = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
480                return wOut
481        endif
482               
483        if(Exists(ksBaseDFPath+folderStr+":"+path))
484                valExists=1
485        endif
486       
487        if(!valExists)
488                //then read in the file
489                V_LoadHDF5_NoAtt(fname,"")
490        endif
491
492// this should exist now - if not, I need to see the error
493        Wave wOut = $(ksBaseDFPath+folderStr+":"+path)
494       
495        return wOut
496       
497End
498
499// Returns a wave reference, not just a single value
500// ---then you pick what you need from the wave
501//
502// - fname passed in is the full path to the file on disk
503// - path is the path to the value in the HDF tree
504//
505// check to see if the value exists (It will be a wave)
506// -- if it does, return the value from the local folder
507// -- if not, read the file in, then return the value
508//
509Function/WAVE V_getTextWaveFromHDF5(fname,path)
510        String fname,path
511
512        String folderStr=""
513        Variable valExists=0
514       
515        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
516
517// check for a work folder first (note that "entry" is doubled)
518        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
519                Wave/T wOut = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
520                return wOut
521        endif
522       
523        if(Exists(ksBaseDFPath+folderStr+":"+path))
524                valExists=1
525        endif
526       
527        if(!valExists)
528                //then read in the file
529                V_LoadHDF5_NoAtt(fname,"")
530        endif
531
532// this should exist now - if not, I need to see the error
533        Wave/T wOut = $(ksBaseDFPath+folderStr+":"+path)
534       
535        return wOut
536       
537End
538
539
540//
541//   TODO
542// depricated? in HDF5 - store all of the values as real?
543// Igor sees no difference in real and integer variables (waves are different)
544// BUT-- Igor 7 will have integer variables
545//
546// truncate to integer before returning??
547//
548//  TODO
549// write a "getIntegerWave" function??
550//
551//////  integer values
552// reads 32 bit integer
553Function V_getIntegerFromHDF5(fname,path)
554        String fname                            //full path+name
555        String path                             //path to the hdf5 location
556       
557        Variable val = V_getRealValueFromHDF5(fname,path)
558       
559        val = round(val)
560        return(val)
561End
562
563
564// read a single string
565// - fname passed in is the full path to the file on disk
566// - path is the path to the value in the HDF tree
567// - num is the number of characters in the VAX string
568// check to see if the value exists (It will be a wave)
569// -- if it does, return the value from the local folder
570// -- if not, read the file in, then return the value
571//
572// TODO -- string could be checked for length, but returned right or wrong
573//
574// -- currently num is completely ignored
575//
576Function/S V_getStringFromHDF5(fname,path,num)
577        String fname,path
578        Variable num
579
580        String folderStr=""
581        Variable valExists=0
582       
583        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
584
585// check for a work folder first (note that "entry" is doubled)
586        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
587                Wave/Z/T tw = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
588                return(tw[0])
589        endif
590       
591        if(Exists(ksBaseDFPath+folderStr+":"+path))
592                valExists=1
593        endif
594       
595        if(!valExists)
596                //then read in the file
597                V_LoadHDF5_NoAtt(fname,"")
598        endif
599
600// this should exist now - if not, I need to see the error
601        Wave/T/Z tw = $(ksBaseDFPath+folderStr+":"+path)
602       
603        if(WaveExists(tw))
604       
605        //      if(strlen(tw[0]) != num)
606        //              Print "string is not the specified length"
607        //      endif
608               
609                return(tw[0])
610        else
611                return("The specified wave does not exist: " + path)
612        endif
613End
614
615
616
617///////////////////////////////
618
619//
620//Write Wave 'wav' to hdf5 file 'fname'
621//Based on code from ANSTO (N. Hauser. nha 8/1/09)
622//
623// TODO:
624// -- figure out if this will write in the native format of the
625//     wave as passed in, or if it will only write as DP.
626// -- do I need to write separate functions for real, integer, etc.?
627// -- the lines to create a missing group have been commented out to avoid filling
628//    in missing fields that should have been generated by the data writer. Need to make
629//    a separate function that will write and generate if needed, and use this in specific cases
630//    only if I really have to force it.
631//
632// --Attributes are not currently saved. Fix this, maybe make it optional? See the help file for
633//  DemoAttributes(w) example under the HDF5SaveData operation
634//     
635// -x change the /P=home to the user-defined data path (catPathName)           
636//
637Function V_WriteWaveToHDF(fname, groupName, varName, wav)
638        String fname, groupName, varName
639        Wave wav
640       
641        variable err=0, fileID,groupID
642        String cDF = getDataFolder(1), temp
643        String NXentry_name
644       
645        try     
646                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
647                if(!fileID)
648                        err = 1
649                        abort "HDF5 file does not exist"
650                endif
651               
652                //get the NXentry node name
653                HDF5ListGroup /TYPE=1 fileID, "/"
654                //remove trailing ; from S_HDF5ListGroup
655               
656                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
657               
658                NXentry_name = S_HDF5ListGroup
659                NXentry_name = ReplaceString(";",NXentry_name,"")
660                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
661                        err = 1
662                        abort "More than one entry under the root node. Ambiguous"
663                endif
664                //concatenate NXentry node name and groupName   
665                // SRK - NOV2015 - dropped this and require the full group name passed in
666//              groupName = "/" + NXentry_name + groupName
667                Print "groupName = ",groupName
668                HDF5OpenGroup /Z fileID , groupName, groupID
669
670                if(!groupID)
671                // don't create the group if the name isn't right -- throw up an error
672                        //HDF5CreateGroup /Z fileID, groupName, groupID
673                        err = 1
674                        HDF5CloseFile /Z fileID
675                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
676                        return(err)
677                else
678                        // get attributes and save them
679                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
680                        //Wave attributes = S_HDF5ListAttributes
681                endif
682       
683                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
684                if (V_flag != 0)
685                        err = 1
686                        abort "Cannot save wave to HDF5 dataset " + varName
687                endif   
688               
689               
690                //attributes - something could be added here as optional parameters and flagged
691//              String attributes = "units"
692//              Make/O/T/N=1 tmp
693//              tmp[0] = "dimensionless"
694//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
695//              if (V_flag != 0)
696//                      err = 1
697//                      abort "Cannot save attributes to HDF5 dataset"
698//              endif   
699        catch
700
701        endtry
702
703// it is not necessary to close the group here. HDF5CloseFile will close the group as well     
704        if(groupID)
705                HDF5CloseGroup /Z groupID
706        endif
707       
708        if(fileID)
709                HDF5CloseFile /Z fileID
710        endif
711
712        setDataFolder $cDF
713        return err
714end
715
716//Write Wave 'wav' to hdf5 file 'fname'
717//Based on code from ANSTO (N. Hauser. nha 8/1/09)
718//
719// TODO
720//
721// -x change the /P=home to the user-defined data path (catPathName)           
722//
723Function V_WriteTextWaveToHDF(fname, groupName, varName, wav)
724        String fname, groupName, varName
725        Wave/T wav
726       
727        variable err=0, fileID,groupID
728        String cDF = getDataFolder(1), temp
729        String NXentry_name
730       
731        try     
732                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
733                if(!fileID)
734                        err = 1
735                        abort "HDF5 file does not exist"
736                endif
737               
738                //get the NXentry node name
739                HDF5ListGroup /TYPE=1 fileID, "/"
740                //remove trailing ; from S_HDF5ListGroup
741               
742                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
743               
744                NXentry_name = S_HDF5ListGroup
745                NXentry_name = ReplaceString(";",NXentry_name,"")
746                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
747                        err = 1
748                        abort "More than one entry under the root node. Ambiguous"
749                endif
750
751                //concatenate NXentry node name and groupName
752                // SRK - NOV2015 - dropped this and require the full group name passed in
753//              groupName = "/" + NXentry_name + groupName
754                Print "groupName = ",groupName
755
756                HDF5OpenGroup /Z fileID , groupName, groupID
757
758                if(!groupID)
759                // don't create the group it the name isn't right -- throw up an error
760                        //HDF5CreateGroup /Z fileID, groupName, groupID
761                        err = 1
762                        HDF5CloseFile /Z fileID
763                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
764                        return(err)
765                else
766                        // get attributes and save them
767                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
768                        //Wave attributes = S_HDF5ListAttributes
769                endif
770       
771                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
772                if (V_flag != 0)
773                        err = 1
774                        abort "Cannot save wave to HDF5 dataset " + varName
775                endif   
776               
777               
778                //attributes - something could be added here as optional parameters and flagged
779//              String attributes = "units"
780//              Make/O/T/N=1 tmp
781//              tmp[0] = "dimensionless"
782//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
783//              if (V_flag != 0)
784//                      err = 1
785//                      abort "Cannot save attributes to HDF5 dataset"
786//              endif   
787        catch
788
789        endtry
790       
791        if(groupID)
792                HDF5CloseGroup /Z groupID
793        endif
794       
795        if(fileID)
796                HDF5CloseFile /Z fileID
797        endif
798
799        setDataFolder $cDF
800        return err
801end
802
803//////////////////////////////
804//////////////////////////////
805//////////////////////////////
806
807
808
809
810//////// function to take VCALC information and
811// fill in the simulated information as needed to make a "fake" data file
812//
813// TODO:
814// -- identify all of the necessary bits to change
815// -- maybe want a panel to make it easier to decide what inputs to change in the file
816// -- decide if it's better to write wholesale, or as individual waves
817//
818Macro Copy_VCALC_to_VSANSFile()
819       
820        String fileName = V_DoSaveFileDialog("pick the file to write to")
821        print fileName
822//     
823        if(strlen(fileName) > 0)
824                writeVCALC_to_file(fileName)
825        endif
826End
827
828//
829// TODO -- fill this in as needed to get fake data that's different
830//
831Function writeVCALC_to_file(fileName)
832        String fileName
833
834
835// the detectors, all 9 + the correct SDD (that accounts for the offset of T/B panels
836// the data itself (as INT32)
837// the front SDD (correct units)
838// the middle SDD (correct units)
839// the back SDD (correct units)
840        Variable ii,val
841        String detStr
842        for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
843                detStr = StringFromList(ii, ksDetectorListAll, ";")
844                Duplicate/O $("root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_"+detStr+":det_"+detStr) tmpData
845                Redimension/I tmpData
846                tmpData = (tmpData ==   2147483647) ? 0 : tmpData               //the NaN "mask" in the sim data (T/B only)shows up as an ugly integer
847                V_writeDetectorData(fileName,detStr,tmpData)
848               
849                val = VCALC_getTopBottomSDDOffset(detStr)/10 + VCALC_getSDD(detStr)*100         // make sure value is in cm
850                print val
851                V_writeDet_distance(fileName,detStr,val)
852               
853// x and y pixel sizes for each detector
854//Function VCALC_getPixSizeX(type)              // returns the pixel X size, in [cm]
855//Function VCALC_getPixSizeY(type)
856        V_writeDet_x_pixel_size(fileName,detStr,VCALC_getPixSizeX(detStr)*10)           // data file is expecting mm
857        V_writeDet_y_pixel_size(fileName,detStr,VCALC_getPixSizeY(detStr)*10)
858       
859// the calibration data for each detector
860//V_writeDetTube_spatialCalib(fname,detStr,inW)
861// and for "B"
862//V_writeDet_cal_x(fname,detStr,inW)
863//V_writeDet_cal_y(fname,detStr,inW)
864
865// the dead time for each detector
866// V_writeDetector_deadtime(fname,detStr,inW)
867// TODO: need a new, separate function to write the single deadtime value in/out of "B"
868
869        endfor
870       
871
872
873
874//? other detector geometry - lateral separation?
875
876// the wavelength
877//      Variable lam = V_getWavelength("VCALC")         //doesn't work, the corresponding folder in VCALC has not been defined
878        V_writeWavelength(fileName,VCALC_getWavelength())
879
880// description of the sample
881
882// sample information
883// name, title, etc
884       
885// fake the information about the count setup, so I have different numbers to read
886// count time = fake
887
888// monitor count (= imon)
889// returns the number of neutrons on the sample
890//Function VCALC_getImon()
891
892// ?? anything else that I'd like to see on the catalog - I could change them here to see different values
893// different collimation types?
894//
895
896        return(0)
897end
898
899
900
901
Note: See TracBrowser for help on using the repository browser.