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

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

lots of changes to 1D averaging and the plotting routines, detector corrections, and basic reads

File size: 25.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                Execute "MakeFakeCalibrationWaves()"
92                //              fMakeFakeCalibrationWaves()             //skips the alert
93
94
95                // TODO -- do I want to calculate the nonlinear x/y arrays and the q-values here?
96                // -- otherwise the mouse-over doesn't calculate the correct Q_values
97                // the display currently is not shifted or altered at all to account for the non-linearity
98                // or for display in q-values -- so why bother with this?
99                NVAR gDoNonLinearCor = root:Packages:NIST:VSANS:Globals:gDoNonLinearCor
100                // generate a distance matrix for each of the detectors
101                if (gDoNonLinearCor == 1)
102                        Print "Calculating Non-linear correction at RAW load time"// for "+ detStr
103                        for(ii=0;ii<ItemsInList(ksDetectorListNoB);ii+=1)
104                                detStr = StringFromList(ii, ksDetectorListNoB, ";")
105                                Wave w = V_getDetectorDataW(folder,detStr)
106        //                      Wave w_err = V_getDetectorDataErrW(fname,detStr)
107                                Wave w_calib = V_getDetTube_spatialCalib(folder,detStr)
108                                Variable tube_width = V_getDet_tubeWidth(folder,detStr)
109                                NonLinearCorrection(w,w_calib,tube_width,detStr,destPath)
110                               
111                               
112                                //(2.4) Convert the beam center values from pixels to mm
113                                // TODO -- there needs to be a permanent location for these values??
114                                //
115                                ConvertBeamCtr_to_mm(folder,detStr,destPath)
116                               
117                                // (2.5) Calculate the q-values
118                                // calculating q-values can't be done unless the non-linear corrections are calculated
119                                // so go ahead and put it in this loop.
120                                // TODO :
121                                // -- make sure that everything is present before the calculation
122                                // -- beam center must be properly defined in terms of real distance
123                                // -- distances/zero location/ etc. must be clearly documented for each detector
124                                //      ** this assumes that NonLinearCorrection() has been run to generate data_RealDistX and Y
125                                // ** this routine Makes the waves QTot, qx, qy, qz in each detector folder.
126                                //
127                                V_Detector_CalcQVals(folder,detStr,destPath)
128                               
129                        endfor
130                       
131                        //"B" is separate
132                        NonLinearCorrection_B(folder,"B",destPath)
133                        ConvertBeamCtr_to_mmB(folder,"B",destPath)
134                        V_Detector_CalcQVals(folder,"B",destPath)
135                       
136                else
137                        Print "Non-linear correction not done"
138                endif
139                                       
140                                       
141                /// END FAKE DATA CORRECTIONS           
142                       
143        endif
144       
145        SetDataFolder root:
146        return(err)
147End
148
149//
150// TODO -- this is all FAKED since all the data arrays are written to hdf as (1,128,128)
151//  -- try to fill in the bits from VCALC, if it exists (or force it)
152//
153// the SetScale parts may be useful later.
154//
155Function V_RedimFakeData()
156       
157        // check for fake data in VCALC folder...
158        wave/Z tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_B:det_B"
159        if(WaveExists(tmpw) == 0)
160                Execute "VCALC_Panel()"
161        endif
162       
163        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_B
164        Wave det_B=data
165        Redimension/N=(320,320)/E=1 det_B       
166        Redimension/D det_B
167//      det_B = p+q+2
168        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_B:det_B"
169        det_B=tmpw
170        det_B += 2
171        Wave distance=distance
172        distance = 2200
173
174                       
175        Variable ctr=20,npix=128
176        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_MT
177        Wave det_MT=data
178        Redimension/N=(npix,48)/E=1 det_MT
179        Redimension/D det_MT           
180        SetScale/I x -npix/2,npix/2,"",det_MT
181        SetScale/I y ctr,ctr+48,"",det_MT
182//      det_MT *= 10
183//      det_MT += 2
184        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_MT:det_MT"
185        det_MT=tmpw
186        det_MT += 2
187        Wave distance=distance
188        distance = 1030
189
190       
191        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_MB
192        Wave det_MB=data
193        Redimension/N=(npix,48)/E=1 det_MB             
194        Redimension/D det_MB
195        SetScale/I x -npix/2,npix/2,"",det_MB
196        SetScale/I y -ctr-48,-ctr,"",det_MB
197//      det_MB *= 5
198//      det_MB += 2
199        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_MB:det_MB"
200        det_MB=tmpw
201        det_MB += 2
202        Wave distance=distance
203        distance = 1030
204
205       
206        ctr=30
207        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_ML
208        Wave det_ML=data
209        Redimension/N=(48,npix)/E=1 det_ML             
210        Redimension/D det_ML
211        SetScale/I x -ctr-48,-ctr,"",det_ML
212        SetScale/I y -npix/2,npix/2,"",det_ML
213//      det_ML *= 2
214//      det_ML += 2
215        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_ML:det_ML"
216        det_ML=tmpw
217        det_ML += 2
218        Wave distance=distance
219        distance = 1000
220
221               
222        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_MR
223        Wave det_MR=data
224        Redimension/N=(48,npix)/E=1 det_MR             
225        Redimension/D det_MR
226        SetScale/I x ctr,ctr+48,"",det_MR
227        SetScale/I y -npix/2,npix/2,"",det_MR
228//      det_MR +=2
229        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_MR:det_MR"
230        det_MR=tmpw
231        det_MR += 2
232        Wave distance=distance
233        distance = 1000
234       
235       
236        ctr=30
237        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FT
238        Wave det_FT=data
239        Redimension/N=(npix,48)/E=1 det_FT             
240        Redimension/D det_FT
241        SetScale/I x -npix/2,npix/2,"",det_FT
242        SetScale/I y ctr,ctr+48,"",det_FT
243        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_FT:det_FT"
244        det_FT=tmpw
245        Wave distance=distance
246        distance = 180
247
248
249        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FB
250        Wave det_FB=data
251        Redimension/N=(npix,48)/E=1 det_FB             
252        Redimension/D det_FB
253        SetScale/I x -npix/2,npix/2,"",det_FB
254        SetScale/I y -ctr-48,-ctr,"",det_FB
255        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_FB:det_FB"
256        det_FB=tmpw
257        Wave distance=distance
258        distance = 180
259
260                       
261        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FL
262        Wave det_FL=data
263        Redimension/N=(48,npix)/E=1 det_FL             
264        Redimension/D det_FL
265        SetScale/I x -ctr-48,-ctr,"",det_FL
266        SetScale/I y -npix/2,npix/2,"",det_FL
267        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_FL:det_FL"
268        det_FL=tmpw
269        Wave distance=distance
270        distance = 150
271
272       
273        SetDataFolder root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FR
274        Wave det_FR=data
275        Redimension/N=(48,npix)/E=1 det_FR             
276        Redimension/D det_FR
277        SetScale/I x ctr,ctr+48,"",det_FR
278        SetScale/I y -npix/2,npix/2,"",det_FR
279        wave tmpw=$"root:Packages:NIST:VSANS:VCALC:entry:entry:instrument:detector_FR:det_FR"
280        det_FR=tmpw
281        Wave distance=distance
282        distance = 150
283
284       
285// get rid of zeros
286        det_FL += 2
287        det_FR += 2
288        det_FT += 2
289        det_FB += 2
290
291
292// fake beam center values
293        V_putDet_beam_center_x("RAW","B",160)
294        V_putDet_beam_center_y("RAW","B",160)
295
296
297        V_putDet_beam_center_x("RAW","MB",64)
298        V_putDet_beam_center_y("RAW","MB",55)
299        V_putDet_beam_center_x("RAW","MT",64)
300        V_putDet_beam_center_y("RAW","MT",-8.7)
301        V_putDet_beam_center_x("RAW","MR",-8.1)
302        V_putDet_beam_center_y("RAW","MR",64)
303        V_putDet_beam_center_x("RAW","ML",55)
304        V_putDet_beam_center_y("RAW","ML",64)
305
306        V_putDet_beam_center_x("RAW","FB",64)
307        V_putDet_beam_center_y("RAW","FB",55)
308        V_putDet_beam_center_x("RAW","FT",64)
309        V_putDet_beam_center_y("RAW","FT",-8.7)
310        V_putDet_beam_center_x("RAW","FR",-8.1)
311        V_putDet_beam_center_y("RAW","FR",64)
312        V_putDet_beam_center_x("RAW","FL",55)
313        V_putDet_beam_center_y("RAW","FL",64)
314
315
316
317
318
319
320        V_RescaleToBeamCenter("RAW","MB",64,55)
321        V_RescaleToBeamCenter("RAW","MT",64,-8.7)
322        V_RescaleToBeamCenter("RAW","MR",-8.1,64)
323        V_RescaleToBeamCenter("RAW","ML",55,64)
324        V_RescaleToBeamCenter("RAW","FL",55,64)
325        V_RescaleToBeamCenter("RAW","FR",-8.1,64)
326        V_RescaleToBeamCenter("RAW","FT",64,-8.7)
327        V_RescaleToBeamCenter("RAW","FB",64,55)
328
329
330
331        return(0)
332End
333
334
335// This loads for speed, since loading the attributes takes a LOT of time.
336//
337// this will load in the whole HDF file all at once.
338// Attributes are NOT loaded at all.
339//
340// -- the Gateway function H5GW_ReadHDF5(parentFolder, fileName, [hdf5Path])
341//    reads in the attributes too, but is very slow
342//   -- the H5GW function is called by: H_HDF5Gate_Read_Raw(file)
343//
344// TODO:
345// -x remove the P=home restriction top make this more generic (replaced with catPathName from PickPath)
346// -- get rid of bits leftover here that I don't need
347// -- be sure I'm using all of the correct flags in the HDF5LoadGroup operation
348// -- settle on how the base_name is to be used. "entry" for the RAW, fileName for the "rawVSANS"?
349// x- error check for path existence
350//
351// passing in "" for base_name will take the name from the file name as selected
352//
353Function V_LoadHDF5_NoAtt(fileName,base_name)
354        String fileName, base_name
355       
356//      if ( ParamIsDefault(hdf5Path) )
357//              hdf5Path = "/"
358//      endif
359
360        PathInfo/S catPathName
361        if(V_flag == 0)
362                V_PickPath()
363        endif
364
365        String hdf5path = "/"           //always read from the top
366        String status = ""
367
368        Variable fileID = 0
369//      HDF5OpenFile/R/P=home/Z fileID as fileName              //read file from home directory?
370        HDF5OpenFile/R/P=catPathName/Z fileID as fileName
371        if (V_Flag != 0)
372                return 0
373        endif
374
375        String/G root:file_path = S_path
376        String/G root:file_name = S_FileName
377       
378        if ( fileID == 0 )
379                Print fileName + ": could not open as HDF5 file"
380                return (0)
381        endif
382       
383//s_tic()               //fast
384       
385        SVAR tmpStr=root:file_name
386        fileName=tmpStr         //SRK - in case the file was chosen from a dialog, I'll need access to the name later
387       
388        //   read the data (too bad that HDF5LoadGroup does not read the attributes)
389        if(cmpstr(base_name,"") == 0)
390                base_name = StringFromList(0,FileName,".")
391        endif
392        if(cmpstr(base_name,"RAW") == 0)
393                base_name = ""
394        endif
395        //base_name = "entry"
396       
397        HDF5LoadGroup/Z/L=7/O/R/T=$base_name  :, fileID, hdf5Path               //      recursive
398        if ( V_Flag != 0 )
399                Print fileName + ": could not open as HDF5 file"
400                setdatafolder root:
401                return (0)
402        endif
403
404        HDF5CloseFile fileID
405       
406//s_toc()
407        return(0)
408end     
409
410
411// read a single real value
412// - fname passed in is the full path to the file on disk
413// - path is the path to the value in the HDF tree
414//
415// check to see if the value exists (It will be a wave)
416// -- if it does, return the value from the local folder
417// -- if not, read the file in, then return the value
418//
419// TODO:
420// currently, the work folders have the following path - so passing in "RAW" as fname
421// will take some re-configuring.
422//  root:Packages:NIST:VSANS:RAW:entry:entry:instrument:detector_FL:distance
423// -- be sure this read from work folders is not broken in the future, and is passed to ALL of the
424//    top-level R/W routines. (Write is necessary ONLY for SIM data files. Patch is direct to disk.)
425Function V_getRealValueFromHDF5(fname,path)
426        String fname,path
427
428        String folderStr=""
429        Variable valExists=0
430       
431        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
432
433// check for a work folder first (note that "entry" is doubled)
434        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
435                Wave/Z w = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
436                return(w[0])
437        endif
438       
439        if(Exists(ksBaseDFPath+folderStr+":"+path))
440                valExists=1
441        endif
442       
443        if(!valExists)
444                //then read in the file
445                V_LoadHDF5_NoAtt(fname,"")
446        endif
447
448// this should exist now - if not, I need to see the error
449        Wave/Z w = $(ksBaseDFPath+folderStr+":"+path)
450       
451        if(WaveExists(w))
452                return(w[0])
453        else
454                return(-999999)
455        endif   
456End
457
458// Returns a wave reference, not just a single value
459// ---then you pick what you need from the wave
460//
461// - fname passed in is the full path to the file on disk
462// - path is the path to the value in the HDF tree
463//
464// check to see if the value exists (It will be a wave)
465// -- if it does, return the value from the local folder
466// -- if not, read the file in, then return the value
467//
468Function/WAVE V_getRealWaveFromHDF5(fname,path)
469        String fname,path
470
471        String folderStr=""
472        Variable valExists=0
473       
474        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
475
476// check for a work folder first (note that "entry" is doubled)
477        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
478                Wave wOut = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
479                return wOut
480        endif
481               
482        if(Exists(ksBaseDFPath+folderStr+":"+path))
483                valExists=1
484        endif
485       
486        if(!valExists)
487                //then read in the file
488                V_LoadHDF5_NoAtt(fname,"")
489        endif
490
491// this should exist now - if not, I need to see the error
492        Wave wOut = $(ksBaseDFPath+folderStr+":"+path)
493       
494        return wOut
495       
496End
497
498// Returns a wave reference, not just a single value
499// ---then you pick what you need from the wave
500//
501// - fname passed in is the full path to the file on disk
502// - path is the path to the value in the HDF tree
503//
504// check to see if the value exists (It will be a wave)
505// -- if it does, return the value from the local folder
506// -- if not, read the file in, then return the value
507//
508Function/WAVE V_getTextWaveFromHDF5(fname,path)
509        String fname,path
510
511        String folderStr=""
512        Variable valExists=0
513       
514        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
515
516// check for a work folder first (note that "entry" is doubled)
517        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
518                Wave/T wOut = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
519                return wOut
520        endif
521       
522        if(Exists(ksBaseDFPath+folderStr+":"+path))
523                valExists=1
524        endif
525       
526        if(!valExists)
527                //then read in the file
528                V_LoadHDF5_NoAtt(fname,"")
529        endif
530
531// this should exist now - if not, I need to see the error
532        Wave/T wOut = $(ksBaseDFPath+folderStr+":"+path)
533       
534        return wOut
535       
536End
537
538
539//
540//   TODO
541// depricated? in HDF5 - store all of the values as real?
542// Igor sees no difference in real and integer variables (waves are different)
543// BUT-- Igor 7 will have integer variables
544//
545// truncate to integer before returning??
546//
547//  TODO
548// write a "getIntegerWave" function??
549//
550//////  integer values
551// reads 32 bit integer
552Function V_getIntegerFromHDF5(fname,path)
553        String fname                            //full path+name
554        String path                             //path to the hdf5 location
555       
556        Variable val = V_getRealValueFromHDF5(fname,path)
557       
558        val = round(val)
559        return(val)
560End
561
562
563// read a single string
564// - fname passed in is the full path to the file on disk
565// - path is the path to the value in the HDF tree
566// - num is the number of characters in the VAX string
567// check to see if the value exists (It will be a wave)
568// -- if it does, return the value from the local folder
569// -- if not, read the file in, then return the value
570//
571// TODO -- string could be checked for length, but returned right or wrong
572//
573Function/S V_getStringFromHDF5(fname,path,num)
574        String fname,path
575        Variable num
576
577        String folderStr=""
578        Variable valExists=0
579       
580        folderStr = V_RemoveDotExtension(V_GetFileNameFromPathNoSemi(fname))
581
582// check for a work folder first (note that "entry" is doubled)
583        if(Exists("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path))
584                Wave/Z/T tw = $("root:Packages:NIST:VSANS:"+folderStr+":entry:"+path)
585                return(tw[0])
586        endif
587       
588        if(Exists(ksBaseDFPath+folderStr+":"+path))
589                valExists=1
590        endif
591       
592        if(!valExists)
593                //then read in the file
594                V_LoadHDF5_NoAtt(fname,"")
595        endif
596
597// this should exist now - if not, I need to see the error
598        Wave/T/Z tw = $(ksBaseDFPath+folderStr+":"+path)
599       
600        if(WaveExists(tw))
601       
602        //      if(strlen(tw[0]) != num)
603        //              Print "string is not the specified length"
604        //      endif
605               
606                return(tw[0])
607        else
608                return("The specified wave does not exist: " + path)
609        endif
610End
611
612
613
614///////////////////////////////
615
616//
617//Write Wave 'wav' to hdf5 file 'fname'
618//Based on code from ANSTO (N. Hauser. nha 8/1/09)
619//
620// TODO:
621// -- figure out if this will write in the native format of the
622//     wave as passed in, or if it will only write as DP.
623// -- do I need to write separate functions for real, integer, etc.?
624// -- the lines to create a missing group have been commented out to avoid filling
625//    in missing fields that should have been generated by the data writer. Need to make
626//    a separate function that will write and generate if needed, and use this in specific cases
627//    only if I really have to force it.
628//     
629// -x change the /P=home to the user-defined data path (catPathName)           
630//
631Function V_WriteWaveToHDF(fname, groupName, varName, wav)
632        String fname, groupName, varName
633        Wave wav
634       
635        variable err=0, fileID,groupID
636        String cDF = getDataFolder(1), temp
637        String NXentry_name
638       
639        try     
640                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
641                if(!fileID)
642                        err = 1
643                        abort "HDF5 file does not exist"
644                endif
645               
646                //get the NXentry node name
647                HDF5ListGroup /TYPE=1 fileID, "/"
648                //remove trailing ; from S_HDF5ListGroup
649               
650                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
651               
652                NXentry_name = S_HDF5ListGroup
653                NXentry_name = ReplaceString(";",NXentry_name,"")
654                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
655                        err = 1
656                        abort "More than one entry under the root node. Ambiguous"
657                endif
658                //concatenate NXentry node name and groupName   
659                // SRK - NOV2015 - dropped this and require the full group name passed in
660//              groupName = "/" + NXentry_name + groupName
661                Print "groupName = ",groupName
662                HDF5OpenGroup /Z fileID , groupName, groupID
663
664                if(!groupID)
665                // don't create the group if the name isn't right -- throw up an error
666                        //HDF5CreateGroup /Z fileID, groupName, groupID
667                        err = 1
668                        HDF5CloseFile /Z fileID
669                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
670                        return(err)
671                else
672                        // get attributes and save them
673                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
674                        //Wave attributes = S_HDF5ListAttributes
675                endif
676       
677                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
678                if (V_flag != 0)
679                        err = 1
680                        abort "Cannot save wave to HDF5 dataset " + varName
681                endif   
682               
683               
684                //attributes - something could be added here as optional parameters and flagged
685//              String attributes = "units"
686//              Make/O/T/N=1 tmp
687//              tmp[0] = "dimensionless"
688//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
689//              if (V_flag != 0)
690//                      err = 1
691//                      abort "Cannot save attributes to HDF5 dataset"
692//              endif   
693        catch
694
695        endtry
696
697// it is not necessary to close the group here. HDF5CloseFile will close the group as well     
698        if(groupID)
699                HDF5CloseGroup /Z groupID
700        endif
701       
702        if(fileID)
703                HDF5CloseFile /Z fileID
704        endif
705
706        setDataFolder $cDF
707        return err
708end
709
710//Write Wave 'wav' to hdf5 file 'fname'
711//Based on code from ANSTO (N. Hauser. nha 8/1/09)
712//
713// TODO
714//
715// -x change the /P=home to the user-defined data path (catPathName)           
716//
717Function V_WriteTextWaveToHDF(fname, groupName, varName, wav)
718        String fname, groupName, varName
719        Wave/T wav
720       
721        variable err=0, fileID,groupID
722        String cDF = getDataFolder(1), temp
723        String NXentry_name
724       
725        try     
726                HDF5OpenFile/P=catPathName /Z fileID  as fname  //open file read-write
727                if(!fileID)
728                        err = 1
729                        abort "HDF5 file does not exist"
730                endif
731               
732                //get the NXentry node name
733                HDF5ListGroup /TYPE=1 fileID, "/"
734                //remove trailing ; from S_HDF5ListGroup
735               
736                Print "S_HDF5ListGroup = ",S_HDF5ListGroup
737               
738                NXentry_name = S_HDF5ListGroup
739                NXentry_name = ReplaceString(";",NXentry_name,"")
740                if(strsearch(NXentry_name,":",0)!=-1) //more than one entry under the root node
741                        err = 1
742                        abort "More than one entry under the root node. Ambiguous"
743                endif
744
745                //concatenate NXentry node name and groupName
746                // SRK - NOV2015 - dropped this and require the full group name passed in
747//              groupName = "/" + NXentry_name + groupName
748                Print "groupName = ",groupName
749
750                HDF5OpenGroup /Z fileID , groupName, groupID
751
752                if(!groupID)
753                // don't create the group it the name isn't right -- throw up an error
754                        //HDF5CreateGroup /Z fileID, groupName, groupID
755                        err = 1
756                        HDF5CloseFile /Z fileID
757                        DoAlert 0, "HDF5 group does not exist "+groupName+varname
758                        return(err)
759                else
760                        // get attributes and save them
761                        //HDF5ListAttributes /Z fileID, groupName    this is returning null. expect it to return semicolon delimited list of attributes
762                        //Wave attributes = S_HDF5ListAttributes
763                endif
764       
765                HDF5SaveData /O /Z /IGOR=0 wav, groupID, varName
766                if (V_flag != 0)
767                        err = 1
768                        abort "Cannot save wave to HDF5 dataset " + varName
769                endif   
770               
771               
772                //attributes - something could be added here as optional parameters and flagged
773//              String attributes = "units"
774//              Make/O/T/N=1 tmp
775//              tmp[0] = "dimensionless"
776//              HDF5SaveData /O /Z /IGOR=0 /A=attributes tmp, groupID, varName
777//              if (V_flag != 0)
778//                      err = 1
779//                      abort "Cannot save attributes to HDF5 dataset"
780//              endif   
781        catch
782
783        endtry
784       
785        if(groupID)
786                HDF5CloseGroup /Z groupID
787        endif
788       
789        if(fileID)
790                HDF5CloseFile /Z fileID
791        endif
792
793        setDataFolder $cDF
794        return err
795end
796
797//////////////////////////////
798//////////////////////////////
799//////////////////////////////
800
801// TODO:
802// -- this must be called as needed to force a re-read of the data from disk
803//    "as needed" means that when an operation is done that needs to ensure
804//     a fresh read from disk, it must take care of the kill.
805// -- the ksBaseDFPath needs to be removed. It's currently pointing to RawVSANS, which is
806//    really not used as intended anymore.
807//
808Function V_KillNamedDataFolder(fname)
809        String fname
810       
811        Variable err=0
812       
813        String folderStr = V_GetFileNameFromPathNoSemi(fname)
814        folderStr = V_RemoveDotExtension(folderStr)
815       
816        KillDataFolder/Z $(ksBaseDFPath+folderStr)
817        err = V_flag
818       
819        return(err)
820end
821
822//given a filename of a SANS data filename of the form
823// name.anything
824//returns the name as a string without the ".fbdfasga" extension
825//
826// returns the input string if a "." can't be found (maybe it wasn't there)
827Function/S V_RemoveDotExtension(item)
828        String item
829        String invalid = item   //
830        Variable num=-1
831       
832        //find the "dot"
833        String runStr=""
834        Variable pos = strsearch(item,".",0)
835        if(pos == -1)
836                //"dot" not found
837                return (invalid)
838        else
839                //found, get all of the characters preceeding it
840                runStr = item[0,pos-1]
841                return (runStr)
842        Endif
843End
844
845//returns a string containing filename (WITHOUT the ;vers)
846//the input string is a full path to the file (Mac-style, still works on Win in IGOR)
847//with the folders separated by colons
848//
849// called by MaskUtils.ipf, ProtocolAsPanel.ipf, WriteQIS.ipf
850//
851Function/S V_GetFileNameFromPathNoSemi(fullPath)
852        String fullPath
853       
854        Variable offset1,offset2
855        String filename=""
856        //String PartialPath
857        offset1 = 0
858        do
859                offset2 = StrSearch(fullPath, ":", offset1)
860                if (offset2 == -1)                              // no more colons ?
861                        fileName = FullPath[offset1,strlen(FullPath) ]
862                        //PartialPath = FullPath[0, offset1-1]
863                        break
864                endif
865                offset1 = offset2+1
866        while (1)
867       
868        //remove version number from name, if it's there - format should be: filename;N
869        filename =  StringFromList(0,filename,";")              //returns null if error
870       
871        Return filename
872End
Note: See TracBrowser for help on using the repository browser.