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

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

updated the base "Write" routines to look locally first, then if no local folder found, write to the HDF file on disk. This is the same behavior as the base "Read" (or "get") routines.

File size: 28.0 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, 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 doubled)
480        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
481                Wave wOut = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+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 doubled)
522        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
523                Wave/T wOut = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+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 doubled)
592        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
593                Wave/Z/T tw = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+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: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.