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

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

Bug fixes and clean up of 1D and 2D NXcanSAS writers. NXcollimator, not NXcollimation. Include time stamp in data file. Get detector name from data values. Change angstrom to A. Remove unused data folders and variable definitions.

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