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

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

changes to the writer to put fake VCALC information into a Nexus file so that it can be used as a fake dataset, one with different detector data, instrument configuration, etc. since NICE currently does not populate many fields.

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//
574Function/S V_getStringFromHDF5(fname,path,num)
575        String fname,path
576        Variable num
577
578        String folderStr=""
579        Variable valExists=0
580       
581        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
582
583// check for a work folder first (note that "entry" is doubled)
584        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
585                Wave/Z/T tw = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
586                return(tw[0])
587        endif
588       
589        if(Exists(ksBaseDFPath+folderStr+":"+path))
590                valExists=1
591        endif
592       
593        if(!valExists)
594                //then read in the file
595                V_LoadHDF5_NoAtt(fname,"")
596        endif
597
598// this should exist now - if not, I need to see the error
599        Wave/T/Z tw = $(ksBaseDFPath+folderStr+":"+path)
600       
601        if(WaveExists(tw))
602       
603        //      if(strlen(tw[0]) != num)
604        //              Print "string is not the specified length"
605        //      endif
606               
607                return(tw[0])
608        else
609                return("The specified wave does not exist: " + path)
610        endif
611End
612
613
614
615///////////////////////////////
616
617//
618//Write Wave 'wav' to hdf5 file 'fname'
619//Based on code from ANSTO (N. Hauser. nha 8/1/09)
620//
621// TODO:
622// -- figure out if this will write in the native format of the
623//     wave as passed in, or if it will only write as DP.
624// -- do I need to write separate functions for real, integer, etc.?
625// -- the lines to create a missing group have been commented out to avoid filling
626//    in missing fields that should have been generated by the data writer. Need to make
627//    a separate function that will write and generate if needed, and use this in specific cases
628//    only if I really have to force it.
629//
630// --Attributes are not currently saved. Fix this, maybe make it optional? See the help file for
631//  DemoAttributes(w) example under the HDF5SaveData operation
632//     
633// -x change the /P=home to the user-defined data path (catPathName)           
634//
635Function V_WriteWaveToHDF(fname, groupName, varName, wav)
636        String fname, groupName, varName
637        Wave wav
638       
639        variable err=0, fileID,groupID
640        String cDF = getDataFolder(1), temp
641        String NXentry_name
642       
643        try     
644                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
645                if(!fileID)
646                        err = 1
647                        abort "HDF5 file does not exist"
648                endif
649               
650                //get the NXentry node name
651                HDF5ListGroup /TYPE=1 fileID, "/"
652                //remove trailing ; from S_HDF5ListGroup
653               
654                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
655               
656                NXentry_name = S_HDF5ListGroup
657                NXentry_name = ReplaceString(";",NXentry_name,"")
658                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
659                        err = 1
660                        abort "More than one entry under the root node. Ambiguous"
661                endif
662                //concatenate NXentry node name and groupName   
663                // SRK - NOV2015 - dropped this and require the full group name passed in
664//              groupName = "/" + NXentry_name + groupName
665                Print "groupName = ",groupName
666                HDF5OpenGroup /Z fileID , groupName, groupID
667
668                if(!groupID)
669                // don't create the group if the name isn't right -- throw up an error
670                        //HDF5CreateGroup /Z fileID, groupName, groupID
671                        err = 1
672                        HDF5CloseFile /Z fileID
673                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
674                        return(err)
675                else
676                        // get attributes and save them
677                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
678                        //Wave attributes = S_HDF5ListAttributes
679                endif
680       
681                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
682                if (V_flag != 0)
683                        err = 1
684                        abort "Cannot save wave to HDF5 dataset " + varName
685                endif   
686               
687               
688                //attributes - something could be added here as optional parameters and flagged
689//              String attributes = "units"
690//              Make/O/T/N=1 tmp
691//              tmp[0] = "dimensionless"
692//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
693//              if (V_flag != 0)
694//                      err = 1
695//                      abort "Cannot save attributes to HDF5 dataset"
696//              endif   
697        catch
698
699        endtry
700
701// it is not necessary to close the group here. HDF5CloseFile will close the group as well     
702        if(groupID)
703                HDF5CloseGroup /Z groupID
704        endif
705       
706        if(fileID)
707                HDF5CloseFile /Z fileID
708        endif
709
710        setDataFolder $cDF
711        return err
712end
713
714//Write Wave 'wav' to hdf5 file 'fname'
715//Based on code from ANSTO (N. Hauser. nha 8/1/09)
716//
717// TODO
718//
719// -x change the /P=home to the user-defined data path (catPathName)           
720//
721Function V_WriteTextWaveToHDF(fname, groupName, varName, wav)
722        String fname, groupName, varName
723        Wave/T wav
724       
725        variable err=0, fileID,groupID
726        String cDF = getDataFolder(1), temp
727        String NXentry_name
728       
729        try     
730                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
731                if(!fileID)
732                        err = 1
733                        abort "HDF5 file does not exist"
734                endif
735               
736                //get the NXentry node name
737                HDF5ListGroup /TYPE=1 fileID, "/"
738                //remove trailing ; from S_HDF5ListGroup
739               
740                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
741               
742                NXentry_name = S_HDF5ListGroup
743                NXentry_name = ReplaceString(";",NXentry_name,"")
744                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
745                        err = 1
746                        abort "More than one entry under the root node. Ambiguous"
747                endif
748
749                //concatenate NXentry node name and groupName
750                // SRK - NOV2015 - dropped this and require the full group name passed in
751//              groupName = "/" + NXentry_name + groupName
752                Print "groupName = ",groupName
753
754                HDF5OpenGroup /Z fileID , groupName, groupID
755
756                if(!groupID)
757                // don't create the group it the name isn't right -- throw up an error
758                        //HDF5CreateGroup /Z fileID, groupName, groupID
759                        err = 1
760                        HDF5CloseFile /Z fileID
761                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
762                        return(err)
763                else
764                        // get attributes and save them
765                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
766                        //Wave attributes = S_HDF5ListAttributes
767                endif
768       
769                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
770                if (V_flag != 0)
771                        err = 1
772                        abort "Cannot save wave to HDF5 dataset " + varName
773                endif   
774               
775               
776                //attributes - something could be added here as optional parameters and flagged
777//              String attributes = "units"
778//              Make/O/T/N=1 tmp
779//              tmp[0] = "dimensionless"
780//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
781//              if (V_flag != 0)
782//                      err = 1
783//                      abort "Cannot save attributes to HDF5 dataset"
784//              endif   
785        catch
786
787        endtry
788       
789        if(groupID)
790                HDF5CloseGroup /Z groupID
791        endif
792       
793        if(fileID)
794                HDF5CloseFile /Z fileID
795        endif
796
797        setDataFolder $cDF
798        return err
799end
800
801//////////////////////////////
802//////////////////////////////
803//////////////////////////////
804
805
806
807
808//////// function to take VCALC information and
809// fill in the simulated information as needed to make a "fake" data file
810//
811// TODO:
812// -- identify all of the necessary bits to change
813// -- maybe want a panel to make it easier to decide what inputs to change in the file
814// -- decide if it's better to write wholesale, or as individual waves
815//
816Macro Copy_VCALC_to_VSANSFile()
817       
818        String fileName = V_DoSaveFileDialog("pick the file to write to")
819        print fileName
820//     
821        if(strlen(fileName) > 0)
822                writeVCALC_to_file(fileName)
823        endif
824End
825
826//
827// TODO -- fill this in as needed to get fake data that's different
828//
829Function writeVCALC_to_file(fileName)
830        String fileName
831
832
833// the detectors, all 9 + the correct SDD (that accounts for the offset of T/B panels
834// the data itself (as INT32)
835// the front SDD (correct units)
836// the middle SDD (correct units)
837// the back SDD (correct units)
838        Variable ii,val
839        String detStr
840        for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
841                detStr = StringFromList(ii, ksDetectorListAll, ";")
842                Duplicate/O $("root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_"+detStr+":det_"+detStr) tmpData
843                Redimension/I tmpData
844                tmpData = (tmpData ==   2147483647) ? 0 : tmpData               //the NaN "mask" in the sim data (T/B only)shows up as an ugly integer
845                V_writeDetectorData(fileName,detStr,tmpData)
846               
847                val = VCALC_getTopBottomSDDOffset(detStr)/10 + VCALC_getSDD(detStr)*100         // make sure value is in cm
848                print val
849                V_writeDet_distance(fileName,detStr,val)
850               
851// x and y pixel sizes for each detector
852//Function VCALC_getPixSizeX(type)              // returns the pixel X size, in [cm]
853//Function VCALC_getPixSizeY(type)
854        V_writeDet_x_pixel_size(fileName,detStr,VCALC_getPixSizeX(detStr)*10)           // data file is expecting mm
855        V_writeDet_y_pixel_size(fileName,detStr,VCALC_getPixSizeY(detStr)*10)
856       
857// the calibration data for each detector
858//V_writeDetTube_spatialCalib(fname,detStr,inW)
859// and for "B"
860//V_writeDet_cal_x(fname,detStr,inW)
861//V_writeDet_cal_y(fname,detStr,inW)
862
863// the dead time for each detector
864// V_writeDetector_deadtime(fname,detStr,inW)
865// TODO: need a new, separate function to write the single deadtime value in/out of "B"
866
867        endfor
868       
869
870
871
872//? other detector geometry - lateral separation?
873
874// the wavelength
875//      Variable lam = V_getWavelength("VCALC")         //doesn't work, the corresponding folder in VCALC has not been defined
876        V_writeWavelength(fileName,VCALC_getWavelength())
877
878// description of the sample
879
880// sample information
881// name, title, etc
882       
883// fake the information about the count setup, so I have different numbers to read
884// count time = fake
885
886// monitor count (= imon)
887// returns the number of neutrons on the sample
888//Function VCALC_getImon()
889
890// ?? anything else that I'd like to see on the catalog - I could change them here to see different values
891// different collimation types?
892//
893
894        return(0)
895end
896
897
898
899
Note: See TracBrowser for help on using the repository browser.