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

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

removed the doubled "entry" field from the VSANS file load.

appears now to work fine with R/W routines and with VCALC.

File size: 27.8 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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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 now NOT doubled)
435        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
436                Wave/Z w = $("root:Packages:NIST:VSANS:"+folderStr+":"+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, putting the data in RawVSANS
446                SetDataFolder ksBaseDFPath
447                V_LoadHDF5_NoAtt(fname,"")
448                SetDataFolder root:
449        endif
450
451// this should exist now - if not, I need to see the error
452        Wave/Z w = $(ksBaseDFPath+folderStr+":"+path)
453       
454        if(WaveExists(w))
455                return(w[0])
456        else
457                return(-999999)
458        endif   
459End
460
461// Returns a wave reference, not just a single value
462// ---then you pick what you need from the wave
463//
464// - fname passed in is the full path to the file on disk
465// - path is the path to the value in the HDF tree
466//
467// check to see if the value exists (It will be a wave)
468// -- if it does, return the value from the local folder
469// -- if not, read the file in, then return the value
470//
471Function/WAVE V_getRealWaveFromHDF5(fname,path)
472        String fname,path
473
474        String folderStr=""
475        Variable valExists=0
476       
477        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
478
479// check for a work folder first (note that "entry" is NOT doubled)
480        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
481                Wave wOut = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
482                return wOut
483        endif
484               
485        if(Exists(ksBaseDFPath+folderStr+":"+path))
486                valExists=1
487        endif
488
489        if(!valExists)
490                //then read in the file, putting the data in RawVSANS
491                SetDataFolder ksBaseDFPath
492                V_LoadHDF5_NoAtt(fname,"")
493                SetDataFolder root:
494        endif
495               
496// this should exist now - if not, I need to see the error
497        Wave wOut = $(ksBaseDFPath+folderStr+":"+path)
498       
499        return wOut
500       
501End
502
503// Returns a wave reference, not just a single value
504// ---then you pick what you need from the wave
505//
506// - fname passed in is the full path to the file on disk
507// - path is the path to the value in the HDF tree
508//
509// check to see if the value exists (It will be a wave)
510// -- if it does, return the value from the local folder
511// -- if not, read the file in, then return the value
512//
513Function/WAVE V_getTextWaveFromHDF5(fname,path)
514        String fname,path
515
516        String folderStr=""
517        Variable valExists=0
518       
519        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
520
521// check for a work folder first (note that "entry" is NOT doubled)
522        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
523                Wave/T wOut = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
524                return wOut
525        endif
526       
527        if(Exists(ksBaseDFPath+folderStr+":"+path))
528                valExists=1
529        endif
530       
531        if(!valExists)
532                //then read in the file, putting the data in RawVSANS
533                SetDataFolder ksBaseDFPath
534                V_LoadHDF5_NoAtt(fname,"")
535                SetDataFolder root:
536        endif
537
538// this should exist now - if not, I need to see the error
539        Wave/T wOut = $(ksBaseDFPath+folderStr+":"+path)
540       
541        return wOut
542       
543End
544
545
546//
547//   TODO
548// depricated? in HDF5 - store all of the values as real?
549// Igor sees no difference in real and integer variables (waves are different)
550// BUT-- Igor 7 will have integer variables
551//
552// truncate to integer before returning??
553//
554//  TODO
555// write a "getIntegerWave" function??
556//
557//////  integer values
558// reads 32 bit integer
559Function V_getIntegerFromHDF5(fname,path)
560        String fname                            //full path+name
561        String path                             //path to the hdf5 location
562       
563        Variable val = V_getRealValueFromHDF5(fname,path)
564       
565        val = round(val)
566        return(val)
567End
568
569
570// read a single string
571// - fname passed in is the full path to the file on disk
572// - path is the path to the value in the HDF tree
573// - num is the number of characters in the VAX string
574// check to see if the value exists (It will be a wave)
575// -- if it does, return the value from the local folder
576// -- if not, read the file in, then return the value
577//
578// TODO -- string could be checked for length, but returned right or wrong
579//
580// -- currently num is completely ignored
581//
582Function/S V_getStringFromHDF5(fname,path,num)
583        String fname,path
584        Variable num
585
586        String folderStr=""
587        Variable valExists=0
588       
589        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
590
591// check for a work folder first (note that "entry" is NOT doubled)
592        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":"+path))
593                Wave/Z/T tw = $("root:Packages:NIST:VSANS:"+folderStr+":"+path)
594                return(tw[0])
595        endif
596       
597        if(Exists(ksBaseDFPath+folderStr+":"+path))
598                valExists=1
599        endif
600
601        if(!valExists)
602                //then read in the file, putting the data in RawVSANS
603                SetDataFolder ksBaseDFPath
604                V_LoadHDF5_NoAtt(fname,"")
605                SetDataFolder root:
606        endif
607
608// this should exist now - if not, I need to see the error
609        Wave/T/Z tw = $(ksBaseDFPath+folderStr+":"+path)
610       
611        if(WaveExists(tw))
612       
613        //      if(strlen(tw[0]) != num)
614        //              Print "string is not the specified length"
615        //      endif
616               
617                return(tw[0])
618        else
619                return("The specified wave does not exist: " + path)
620        endif
621End
622
623
624
625///////////////////////////////
626
627//
628//Write Wave 'wav' to hdf5 file 'fname'
629//Based on code from ANSTO (N. Hauser. nha 8/1/09)
630//
631// TODO:
632// -- figure out if this will write in the native format of the
633//     wave as passed in, or if it will only write as DP.
634// -- do I need to write separate functions for real, integer, etc.?
635// -- the lines to create a missing group have been commented out to avoid filling
636//    in missing fields that should have been generated by the data writer. Need to make
637//    a separate function that will write and generate if needed, and use this in specific cases
638//    only if I really have to force it.
639//
640// --Attributes are not currently saved. Fix this, maybe make it optional? See the help file for
641//  DemoAttributes(w) example under the HDF5SaveData operation
642//     
643// -x change the /P=home to the user-defined data path (catPathName)           
644//
645Function V_WriteWaveToHDF(fname, groupName, varName, wav)
646        String fname, groupName, varName
647        Wave wav
648       
649       
650        // try a local folder first, then try to save to disk
651        //
652        String folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
653       
654        String localPath = "root:Packages:NIST:VSANS:"+folderStr//+":entry"
655        localPath += groupName + "/" + varName
656        // make everything colons for local data folders
657        localPath = ReplaceString("/", localPath, ":")
658       
659        Wave/Z w = $localPath
660        if(waveExists(w) == 1)
661                w = wav
662                Print "write to local folder done"
663                return(0)               //we're done, get out
664        endif
665       
666       
667        // if the local wave did not exist, then we proceed to write to disk
668
669       
670        variable err=0, fileID,groupID
671        String cDF = getDataFolder(1), temp
672        String NXentry_name
673       
674        try     
675                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
676                if(!fileID)
677                        err = 1
678                        abort "HDF5 file does not exist"
679                endif
680               
681                //get the NXentry node name
682                HDF5ListGroup /TYPE=1 fileID, "/"
683                //remove trailing ; from S_HDF5ListGroup
684               
685                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
686               
687                NXentry_name = S_HDF5ListGroup
688                NXentry_name = ReplaceString(";",NXentry_name,"")
689                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
690                        err = 1
691                        abort "More than one entry under the root node. Ambiguous"
692                endif
693                //concatenate NXentry node name and groupName   
694                // SRK - NOV2015 - dropped this and require the full group name passed in
695//              groupName = "/" + NXentry_name + groupName
696                Print "groupName = ",groupName
697                HDF5OpenGroup /Z fileID , groupName, groupID
698
699                if(!groupID)
700                // don't create the group if the name isn't right -- throw up an error
701                        //HDF5CreateGroup /Z fileID, groupName, groupID
702                        err = 1
703                        HDF5CloseFile /Z fileID
704                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
705                        return(err)
706                else
707                        // get attributes and save them
708                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
709                        //Wave attributes = S_HDF5ListAttributes
710                endif
711       
712                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
713                if (V_flag != 0)
714                        err = 1
715                        abort "Cannot save wave to HDF5 dataset " + varName
716                endif   
717               
718               
719                //attributes - something could be added here as optional parameters and flagged
720//              String attributes = "units"
721//              Make/O/T/N=1 tmp
722//              tmp[0] = "dimensionless"
723//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
724//              if (V_flag != 0)
725//                      err = 1
726//                      abort "Cannot save attributes to HDF5 dataset"
727//              endif   
728        catch
729
730        endtry
731
732// it is not necessary to close the group here. HDF5CloseFile will close the group as well     
733        if(groupID)
734                HDF5CloseGroup /Z groupID
735        endif
736       
737        if(fileID)
738                HDF5CloseFile /Z fileID
739        endif
740
741        setDataFolder $cDF
742        return err
743end
744
745//Write Wave 'wav' to hdf5 file 'fname'
746//Based on code from ANSTO (N. Hauser. nha 8/1/09)
747//
748// TODO
749//
750// -x change the /P=home to the user-defined data path (catPathName)           
751//
752Function V_WriteTextWaveToHDF(fname, groupName, varName, wav)
753        String fname, groupName, varName
754        Wave/T wav
755
756        // try a local folder first, then try to save to disk
757        //
758        String folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
759       
760        String localPath = "root:Packages:NIST:VSANS:"+folderStr//+":entry"
761        localPath += groupName + "/" + varName
762        // make everything colons for local data folders
763        localPath = ReplaceString("/", localPath, ":")
764       
765        Wave/Z/T w = $localPath
766        if(waveExists(w) == 1)
767                w = wav
768                Print "write to local folder done"
769                return(0)               //we're done, get out
770        endif
771       
772       
773        // if the local wave did not exist, then we proceed to write to disk
774
775
776       
777        variable err=0, fileID,groupID
778        String cDF = getDataFolder(1), temp
779        String NXentry_name
780       
781        try     
782                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
783                if(!fileID)
784                        err = 1
785                        abort "HDF5 file does not exist"
786                endif
787               
788                //get the NXentry node name
789                HDF5ListGroup /TYPE=1 fileID, "/"
790                //remove trailing ; from S_HDF5ListGroup
791               
792                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
793               
794                NXentry_name = S_HDF5ListGroup
795                NXentry_name = ReplaceString(";",NXentry_name,"")
796                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
797                        err = 1
798                        abort "More than one entry under the root node. Ambiguous"
799                endif
800
801                //concatenate NXentry node name and groupName
802                // SRK - NOV2015 - dropped this and require the full group name passed in
803//              groupName = "/" + NXentry_name + groupName
804                Print "groupName = ",groupName
805
806                HDF5OpenGroup /Z fileID , groupName, groupID
807
808                if(!groupID)
809                // don't create the group it the name isn't right -- throw up an error
810                        //HDF5CreateGroup /Z fileID, groupName, groupID
811                        err = 1
812                        HDF5CloseFile /Z fileID
813                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
814                        return(err)
815                else
816                        // get attributes and save them
817                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
818                        //Wave attributes = S_HDF5ListAttributes
819                endif
820       
821                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
822                if (V_flag != 0)
823                        err = 1
824                        abort "Cannot save wave to HDF5 dataset " + varName
825                endif   
826               
827               
828                //attributes - something could be added here as optional parameters and flagged
829//              String attributes = "units"
830//              Make/O/T/N=1 tmp
831//              tmp[0] = "dimensionless"
832//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
833//              if (V_flag != 0)
834//                      err = 1
835//                      abort "Cannot save attributes to HDF5 dataset"
836//              endif   
837        catch
838
839        endtry
840       
841        if(groupID)
842                HDF5CloseGroup /Z groupID
843        endif
844       
845        if(fileID)
846                HDF5CloseFile /Z fileID
847        endif
848
849        setDataFolder $cDF
850        return err
851end
852
853//////////////////////////////
854//////////////////////////////
855//////////////////////////////
856
857
858
859
860//////// function to take VCALC information and
861// fill in the simulated information as needed to make a "fake" data file
862//
863// TODO:
864// -- identify all of the necessary bits to change
865// -- maybe want a panel to make it easier to decide what inputs to change in the file
866// -- decide if it's better to write wholesale, or as individual waves
867//
868Macro Copy_VCALC_to_VSANSFile()
869       
870        String fileName = V_DoSaveFileDialog("pick the file to write to")
871        print fileName
872//     
873        if(strlen(fileName) > 0)
874                writeVCALC_to_file(fileName)
875        endif
876End
877
878//
879// TODO -- fill this in as needed to get fake data that's different
880//
881Function writeVCALC_to_file(fileName)
882        String fileName
883
884
885// the detectors, all 9 + the correct SDD (that accounts for the offset of T/B panels
886// the data itself (as INT32)
887// the front SDD (correct units)
888// the middle SDD (correct units)
889// the back SDD (correct units)
890        Variable ii,val
891        String detStr
892        for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
893                detStr = StringFromList(ii, ksDetectorListAll, ";")
894                Duplicate/O $("root:Packages:NIST:VSANS:VCALC:entry:instrument:detector_"+detStr+":det_"+detStr) tmpData
895                Redimension/I tmpData
896                tmpData = (tmpData ==   2147483647) ? 0 : tmpData               //the NaN "mask" in the sim data (T/B only)shows up as an ugly integer
897                V_writeDetectorData(fileName,detStr,tmpData)
898               
899                val = VCALC_getTopBottomSDDOffset(detStr)/10 + VCALC_getSDD(detStr)*100         // make sure value is in cm
900                print val
901                V_writeDet_distance(fileName,detStr,val)
902               
903// x and y pixel sizes for each detector
904//Function VCALC_getPixSizeX(type)              // returns the pixel X size, in [cm]
905//Function VCALC_getPixSizeY(type)
906        V_writeDet_x_pixel_size(fileName,detStr,VCALC_getPixSizeX(detStr)*10)           // data file is expecting mm
907        V_writeDet_y_pixel_size(fileName,detStr,VCALC_getPixSizeY(detStr)*10)
908       
909// the calibration data for each detector
910//V_writeDetTube_spatialCalib(fname,detStr,inW)
911// and for "B"
912//V_writeDet_cal_x(fname,detStr,inW)
913//V_writeDet_cal_y(fname,detStr,inW)
914
915               
916// the dead time for each detector
917// V_writeDetector_deadtime(fname,detStr,inW)
918// TODO: need a new, separate function to write the single deadtime value in/out of "B"
919
920        endfor
921       
922        // TODO testing - delete this
923                V_writeDet_beam_center_x(fileName,detStr,321)
924
925
926
927//? other detector geometry - lateral separation?
928
929// the wavelength
930//      Variable lam = V_getWavelength("VCALC")         //doesn't work, the corresponding folder in VCALC has not been defined
931        V_writeWavelength(fileName,VCALC_getWavelength())
932
933// description of the sample
934
935// sample information
936// name, title, etc
937       
938// fake the information about the count setup, so I have different numbers to read
939// count time = fake
940
941// monitor count (= imon)
942// returns the number of neutrons on the sample
943//Function VCALC_getImon()
944
945// ?? anything else that I'd like to see on the catalog - I could change them here to see different values
946// different collimation types?
947//
948
949        return(0)
950end
951
952
953
954
Note: See TracBrowser for help on using the repository browser.