source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/WriteHDF5.ipf @ 1068

Last change on this file since 1068 was 1068, checked in by krzywon, 5 years ago

NXcanSAS writer code cleanup.

File size: 23.6 KB
Line 
1#pragma rtGlobals=3             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
4
5#include <HDF5 Browser>
6
7//************************
8// Vers 1.14 20170928
9//
10//************************
11
12
13///////////////////////////////////////////////////////////////////////////
14// - WriteNxCanSAS1D - Method for writing 1D NXcanSAS data
15// Creates an HDF5 file, with reduced 1D data and stores all meta data
16// If dialog and fullpath are left blank (0 and ""), fake data will be used
17
18Function WriteNxCanSAS1D(type,fullpath,dialog)
19        // Define input variables
20        String type // data location, in memory, relative to root:Packages:NIST:
21        String fullpath // file path and name where data will be saved
22        Variable dialog // if 1, prompt user for file path, otherwise, use fullpath
23       
24        // Define local function variables
25        Variable fileID
26        String destStr=""
27        String parentBase = "/sasentry/" // HDF5 base path for all
28        String/G base = "root:NXcanSAS_file"
29       
30        KillDataFolder/Z $base
31       
32        // Define local waves
33        Wave/T vals,attr,attrVals
34       
35        // Define folder for data heirarchy
36        NewDataFolder/O/S root:NXcanSAS_file
37       
38        // Check fullpath and dialog
39        if(dialog || stringmatch(fullpath, ""))
40                fileID = NxCansas_DoSaveFileDialog()
41        else
42                NxCansas_CreateFile(fullpath)
43        Endif
44        if(!fileID)
45                Print "Unable to create file at " + fullpath + "."
46        else
47                destStr = "root:Packages:NIST:"+type
48                //*****these waves MUST EXIST, or IGOR Pro will crash, with a type 2 error****
49                WAVE intw = $(destStr + ":integersRead")
50                WAVE rw = $(destStr + ":realsRead")
51                WAVE/T textw=$(destStr + ":textRead")
52                WAVE qvals =$(destStr + ":qval")
53                WAVE inten=$(destStr + ":aveint")
54                WAVE sig=$(destStr + ":sigave")
55                WAVE qbar = $(destStr + ":QBar")
56                WAVE sigmaq = $(destStr + ":SigmaQ")
57                WAVE fsubs = $(destStr + ":fSubS")
58        endif
59
60        ///////////////////////////////////////////////////////////////////////////
61        // Write all data
62       
63        // Define common attribute waves
64        Make/T/N=1 empty = {""}
65        Make/T/N=1 units = {"units"}
66        Make/T/N=1 inv_cm = {"1/cm"}
67        Make/T/N=1 inv_angstrom = {"1/A"}
68       
69        // Run Name and title
70        NewDataFolder/O/S $(base + ":entry1")
71        Make/T/N=1 $(base + ":entry1:title") = {textw[6]}
72        CreateStrNxCansas(fileID,parentBase,"","title",$(base + ":entry1:title"),empty,empty)
73        Make/T/N=1 $(base + ":entry1:run") = {textw[0]}
74        CreateStrNxCansas(fileID,parentBase,"","run",$(base + ":entry1:run"),empty,empty)
75       
76        // SASData
77        String dataParent = parentBase + "sasdata/"
78        // Create SASdata entry
79        String dataBase = base + ":entry1:sasdata"
80        NewDataFolder/O/S $(dataBase)
81        Make/O/T/N=5 $(dataBase + ":attr") = {"canSAS_class","signal","I_axes","NX_class","Q_indices", "timestamp"}
82        Make/O/T/N=5 $(dataBase + ":attrVals") = {"SASdata","I","Q","NXdata","0,1",textw[1]}
83        CreateStrNxCansas(fileID,dataParent,"","",empty,$(dataBase + ":attr"),$(dataBase + ":attrVals"))
84        // Create q entry
85        NewDataFolder/O/S $(dataBase + ":q")
86        Make/T/N=2 $(dataBase + ":q:attr") = {"units","resolutions"}
87        Make/T/N=2 $(dataBase + ":q:attrVals") = {"1/angstrom","Qdev"}
88        CreateVarNxCansas(fileID,dataParent,"sasdata","Q",qvals,$(dataBase + ":q:attr"),$(dataBase + ":q:attrVals"))
89        // Create i entry
90        NewDataFolder/O/S $(dataBase + ":i")
91        Make/T/N=2 $(dataBase + ":i:attr") = {"units","uncertainties"}
92        Make/T/N=2 $(dataBase + ":i:attrVals") = {"1/cm","Idev"}
93        CreateVarNxCansas(fileID,dataParent,"sasdata","I",inten,$(dataBase + ":i:attr"),$(dataBase + ":i:attrVals"))
94        // Create idev entry
95        CreateVarNxCansas(fileID,dataParent,"sasdata","Idev",sig,units,inv_cm)
96        // Create qdev entry
97        CreateVarNxCansas(fileID,dataParent,"sasdata","Qdev",sigmaq,units,inv_angstrom)
98        CreateVarNxCansas(fileID,dataParent,"sasdata","Qmean",qbar,units,inv_angstrom)
99       
100        // Write all meta data
101        WriteMetaData(fileID,base,parentBase,rw,textw)
102       
103        //
104        ///////////////////////////////////////////////////////////////////////////
105       
106        // Close the file
107        if(fileID)
108                HDF5CloseFile /Z fileID
109        endif
110       
111End
112
113//
114///////////////////////////////////////////////////////////////////////////
115
116
117///////////////////////////////////////////////////////////////////////////
118// - WriteNxCanSAS2D - Method for writing 2D NXcanSAS data
119// Creates an HDF5 file, generates reduced 2D data and stores all meta data
120// If dialog and fullpath are left blank (0 and ""), fake data will be used
121
122Function WriteNxCanSAS2D(type,fullpath,dialog)
123        // Define input variables
124        String type // data location, in memory, relative to root:Packages:NIST:
125        String fullpath // file path and name where data will be saved
126        Variable dialog // if 1, prompt user for file path, otherwise, use fullpath
127       
128        // Define local function variables
129        Variable fileID
130        String destStr="",typeStr=""
131        String parentBase = "/sasentry/" // HDF5 base path for all
132        String/G base = "root:NXcanSAS_file"
133       
134        KillDataFolder/Z $base
135       
136        // Define local waves
137        Wave/T vals,attr,attrVals
138       
139        // Define folder for data heirarchy
140        NewDataFolder/O/S root:NXcanSAS_file
141       
142        // Check fullpath and dialog
143        if(dialog || stringmatch(fullpath, ""))
144                fileID = NxCansas_DoSaveFileDialog()
145        else
146                NxCansas_CreateFile(fullpath)
147        Endif
148        if(!fileID)
149                Print "Unable to create file at " + fullpath + "."
150        else
151                destStr = "root:Packages:NIST:"+type
152
153                //must select the linear_data to export
154                NVAR isLog = $(destStr+":gIsLogScale")
155                if(isLog==1)
156                        typeStr = ":linear_data"
157                else
158                        typeStr = ":data"
159                endif
160                        NVAR pixelsX = root:myGlobals:gNPixelsX
161                NVAR pixelsY = root:myGlobals:gNPixelsY
162                Wave data=$(destStr+typeStr)
163                Wave data_err=$(destStr+":linear_data_error")
164                WAVE intw=$(destStr + ":integersRead")
165                WAVE rw=$(destStr + ":realsRead")
166                WAVE/T textw=$(destStr + ":textRead")
167        endif
168       
169        ///////////////////////////////////////////////////////////////////////////
170        // Compute Qx, Qy data from pixel space
171       
172        Duplicate/O data,qx_val,qy_val,z_val,qval,qz_val,phi,r_dist
173       
174        Variable xctr,yctr,sdd,lambda,pixSize
175        xctr = rw[16]
176        yctr = rw[17]
177        sdd = rw[18]
178        lambda = rw[26]
179        pixSize = rw[13]/10             //convert mm to cm (x and y are the same size pixels)
180       
181        qx_val = CalcQx(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10)          //+1 converts to detector coordinate system
182        qy_val = CalcQy(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10)
183       
184        Redimension/N=(pixelsX*pixelsY) qx_val,qy_val,z_val
185
186        Variable L2 = rw[18]
187        Variable BS = rw[21]
188        Variable S1 = rw[23]
189        Variable S2 = rw[24]
190        Variable L1 = rw[25]
191        Variable lambdaWidth = rw[27]   
192        Variable usingLenses = rw[28]           //new 2007
193
194        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
195        Variable g = 981.0                              //gravity acceleration [cm/s^2]
196        Variable m_h    = 252.8                 // m/h [=] s/cm^2
197
198        Variable acc,ssd,lambda0,yg_d,qstar
199               
200        G = 981.  //!   ACCELERATION OF GRAVITY, CM/SEC^2
201        acc = vz_1              //      3.956E5 //!     CONVERT WAVELENGTH TO VELOCITY CM/SEC
202        SDD = L2        *100    //1317
203        SSD = L1        *100    //1627          //cm
204        lambda0 = lambda                //              15
205        YG_d = -0.5*G*SDD*(SSD+SDD)*(LAMBDA0/acc)^2
206        qstar = -2*pi/lambda0*2*yg_d/sdd
207
208        // the gravity center is not the resolution center
209        // gravity center = beam center
210        // resolution center = offset y = dy + (2)*yg_d
211        ///************
212        // do everything to write out the resolution too
213        // un-comment these if you want to write out qz_val and qval too, then use the proper save command
214        qval = CalcQval(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10)
215        qz_val = CalcQz(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10)
216        //      phi = FindPhi( pixSize*((p+1)-xctr) , pixSize*((q+1)-yctr))             //(dx,dy)
217        //      r_dist = sqrt(  (pixSize*((p+1)-xctr))^2 +  (pixSize*((q+1)-yctr))^2 )          //radial distance from ctr to pt
218        phi = FindPhi( pixSize*((p+1)-xctr) , pixSize*((q+1)-yctr)+(2)*yg_d)            //(dx,dy+yg_d)
219        r_dist = sqrt(  (pixSize*((p+1)-xctr))^2 +  (pixSize*((q+1)-yctr)+(2)*yg_d)^2 )         //radial distance from ctr to pt
220        Redimension/N=(pixelsX*pixelsY) qz_val,qval,phi,r_dist
221        //everything in 1D now
222        Duplicate/O qval SigmaQX,SigmaQY,fsubS
223
224        //Two parameters DDET and APOFF are instrument dependent.  Determine
225        //these from the instrument name in the header.
226        //From conversation with JB on 01.06.99 these are the current good values
227        Variable DDet
228        NVAR apOff = root:myGlobals:apOff               //in cm
229        DDet = rw[10]/10                        // header value (X) is in mm, want cm here
230
231        Variable ret1,ret2,ret3,nq
232        nq = pixelsX*pixelsY
233        Variable ii = 0
234       
235        do
236                get2DResolution(qval[ii],phi[ii],lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,pixSize,usingLenses,r_dist[ii],ret1,ret2,ret3)
237                SigmaQX[ii] = ret1     
238                SigmaQY[ii] = ret2     
239                fsubs[ii] = ret3       
240                ii+=1
241        while(ii<nq)
242        //
243        ///////////////////////////////////////////////////////////////////////////
244
245       
246        ///////////////////////////////////////////////////////////////////////////
247        // Write all data
248       
249        // Define common attribute waves
250        Make/T/N=1 empty = {""}
251        Make/T/N=1 units = {"units"}
252        Make/T/N=1 inv_cm = {"1/cm"}
253        Make/T/N=1 inv_angstrom = {"1/A"}
254       
255        // Run Name and title
256        NewDataFolder/O/S $(base + ":entry1")
257        Make/T/N=1 $(base + ":entry1:title") = {textw[6]}
258        CreateStrNxCansas(fileID,parentBase,"","title",$(base + ":entry1:title"),empty,empty)
259        Make/T/N=1 $(base + ":entry1:run") = {textw[0]}
260        CreateStrNxCansas(fileID,parentBase,"","run",$(base + ":entry1:run"),empty,empty)
261       
262        // SASData
263        String dataParent = parentBase + "sasdata/"
264        // Create SASdata entry
265        String dataBase = base + ":entry1:sasdata"
266        NewDataFolder/O/S $(dataBase)
267        Make/O/T/N=5 $(dataBase + ":attr") = {"canSAS_class","signal","I_axes","NX_class","Q_indices", "timestamp"}
268        Make/O/T/N=5 $(dataBase + ":attrVals") = {"SASdata","I","Qx,Qy","NXdata","0,1",textw[1]}
269        CreateStrNxCansas(fileID,dataParent,"","",empty,$(dataBase + ":attr"),$(dataBase + ":attrVals"))
270        // Create i entry
271        NewDataFolder/O/S $(dataBase + ":i")
272        Make/T/N=2 $(dataBase + ":i:attr") = {"units","uncertainties"}
273        Make/T/N=2 $(dataBase + ":i:attrVals") = {"1/cm","Idev"}
274        CreateVarNxCansas(fileID,dataParent,"sasdata","I",data,$(dataBase + ":i:attr"),$(dataBase + ":i:attrVals"))
275        // Create qx and qy entry
276        NewDataFolder/O/S $(dataBase + ":qx")
277        Make/T/N=2 $(dataBase + ":qx:attr") = {"units","resolutions"}
278        Make/T/N=2 $(dataBase + ":qx:attrVals") = {"1/angstrom","Qxdev"}
279        CreateVarNxCansas(fileID,dataParent,"sasdata","Qx",qx_val,$(dataBase + ":qx:attr"),$(dataBase + ":qx:attrVals"))
280        NewDataFolder/O/S $(dataBase + ":qy")
281        Make/T/N=2 $(dataBase + ":qy:attr") = {"units","resolutions"}
282        Make/T/N=2 $(dataBase + ":qy:attrVals") = {"1/angstrom","Qydev"}
283        CreateVarNxCansas(fileID,dataParent,"sasdata","Qy",qy_val,$(dataBase + ":qy:attr"),$(dataBase + ":qy:attrVals"))
284        // Create idev entry
285        CreateVarNxCansas(fileID,dataParent,"sasdata","Idev",data_err,units,inv_cm)
286        // Create qdev entry
287        CreateVarNxCansas(fileID,dataParent,"sasdata","Qxdev",SigmaQX,units,inv_angstrom)
288        CreateVarNxCansas(fileID,dataParent,"sasdata","Qydev",SigmaQY,units,inv_angstrom)
289        // Create shadwfactor entry
290       
291        // TODO: Reinstate ShadowFactor
292        // CreateVarNxCansas(fileID,dataParent,"sasdata","ShadowFactor",fsubs,empty,empty)
293       
294        // Write all meta data
295        WriteMetaData(fileID,base,parentBase,rw,textw)
296       
297        // Close the file
298        if(fileID)
299                HDF5CloseFile /Z fileID
300        endif
301       
302End
303
304//
305///////////////////////////////////////////////////////////////////////////
306
307///////////////////////////////////////////////////////////////////////////
308// - WriteMetaData - Method used to write non data elements into NXcanSAS
309// format. This is common between 1D and 2D data sets.
310
311Function WriteMetaData(fileID,base,parentBase,rw,textw)
312        String base,parentBase
313        Variable fileID
314        Wave rw
315        Wave/T textw
316       
317        // Define common attribute waves
318        Make/T/N=1 empty = {""}
319        Make/T/N=1 units = {"units"}
320        Make/T/N=1 m = {"m"}
321        Make/T/N=1 mm = {"mm"}
322        Make/T/N=1 cm = {"cm"}
323        Make/T/N=1 pixel = {"pixel"}
324        Make/T/N=1 angstrom = {"A"}
325       
326        // SASinstrument
327        String instrParent = parentBase + "sasinstrument/"
328        // Create SASinstrument entry
329        String instrumentBase = base + ":entry1:sasinstrument"
330        NewDataFolder/O/S $(instrumentBase)
331        Make/O/T/N=5 $(instrumentBase + ":attr") = {"canSAS_class","NX_class"}
332        Make/O/T/N=5 $(instrumentBase + ":attrVals") = {"SASinstrument","NXinstrument"}
333        CreateStrNxCansas(fileID,instrParent,"","",empty,$(instrumentBase + ":attr"),$(instrumentBase + ":attrVals"))
334       
335        // SASaperture
336        String apertureParent = instrParent + "sasaperture/"
337        // Create SASaperture entry
338        String apertureBase = instrumentBase + ":sasaperture"
339        NewDataFolder/O/S $(apertureBase)
340        Make/O/T/N=5 $(apertureBase + ":attr") = {"canSAS_class","NX_class"}
341        Make/O/T/N=5 $(apertureBase + ":attrVals") = {"SASaperture","NXaperture"}
342        CreateStrNxCansas(fileID,apertureParent,"","",empty,$(apertureBase + ":attr"),$(apertureBase + ":attrVals"))
343        // Create SASaperture shape entry
344        Make/O/T/N=1 $(apertureBase + ":shape") = {"pinhole"} // TODO: Where do I get rectangular dimensions from?
345        CreateStrNxCansas(fileID,apertureParent,"sasaperture","shape",$(apertureBase + ":shape"),empty,empty)
346        // Create SASaperture x_gap entry
347        Make/O/N=1 $(apertureBase + ":x_gap") = {rw[24]} // TODO: Where do I get rectangular dimensions from?
348        CreateVarNxCansas(fileID,apertureParent,"sasaperture","x_gap",$(apertureBase + ":x_gap"),units,cm)
349        // Create SASaperture y_gap entry
350        Make/O/N=1 $(apertureBase + ":y_gap") = {rw[24]} // TODO: Where do I get rectangular dimensions from?
351        CreateVarNxCansas(fileID,apertureParent,"sasaperture","y_gap",$(apertureBase + ":y_gap"),units,cm)
352       
353        // SAScollimation
354        String collimationParent = instrParent + "sascollimation/"
355        // Create SAScollimation entry
356        String collimationBase = instrumentBase + ":sascollimation"
357        NewDataFolder/O/S $(collimationBase)
358        Make/O/T/N=5 $(collimationBase + ":attr") = {"canSAS_class","NX_class"}
359        Make/O/T/N=5 $(collimationBase + ":attrVals") = {"SAScollimation","NXcollimator"}
360        CreateStrNxCansas(fileID,collimationParent,"","",empty,$(collimationBase + ":attr"),$(collimationBase + ":attrVals"))
361        // Create SAScollimation length entry
362        Make/O/N=1 $(collimationBase + ":length") = {15.3} // TODO: Get real value
363        CreateVarNxCansas(fileID,collimationParent,"sasaperture","length",$(collimationBase + ":length"),units,m)
364        // Create SAScollimation distance entry
365        Make/O/N=1 $(collimationBase + ":distance") = {rw[25]}
366        CreateVarNxCansas(fileID,collimationParent,"sasaperture","distance",$(collimationBase + ":distance"),units,m)
367       
368        // SASdetector
369        String detectorParent = instrParent + "sasdetector/"
370        // Create SASdetector entry
371        String detectorBase = instrumentBase + ":sasdetector"
372        NewDataFolder/O/S $(detectorBase)
373        Make/O/T/N=5 $(detectorBase + ":attr") = {"canSAS_class","NX_class"}
374        Make/O/T/N=5 $(detectorBase + ":attrVals") = {"SASdetector","NXdetector"}
375        CreateStrNxCansas(fileID,detectorParent,"","",empty,$(detectorBase + ":attr"),$(detectorBase + ":attrVals"))
376        // Create SASdetector name entry
377        Make/O/T/N=1 $(detectorBase + ":name") = {textw[9]}
378        CreateStrNxCansas(fileID,detectorParent,"","name",$(detectorBase + ":name"),empty,empty)
379        // Create SASdetector distance entry
380        Make/O/N=1 $(detectorBase + ":SDD") = {rw[18]}
381        CreateVarNxCansas(fileID,detectorParent,"","SDD",$(detectorBase + ":SDD"),units,m)
382        // Create SASdetector beam_center_x entry
383        Make/O/N=1 $(detectorBase + ":beam_center_x") = {rw[16]}
384        CreateVarNxCansas(fileID,detectorParent,"","beam_center_x",$(detectorBase + ":beam_center_x"),units,pixel)
385        // Create SASdetector beam_center_y entry
386        Make/O/N=1 $(detectorBase + ":beam_center_y") = {rw[17]}
387        CreateVarNxCansas(fileID,detectorParent,"","beam_center_y",$(detectorBase + ":beam_center_y"),units,pixel)
388        // Create SASdetector x_pixel_size entry
389        Make/O/N=1 $(detectorBase + ":x_pixel_size") = {rw[10]}
390        CreateVarNxCansas(fileID,detectorParent,"","x_pixel_size",$(detectorBase + ":x_pixel_size"),units,mm)
391        // Create SASdetector y_pixel_size entry
392        Make/O/N=1 $(detectorBase + ":y_pixel_size") = {rw[13]}
393        CreateVarNxCansas(fileID,detectorParent,"","y_pixel_size",$(detectorBase + ":y_pixel_size"),units,mm)
394       
395        // SASsource
396        String sourceParent = instrParent + "sassource/"
397        // Create SASdetector entry
398        String sourceBase = instrumentBase + ":sassource"
399        NewDataFolder/O/S $(sourceBase)
400        Make/O/T/N=5 $(sourceBase + ":attr") = {"canSAS_class","NX_class"}
401        Make/O/T/N=5 $(sourceBase + ":attrVals") = {"SASsource","NXsource"}
402        CreateStrNxCansas(fileID,sourceParent,"","",empty,$(sourceBase + ":attr"),$(sourceBase + ":attrVals"))
403        // Create SASsource radiation entry
404        Make/O/T/N=1 $(sourceBase + ":radiation") = {"Reactor Neutron Source"}
405        CreateStrNxCansas(fileID,sourceParent,"","radiation",$(sourceBase + ":radiation"),empty,empty)
406        // Create SASsource incident_wavelength entry
407        Make/O/N=1 $(sourceBase + ":incident_wavelength") = {rw[26]}
408        CreateVarNxCansas(fileID,sourceParent,"","incident_wavelength",$(sourceBase + ":incident_wavelength"),units,angstrom)
409        // Create SASsource incident_wavelength_spread entry
410        Make/O/N=1 $(sourceBase + ":incident_wavelength_spread") = {rw[27]}
411        CreateVarNxCansas(fileID,sourceParent,"","incident_wavelength_spread",$(sourceBase + ":incident_wavelength_spread"),units,angstrom)
412       
413        // SASsample
414        String sampleParent = parentBase + "sassample/"
415        // Create SASsample entry
416        String sampleBase = base + ":entry1:sassample"
417        NewDataFolder/O/S $(sampleBase)
418        Make/O/T/N=5 $(sampleBase + ":attr") = {"canSAS_class","NX_class"}
419        Make/O/T/N=5 $(sampleBase + ":attrVals") = {"SASsample","NXsample"}
420        CreateStrNxCansas(fileID,sampleParent,"","",empty,$(sampleBase + ":attr"),$(sampleBase + ":attrVals"))
421        // Create SASsample name entry
422        Make/O/T/N=1 $(sampleBase + ":name") = {textw[6]}
423        CreateStrNxCansas(fileID,sampleParent,"","name",$(sampleBase + ":name"),empty,empty)
424        // Create SASsample thickness entry
425        Make/O/N=1 $(sampleBase + ":thickness") = {rw[5]}
426        CreateVarNxCansas(fileID,sampleParent,"","thickness",$(sampleBase + ":thickness"),units,cm)
427        // Create SASsample transmission entry
428        Make/O/N=1 $(sampleBase + ":transmission") = {rw[4]}
429        CreateVarNxCansas(fileID,sampleParent,"","transmission",$(sampleBase + ":transmission"),empty,empty)
430End
431       
432//
433///////////////////////////////////////////////////////////////////////////
434
435
436///////////////////////////////////////////////////////////////////////////
437// Basic file open and initialization routines
438
439// Select/create file through prompt
440Function NxCansas_DoSaveFileDialog()
441        Variable refNum, fileID
442        String message = "Save a file"
443        String outputPath
444        String fileFilters = "Data Files (*.h5):.h5;"
445        fileFilters += "All Files:.*;"
446        Open /D /F=fileFilters /M=message refNum
447        outputPath = S_fileName
448        fileID = NxCansas_CreateFile(outputPath)
449        return fileID
450End
451
452// Create file with a known path
453Function NxCansas_CreateFile(fullpath)
454        String fullpath
455        Variable fileID
456        fullpath = ReplaceString(":\\", fullpath, ":")
457        fullpath = ReplaceString("\\", fullpath, ":")
458        HDF5CreateFile /Z fileID as fullpath
459        NXCansas_InitializeFile(fileID)
460        return fileID
461End
462
463// Initialize the file to a base state
464Function NxCansas_InitializeFile(fileID)
465        Variable fileID
466        String parent
467        String/G base = "root:NXcanSAS_file"
468        Make/T/N=1 $(base + ":vals") = {""}
469        Make/T/N=3 $(base + ":attr") = {"NX_class", "canSAS_class", "version"}
470        Make/T/N=3 $(base + ":attrVals") = {"NXentry", "SASentry", "1.0"}
471        parent = "/sasentry/"
472        CreateStrNxCansas(fileID,parent,"","",$(base + ":vals"),$(base + ":attr"),$(base + ":attrVals"))
473        Make/T/N=1 $(base + ":entryAttr") = {""}
474        Make/T/N=1 $(base + ":entryAttrVals") = {""}
475        CreateStrNxCansas(fileID,parent,"","definition",NxCansas_strPtToWave("NXcanSAS"),$(base + ":entryAttr"),$(base + ":entryAttrVals"))
476End
477
478//
479///////////////////////////////////////////////////////////////////////////
480
481///////////////////////////////////////////////////////////////////////////
482// Functions to put values into usable form for NxCansas
483
484// Convert a number to a string
485Function /WAVE NxCansas_varToWave(number)
486        Variable number
487        Wave returnWave
488        Make/N=1 returnWave = {number}
489        return returnWave
490End
491
492// Create a single point wave from a string
493Function /WAVE NxCansas_strPtToWave(str)
494        String str
495        Wave/T returnWave
496        Make/T/N=1 returnWave = {str}
497        return returnWave
498End
499
500//
501///////////////////////////////////////////////////////////////////////////
502
503///////////////////////////////////////////////////////////////////////////
504// Functions used to save data to file
505
506// Intermediate error handler for saving variable waves - this function should be called instead of saveNxCansas
507Function CreateVarNxCansas(fileID,parent,group,var,valueWave,attr,attrValues)
508        Variable fileID
509        String parent,group,var
510        Wave valueWave
511        Wave /T attr,attrValues
512        Variable err
513        err = saveNxCansasVars(fileID,parent,group,var,valueWave,attr,attrValues)
514        if(err)
515                Print "NxCansas write err = ",err
516        endif
517End
518// Intermediate error handler for saving string waves - this function should be called instead of saveNxCansas
519Function CreateStrNxCansas(fileID,parent,group,var,valueWave,attr,attrValues)
520        Variable fileID
521        String parent,group,var
522        Wave /T valueWave,attr,attrValues
523        Variable err
524        err = saveNxCansasStrs(fileID,parent,group,var,valueWave,attr,attrValues)
525        if(err)
526                Print "NxCansas write err = ",err
527        endif
528End
529
530Function NxCansas_writeAttributes(fileID,path,attrNames,attrVals)
531        Variable fileID
532        String path
533        Wave/T attrNames, attrVals
534        int numAttrs,i
535        numAttrs = numpnts(attrNames)
536        Duplicate/O/T attrNames, names
537        Duplicate/O/T attrVals, vals
538       
539        for(i=0; i < numAttrs; i += 1)
540                String name_i = names[i]
541                String vals_i = vals[i]
542                Make/T/N=1 vals_i_wave
543                vals_i_wave[0] = vals_i
544                if(!stringmatch(name_i,""))
545                        HDF5SaveData /A=name_i vals_i_wave, fileID, path
546                endif
547        endfor
548       
549End
550
551Function NxCansas_CreateGroup(fileID,parent)
552        Variable fileID
553        String parent
554        Variable groupID
555        try     
556                if(!fileID)
557                        abort "HDF5 file does not exist"
558                endif
559               
560                // Create the group if it doesn't already exist
561                HDF5CreateGroup /Z fileID, parent, groupID
562                       
563        catch
564                // DO something if error is thrown
565                Print "NxCansas write err in saveNxCansas = ",V_AbortCode
566        endtry
567        return groupID
568End
569
570// Write in a single NxCansas element (from the STRUCTURE)
571// This method should only be called by CreateVarNxCansas
572Function saveNxCansasVars(fileID,parent,group,var,valueWave,attr,attrValues)
573        Variable fileID
574        String parent,group,var
575        Wave valueWave
576        Wave /T attr,attrValues
577        int i, numAttrs
578       
579        variable err=0, groupID
580        String NXentry_name
581       
582        groupID = NxCansas_CreateGroup(fileID,parent)
583
584        // Save data to disk
585        if(!stringmatch(var,""))
586                HDF5SaveData /O /Z /IGOR=0 valueWave, groupID, var
587                if (V_flag != 0)
588                        err = 1
589                        abort "Cannot save wave to HDF5 dataset " + var + " with V_flag of " + num2str(V_flag)
590                endif
591        endif
592               
593        NxCansas_writeAttributes(fileID,parent+var,attr,attrValues)
594       
595        // Close group and file to release resources
596        if(groupID)
597                HDF5CloseGroup /Z groupID
598        endif
599
600        return err
601end
602
603// Write in a single NxCansas element
604// This method should only be called by CreateStrNxCansas
605Function saveNxCansasStrs(fileID,parent,group,var,valueWave,attr,attrValues)
606        Variable fileID
607        String parent,group,var
608        Wave /T attr,attrValues, valueWave
609        int i, numAttrs
610       
611        variable err=0, groupID
612        String NXentry_name
613       
614        groupID = NxCansas_CreateGroup(fileID,parent)
615
616        // Save data to disk
617        if(!stringmatch(var,""))
618                HDF5SaveData /O /Z /IGOR=0 valueWave, groupID, var
619                if (V_flag != 0)
620                        err = 1
621                        abort "Cannot save wave to HDF5 dataset " + var + " with V_flag of " + num2str(V_flag)
622                endif
623        endif
624               
625        NxCansas_writeAttributes(fileID,parent+var,attr,attrValues)
626       
627        // Close group and file to release resources
628        if(groupID)
629                HDF5CloseGroup /Z groupID
630        endif
631
632        return err
633end
634
635//
636///////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.