source: sans/Dev/branches/nxcansas_writer/NCNR_User_Procedures/Common/NIST_NXcanSAS_v709.ipf @ 1187

Last change on this file since 1187 was 1187, checked in by krzywon, 3 years ago

Create a method to open or create a new file for all NXcanSAS writers.

File size: 31.9 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.15 20171003
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="", parentBase, nxcansasBase
27        String/G base = "root:NXcanSAS_file"
28       
29        // Define local waves
30        Wave/T vals,attr,attrVals
31       
32        // Define folder for data heirarchy
33        NewDataFolder/O/S root:NXcanSAS_file
34       
35        // Check fullpath and dialog
36        print "fullpath: ",fullpath
37        fileID = NXcanSAS_OpenOrCreate(dialog,fullpath,base)
38       
39        Variable sasentry = NumVarOrDefault("root:Packages:NIST:gSASEntryNumber", 1)
40        sPrintf parentBase,"%s:sasentry%d",base,sasentry // Igor memory base path for all
41        sPrintf nxcansasBase,"/sasentry%d/",sasentry // HDF5 base path for all
42
43        destStr = "root:Packages:NIST:"+type
44        //*****these waves MUST EXIST, or IGOR Pro will crash, with a type 2 error****
45        WAVE intw = $(destStr + ":integersRead")
46        WAVE rw = $(destStr + ":realsRead")
47        WAVE/T textw=$(destStr + ":textRead")
48        WAVE qvals =$(destStr + ":qval")
49        WAVE inten=$(destStr + ":aveint")
50        WAVE sig=$(destStr + ":sigave")
51        WAVE qbar = $(destStr + ":QBar")
52        WAVE sigmaq = $(destStr + ":SigmaQ")
53        WAVE fsubs = $(destStr + ":fSubS")
54
55        ///////////////////////////////////////////////////////////////////////////
56        // Write all data
57       
58        // Define common attribute waves
59        Make/T/O/N=1 empty = {""}
60        Make/T/O/N=1 units = {"units"}
61        Make/T/O/N=1 inv_cm = {"1/cm"}
62        Make/T/O/N=1 inv_angstrom = {"1/A"}
63       
64        // Run Name and title
65        NewDataFolder/O/S $(parentBase)
66        Make/O/T/N=1 $(parentBase + ":title") = {textw[6]}
67        CreateStrNxCansas(fileID,nxcansasBase,"","title",$(parentBase + ":title"),empty,empty)
68        Make/O/T/N=1 $(parentBase + ":run") = {textw[0]}
69        CreateStrNxCansas(fileID,nxcansasBase,"","run",$(parentBase + ":run"),empty,empty)
70       
71        // SASData
72        String dataParent = nxcansasBase + "sasdata/"
73        // Create SASdata entry
74        String dataBase = parentBase + ":sasdata"
75        NewDataFolder/O/S $(dataBase)
76        Make/O/T/N=5 $(dataBase + ":attr") = {"canSAS_class","signal","I_axes","NX_class","Q_indices", "timestamp"}
77        Make/O/T/N=5 $(dataBase + ":attrVals") = {"SASdata","I","Q","NXdata","0",textw[1]}
78        CreateStrNxCansas(fileID,dataParent,"","",empty,$(dataBase + ":attr"),$(dataBase + ":attrVals"))
79        // Create q entry
80        NewDataFolder/O/S $(dataBase + ":q")
81        Make/T/N=2 $(dataBase + ":q:attr") = {"units","resolutions"}
82        Make/T/N=2 $(dataBase + ":q:attrVals") = {"1/angstrom","Qdev"}
83        CreateVarNxCansas(fileID,dataParent,"sasdata","Q",qvals,$(dataBase + ":q:attr"),$(dataBase + ":q:attrVals"))
84        // Create i entry
85        NewDataFolder/O/S $(dataBase + ":i")
86        Make/O/T/N=2 $(dataBase + ":i:attr") = {"units","uncertainties"}
87        Make/O/T/N=2 $(dataBase + ":i:attrVals") = {"1/cm","Idev"}
88        CreateVarNxCansas(fileID,dataParent,"sasdata","I",inten,$(dataBase + ":i:attr"),$(dataBase + ":i:attrVals"))
89        // Create idev entry
90        CreateVarNxCansas(fileID,dataParent,"sasdata","Idev",sig,units,inv_cm)
91        // Create qdev entry
92        CreateVarNxCansas(fileID,dataParent,"sasdata","Qdev",sigmaq,units,inv_angstrom)
93        CreateVarNxCansas(fileID,dataParent,"sasdata","Qmean",qbar,units,inv_angstrom)
94       
95        // Write all meta data
96        WriteMetaData(fileID,parentBase,nxcansasBase,rw,textw)
97       
98        //
99        ///////////////////////////////////////////////////////////////////////////
100       
101        // Close the file
102        if(fileID)
103                HDF5CloseFile /Z fileID
104        endif
105       
106        KillDataFolder/Z $base
107       
108End
109
110//
111///////////////////////////////////////////////////////////////////////////
112
113
114///////////////////////////////////////////////////////////////////////////
115// - WriteNxCanSAS2D - Method for writing 2D NXcanSAS data
116// Creates an HDF5 file, generates reduced 2D data and stores all meta data
117// If dialog and fullpath are left blank (0 and ""), fake data will be used
118
119Function WriteNxCanSAS2D(type,fullpath,dialog)
120        // Define input variables
121        String type // data location, in memory, relative to root:Packages:NIST:
122        String fullpath // file path and name where data will be saved
123        Variable dialog // if 1, prompt user for file path, otherwise, use fullpath
124       
125        // Define local function variables
126        Variable fileID
127        String destStr="",typeStr="", parentBase, nxcansasBase
128        String/G base = "root:NXcanSAS_file"
129       
130        // Define local waves
131        Wave/T vals,attr,attrVals
132       
133        // Define folder for data heirarchy
134        NewDataFolder/O/S root:NXcanSAS_file
135       
136        // Check fullpath and dialog
137        fileID = NXcanSAS_OpenOrCreate(dialog,fullpath,base)
138
139        Variable sasentry = NumVarOrDefault("root:Packages:NIST:gSASEntryNumber", 1)
140        sPrintf parentBase,"%s:sasentry%d",base,sasentry // Igor memory base path for all
141        sPrintf nxcansasBase,"/sasentry%d/",sasentry // HDF5 base path for all
142       
143        destStr = "root:Packages:NIST:"+type
144
145        //must select the linear_data to export
146        NVAR isLog = $(destStr+":gIsLogScale")
147        if(isLog==1)
148                typeStr = ":linear_data"
149        else
150                typeStr = ":data"
151        endif
152        NVAR pixelsX = root:myGlobals:gNPixelsX
153        NVAR pixelsY = root:myGlobals:gNPixelsY
154        Wave data=$(destStr+typeStr)
155        Wave data_err=$(destStr+":linear_data_error")
156        WAVE intw=$(destStr + ":integersRead")
157        WAVE rw=$(destStr + ":realsRead")
158        WAVE/T textw=$(destStr + ":textRead")
159       
160        ///////////////////////////////////////////////////////////////////////////
161        // Compute Qx, Qy data from pixel space
162       
163        Duplicate/O data,qx_val,qy_val,z_val,qval,qz_val,phi,r_dist
164       
165        Variable xctr,yctr,sdd,lambda,pixSize
166        xctr = rw[16]
167        yctr = rw[17]
168        sdd = rw[18]
169        lambda = rw[26]
170        pixSize = rw[13]/10             //convert mm to cm (x and y are the same size pixels)
171       
172        qx_val = CalcQx(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10)          //+1 converts to detector coordinate system
173        qy_val = CalcQy(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10)
174       
175        Redimension/N=(pixelsX*pixelsY) qx_val,qy_val,z_val
176
177        Variable L2 = rw[18]
178        Variable BS = rw[21]
179        Variable S1 = rw[23]
180        Variable S2 = rw[24]
181        Variable L1 = rw[25]
182        Variable lambdaWidth = rw[27]   
183        Variable usingLenses = rw[28]           //new 2007
184
185        Variable vz_1 = 3.956e5         //velocity [cm/s] of 1 A neutron
186        Variable g = 981.0                              //gravity acceleration [cm/s^2]
187        Variable m_h    = 252.8                 // m/h [=] s/cm^2
188
189        Variable acc,ssd,lambda0,yg_d,qstar
190               
191        G = 981.  //!   ACCELERATION OF GRAVITY, CM/SEC^2
192        acc = vz_1              //      3.956E5 //!     CONVERT WAVELENGTH TO VELOCITY CM/SEC
193        SDD = L2        *100    //1317
194        SSD = L1        *100    //1627          //cm
195        lambda0 = lambda                //              15
196        YG_d = -0.5*G*SDD*(SSD+SDD)*(LAMBDA0/acc)^2
197        qstar = -2*pi/lambda0*2*yg_d/sdd
198
199        // the gravity center is not the resolution center
200        // gravity center = beam center
201        // resolution center = offset y = dy + (2)*yg_d
202        ///************
203        // do everything to write out the resolution too
204        // un-comment these if you want to write out qz_val and qval too, then use the proper save command
205        qval = CalcQval(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10)
206        qz_val = CalcQz(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10)
207        //      phi = FindPhi( pixSize*((p+1)-xctr) , pixSize*((q+1)-yctr))             //(dx,dy)
208        //      r_dist = sqrt(  (pixSize*((p+1)-xctr))^2 +  (pixSize*((q+1)-yctr))^2 )          //radial distance from ctr to pt
209        phi = FindPhi( pixSize*((p+1)-xctr) , pixSize*((q+1)-yctr)+(2)*yg_d)            //(dx,dy+yg_d)
210        r_dist = sqrt(  (pixSize*((p+1)-xctr))^2 +  (pixSize*((q+1)-yctr)+(2)*yg_d)^2 )         //radial distance from ctr to pt
211        Redimension/N=(pixelsX*pixelsY) qz_val,qval,phi,r_dist
212        Make/O/N=(2,pixelsX,pixelsY) qxy_vals
213        //everything in 1D now
214        Duplicate/O qval SigmaQX,SigmaQY
215        Make/O/N=(pixelsX,pixelsY) shadow
216        Make/O/N=(2,pixelsX,pixelsY) SigmaQ_combined
217
218        //Two parameters DDET and APOFF are instrument dependent.  Determine
219        //these from the instrument name in the header.
220        //From conversation with JB on 01.06.99 these are the current good values
221        Variable DDet
222        NVAR apOff = root:myGlobals:apOff               //in cm
223        DDet = rw[10]/10                        // header value (X) is in mm, want cm here
224
225        Variable ret1,ret2,ret3,jj
226        Variable nq = 0
227        Variable ii = 0
228       
229        do
230                jj = 0
231                do
232                        nq = ii * pixelsX + jj
233                        get2DResolution(qval[nq],phi[nq],lambda,lambdaWidth,DDet,apOff,S1,S2,L1,L2,BS,pixSize,usingLenses,r_dist[nq],ret1,ret2,ret3)
234                        qxy_vals[0][ii][jj] = qx_val[nq]
235                        qxy_vals[1][ii][jj] = qy_val[nq]
236                        SigmaQ_combined[0][ii][jj] = ret1       
237                        SigmaQ_combined[1][ii][jj] = ret2
238                        shadow[ii][jj] = ret3   
239                        jj+=1
240                while(jj<pixelsX)
241                ii+=1
242        while(ii<pixelsY)
243        //
244        ///////////////////////////////////////////////////////////////////////////
245
246       
247        ///////////////////////////////////////////////////////////////////////////
248        // Write all data
249       
250        // Define common attribute waves
251        Make/O/T/N=1 empty = {""}
252        Make/O/T/N=1 units = {"units"}
253        Make/O/T/N=1 inv_cm = {"1/cm"}
254        Make/O/T/N=1 inv_angstrom = {"1/A"}
255       
256        // Run Name and title
257        NewDataFolder/O/S $(parentBase)
258        Make/O/T/N=1 $(parentBase + ":title") = {textw[6]}
259        CreateStrNxCansas(fileID,nxcansasBase,"","title",$(parentBase + ":title"),empty,empty)
260        Make/O/T/N=1 $(parentBase + ":run") = {textw[0]}
261        CreateStrNxCansas(fileID,nxcansasBase,"","run",$(parentBase + ":run"),empty,empty)
262       
263        // SASData
264        String dataParent = nxcansasBase + "sasdata/"
265        // Create SASdata entry
266        String dataBase = parentBase + ":sasdata"
267        NewDataFolder/O/S $(dataBase)
268        Make/O/T/N=5 $(dataBase + ":attr") = {"canSAS_class","signal","I_axes","NX_class","Q_indices", "timestamp"}
269        Make/O/T/N=5 $(dataBase + ":attrVals") = {"SASdata","I","Q,Q","NXdata","0,1",textw[1]}
270        CreateStrNxCansas(fileID,dataParent,"","",empty,$(dataBase + ":attr"),$(dataBase + ":attrVals"))
271        // Create i entry
272        NewDataFolder/O/S $(dataBase + ":i")
273        Make/O/T/N=2 $(dataBase + ":i:attr") = {"units","uncertainties"}
274        Make/O/T/N=2 $(dataBase + ":i:attrVals") = {"1/cm","Idev"}
275        CreateVarNxCansas(fileID,dataParent,"sasdata","I",data,$(dataBase + ":i:attr"),$(dataBase + ":i:attrVals"))
276
277        //
278        // TODO: Reinstate Qdev/resolutions when I can fix the reader issue
279        //
280       
281
282        // Create qx and qy entry
283        NewDataFolder/O/S $(dataBase + ":q")
284        Make/O/T/N=2 $(dataBase + ":q:attr") = {"units"}//,"resolutions"}
285        Make/O/T/N=2 $(dataBase + ":q:attrVals") = {"1/angstrom"}//,"Qdev"}
286        CreateVarNxCansas(fileID,dataParent,"sasdata","Q",qxy_vals,$(dataBase + ":q:attr"),$(dataBase + ":q:attrVals"))
287       
288        // Create idev entry
289        CreateVarNxCansas(fileID,dataParent,"sasdata","Idev",data_err,units,inv_cm)
290        // Create qdev entry
291        CreateVarNxCansas(fileID,dataParent,"sasdata","Qdev",SigmaQ_combined,units,inv_angstrom)
292        // Create shadwfactor entry
293        CreateVarNxCansas(fileID,dataParent,"sasdata","ShadowFactor",shadow,empty,empty)
294       
295        // Write all meta data
296        WriteMetaData(fileID,parentBase,nxcansasBase,rw,textw)
297       
298        // Close the file
299        if(fileID)
300                HDF5CloseFile /Z fileID
301        endif
302       
303        KillDataFolder/Z $base
304       
305End
306
307//
308///////////////////////////////////////////////////////////////////////////
309
310///////////////////////////////////////////////////////////////////////////
311// - WriteMetaData - Method used to write non data elements into NXcanSAS
312// format. This is common between 1D and 2D data sets.
313
314Function WriteMetaData(fileID,base,parentBase,rw,textw)
315        String base,parentBase
316        Variable fileID
317        Wave rw
318        Wave/T textw
319       
320        // Define common attribute waves
321        Make/T/O/N=1 empty = {""}
322        Make/T/O/N=1 units = {"units"}
323        Make/T/O/N=1 m = {"m"}
324        Make/T/O/N=1 mm = {"mm"}
325        Make/T/O/N=1 cm = {"cm"}
326        Make/T/O/N=1 pixel = {"pixel"}
327        Make/T/O/N=1 angstrom = {"A"}
328       
329        // SASinstrument
330        String instrParent = parentBase + "sasinstrument/"
331        // Create SASinstrument entry
332        String instrumentBase = base + ":sasinstrument"
333        NewDataFolder/O/S $(instrumentBase)
334        Make/O/T/N=5 $(instrumentBase + ":attr") = {"canSAS_class","NX_class"}
335        Make/O/T/N=5 $(instrumentBase + ":attrVals") = {"SASinstrument","NXinstrument"}
336        CreateStrNxCansas(fileID,instrParent,"","",empty,$(instrumentBase + ":attr"),$(instrumentBase + ":attrVals"))
337       
338        // SASaperture
339        String apertureParent = instrParent + "sasaperture/"
340        // Create SASaperture entry
341        String apertureBase = instrumentBase + ":sasaperture"
342        NewDataFolder/O/S $(apertureBase)
343        Make/O/T/N=5 $(apertureBase + ":attr") = {"canSAS_class","NX_class"}
344        Make/O/T/N=5 $(apertureBase + ":attrVals") = {"SASaperture","NXaperture"}
345        CreateStrNxCansas(fileID,apertureParent,"","",empty,$(apertureBase + ":attr"),$(apertureBase + ":attrVals"))
346       
347        //
348        // TODO: Where do I get rectangular dimensions from?
349        //
350       
351        // Create SASaperture shape entry
352        Make/O/T/N=1 $(apertureBase + ":shape") = {"pinhole"}
353        CreateStrNxCansas(fileID,apertureParent,"sasaperture","shape",$(apertureBase + ":shape"),empty,empty)
354        // Create SASaperture x_gap entry
355        Make/O/N=1 $(apertureBase + ":x_gap") = {rw[24]}
356        CreateVarNxCansas(fileID,apertureParent,"sasaperture","x_gap",$(apertureBase + ":x_gap"),units,mm)
357        // Create SASaperture y_gap entry
358        Make/O/N=1 $(apertureBase + ":y_gap") = {rw[24]}
359        CreateVarNxCansas(fileID,apertureParent,"sasaperture","y_gap",$(apertureBase + ":y_gap"),units,mm)
360       
361        // SAScollimation
362        String collimationParent = instrParent + "sascollimation/"
363        // Create SAScollimation entry
364        String collimationBase = instrumentBase + ":sascollimation"
365        NewDataFolder/O/S $(collimationBase)
366        Make/O/T/N=5 $(collimationBase + ":attr") = {"canSAS_class","NX_class"}
367        Make/O/T/N=5 $(collimationBase + ":attrVals") = {"SAScollimation","NXcollimator"}
368        CreateStrNxCansas(fileID,collimationParent,"","",empty,$(collimationBase + ":attr"),$(collimationBase + ":attrVals"))
369        // Create SAScollimation distance entry
370        Make/O/N=1 $(collimationBase + ":distance") = {rw[25]}
371        CreateVarNxCansas(fileID,collimationParent,"sasaperture","distance",$(collimationBase + ":distance"),units,m)
372       
373        // SASdetector
374        String detectorParent = instrParent + "sasdetector/"
375        // Create SASdetector entry
376        String detectorBase = instrumentBase + ":sasdetector"
377        NewDataFolder/O/S $(detectorBase)
378        Make/O/T/N=5 $(detectorBase + ":attr") = {"canSAS_class","NX_class"}
379        Make/O/T/N=5 $(detectorBase + ":attrVals") = {"SASdetector","NXdetector"}
380        CreateStrNxCansas(fileID,detectorParent,"","",empty,$(detectorBase + ":attr"),$(detectorBase + ":attrVals"))
381        // Create SASdetector name entry
382        Make/O/T/N=1 $(detectorBase + ":name") = {textw[9]}
383        CreateStrNxCansas(fileID,detectorParent,"","name",$(detectorBase + ":name"),empty,empty)
384        // Create SASdetector distance entry
385        Make/O/N=1 $(detectorBase + ":SDD") = {rw[18]}
386        CreateVarNxCansas(fileID,detectorParent,"","SDD",$(detectorBase + ":SDD"),units,m)
387        // Create SASdetector beam_center_x entry
388        Make/O/N=1 $(detectorBase + ":beam_center_x") = {rw[16]}
389        CreateVarNxCansas(fileID,detectorParent,"","beam_center_x",$(detectorBase + ":beam_center_x"),units,pixel)
390        // Create SASdetector beam_center_y entry
391        Make/O/N=1 $(detectorBase + ":beam_center_y") = {rw[17]}
392        CreateVarNxCansas(fileID,detectorParent,"","beam_center_y",$(detectorBase + ":beam_center_y"),units,pixel)
393        // Create SASdetector x_pixel_size entry
394        Make/O/N=1 $(detectorBase + ":x_pixel_size") = {rw[10]}
395        CreateVarNxCansas(fileID,detectorParent,"","x_pixel_size",$(detectorBase + ":x_pixel_size"),units,mm)
396        // Create SASdetector y_pixel_size entry
397        Make/O/N=1 $(detectorBase + ":y_pixel_size") = {rw[13]}
398        CreateVarNxCansas(fileID,detectorParent,"","y_pixel_size",$(detectorBase + ":y_pixel_size"),units,mm)
399       
400        // SASsource
401        String sourceParent = instrParent + "sassource/"
402        // Create SASdetector entry
403        String sourceBase = instrumentBase + ":sassource"
404        NewDataFolder/O/S $(sourceBase)
405        Make/O/T/N=5 $(sourceBase + ":attr") = {"canSAS_class","NX_class"}
406        Make/O/T/N=5 $(sourceBase + ":attrVals") = {"SASsource","NXsource"}
407        CreateStrNxCansas(fileID,sourceParent,"","",empty,$(sourceBase + ":attr"),$(sourceBase + ":attrVals"))
408        // Create SASsource radiation entry
409        Make/O/T/N=1 $(sourceBase + ":radiation") = {"Reactor Neutron Source"}
410        CreateStrNxCansas(fileID,sourceParent,"","radiation",$(sourceBase + ":radiation"),empty,empty)
411        // Create SASsource incident_wavelength entry
412        Make/O/N=1 $(sourceBase + ":incident_wavelength") = {rw[26]}
413        CreateVarNxCansas(fileID,sourceParent,"","incident_wavelength",$(sourceBase + ":incident_wavelength"),units,angstrom)
414        // Create SASsource incident_wavelength_spread entry
415        Make/O/N=1 $(sourceBase + ":incident_wavelength_spread") = {rw[27]}
416        CreateVarNxCansas(fileID,sourceParent,"","incident_wavelength_spread",$(sourceBase + ":incident_wavelength_spread"),units,angstrom)
417       
418        // SASsample
419        String sampleParent = parentBase + "sassample/"
420        // Create SASsample entry
421        String sampleBase = base + ":sassample"
422        NewDataFolder/O/S $(sampleBase)
423        Make/O/T/N=5 $(sampleBase + ":attr") = {"canSAS_class","NX_class"}
424        Make/O/T/N=5 $(sampleBase + ":attrVals") = {"SASsample","NXsample"}
425        CreateStrNxCansas(fileID,sampleParent,"","",empty,$(sampleBase + ":attr"),$(sampleBase + ":attrVals"))
426        // Create SASsample name entry
427        Make/O/T/N=1 $(sampleBase + ":name") = {textw[6]}
428        CreateStrNxCansas(fileID,sampleParent,"","name",$(sampleBase + ":name"),empty,empty)
429        // Create SASsample thickness entry
430        Make/O/N=1 $(sampleBase + ":thickness") = {rw[5]}
431        CreateVarNxCansas(fileID,sampleParent,"","thickness",$(sampleBase + ":thickness"),units,cm)
432        // Create SASsample transmission entry
433        Make/O/N=1 $(sampleBase + ":transmission") = {rw[4]}
434        CreateVarNxCansas(fileID,sampleParent,"","transmission",$(sampleBase + ":transmission"),empty,empty)
435End
436       
437//
438///////////////////////////////////////////////////////////////////////////
439
440
441///////////////////////////////////////////////////////////////////////////
442//
443// Basic file open/create and file initialization routines
444
445// Generic open or create file
446Function NXcanSAS_OpenOrCreate(dialog,fullpath,base)
447        Variable dialog
448        String fullpath,base
449        Variable fileID
450        if(dialog || stringmatch(fullpath, ""))
451                fileID = NxCansas_DoSaveFileDialog(base)
452        else
453                fileID = NxCansas_CreateFile(fullpath,base)
454        Endif
455        if(!fileID)
456                abort "Unable to create file at " + fullpath + "."
457        EndIf
458        return fileID
459End
460
461// Select/create file through prompt
462Function NxCansas_DoSaveFileDialog(base)
463        String base
464        Variable refNum, fileID
465        String message = "Save a file"
466        String outputPath
467        String fileFilters = "Data Files (*.h5):.h5;"
468        fileFilters += "All Files:.*;"
469        Open /D /F=fileFilters /M=message refNum
470        outputPath = S_fileName
471        fileID = NxCansas_CreateFile(outputPath,base)
472        return fileID
473End
474
475// Create file with a known path
476Function NxCansas_CreateFile(fullpath, base)
477        String fullpath,base
478        Variable fileID
479        Make/T/O/N=1 $("root:file_name") = fullpath
480        fullpath = ReplaceString(":\\", fullpath, ":")
481        fullpath = ReplaceString("\\", fullpath, ":")
482        HDF5CreateFile /Z fileID as fullpath
483        NXCansas_InitializeFile(fileID, base)
484        return fileID
485End
486
487// Open\ file with a known path
488Function NxCansas_OpenFile(fullpath)
489        String fullpath
490        String fileName
491        Variable fileID
492        fileName = ParseFilePath(3,fullpath,":",0,0)
493        Make/T/O/N=1 $("root:file_name") = fileName
494        fullpath = ReplaceString(":\\", fullpath, ":")
495        fullpath = ReplaceString("\\", fullpath, ":")
496        HDF5OpenFile /Z fileID as fullpath
497        return fileID
498End
499
500// Select/create file through prompt
501Function NxCansas_DoOpenFileDialog()
502        Variable refNum,fileID
503        String message = "Select a file"
504        String inputPath,fileName
505        String fileFilters = "Data Files (*.h5):.h5;"
506        STRUCT HDF5BrowserData bd
507        fileFilters += "All Files:.*;"
508        Open /D /F=fileFilters /M=message refNum as fileName
509        inputPath = S_fileName
510        fileID = NxCansas_OpenFile(inputPath)
511        return fileID
512End
513
514// Initialize the file to a base state
515Function NxCansas_InitializeFile(fileID, base)
516        Variable fileID
517        String base
518        String parent,nxParent
519        Variable sasentry = NumVarOrDefault("root:Packages:NIST:gSASEntryNumber", 1)
520        sPrintf parent,":sasentry%d",sasentry
521        String location = base + parent
522        sPrintf nxParent,"/sasentry%d/",sasentry
523        NewDataFolder/O/S $(location)
524        Make/T/N=1 $(location + ":vals") = {""}
525        Make/T/N=3 $(location + ":attr") = {"NX_class", "canSAS_class", "version"}
526        Make/T/N=3 $(location + ":attrVals") = {"NXentry", "SASentry", "1.0"}
527        CreateStrNxCansas(fileID,nxParent,"","",$(location + ":vals"),$(location + ":attr"),$(location + ":attrVals"))
528        Make/T/N=1 $(location + ":entryAttr") = {""}
529        Make/T/N=1 $(location + ":entryAttrVals") = {""}
530        CreateStrNxCansas(fileID,nxParent,"","definition",{"NXcanSAS"},$(location + ":entryAttr"),$(location + ":entryAttrVals"))
531End
532
533//
534///////////////////////////////////////////////////////////////////////////
535
536///////////////////////////////////////////////////////////////////////////
537// Functions used to save data to file
538
539// Intermediate error handler for saving variable waves - this function should be called instead of saveNxCansas
540Function CreateVarNxCansas(fileID,parent,group,var,valueWave,attr,attrValues)
541        Variable fileID
542        String parent,group,var
543        Wave valueWave
544        Wave /T attr,attrValues
545        Variable err
546        err = saveNxCansasVars(fileID,parent,group,var,valueWave,attr,attrValues)
547        if(err)
548                Print "NxCansas write err = ",err
549        endif
550End
551// Intermediate error handler for saving string waves - this function should be called instead of saveNxCansas
552Function CreateStrNxCansas(fileID,parent,group,var,valueWave,attr,attrValues)
553        Variable fileID
554        String parent,group,var
555        Wave /T valueWave,attr,attrValues
556        Variable err
557        err = saveNxCansasStrs(fileID,parent,group,var,valueWave,attr,attrValues)
558        if(err)
559                Print "NxCansas write err = ",err
560        endif
561End
562
563Function NxCansas_writeAttributes(fileID,path,attrNames,attrVals)
564        Variable fileID
565        String path
566        Wave/T attrNames, attrVals
567        int numAttrs,i
568        numAttrs = numpnts(attrNames)
569        Duplicate/O/T attrNames, names
570        Duplicate/O/T attrVals, vals
571       
572        for(i=0; i < numAttrs; i += 1)
573                String name_i = names[i]
574                String vals_i = vals[i]
575                Make/T/N=1 vals_i_wave
576                vals_i_wave[0] = vals_i
577                if(!stringmatch(name_i,""))
578                        HDF5SaveData /A=name_i vals_i_wave, fileID, path
579                endif
580        endfor
581       
582End
583
584Function NxCansas_CreateGroup(fileID,parent)
585        Variable fileID
586        String parent
587        Variable groupID
588        try     
589                if(!fileID)
590                        abort "HDF5 file does not exist"
591                endif
592               
593                // Create the group if it doesn't already exist
594                HDF5CreateGroup /Z fileID, parent, groupID
595                       
596        catch
597                // DO something if error is thrown
598                Print "NxCansas write err in saveNxCansas = ",V_AbortCode
599        endtry
600        return groupID
601End
602
603// Write in a single NxCansas element (from the STRUCTURE)
604// This method should only be called by CreateVarNxCansas
605Function saveNxCansasVars(fileID,parent,group,var,valueWave,attr,attrValues)
606
607        Variable fileID
608        String parent,group,var
609        Wave valueWave
610        Wave /T attr,attrValues
611        int i, numAttrs
612       
613        variable err=0, groupID
614        String NXentry_name
615       
616        groupID = NxCansas_CreateGroup(fileID,parent)
617
618        // Save data to disk
619        if(!stringmatch(var,""))
620                HDF5SaveData /O /Z /IGOR=0 valueWave, groupID, var
621                if (V_flag != 0)
622                        err = 1
623                        abort "Cannot save wave to HDF5 dataset " + var + " with V_flag of " + num2str(V_flag)
624                endif
625        endif
626               
627        NxCansas_writeAttributes(fileID,parent+var,attr,attrValues)
628       
629        // Close group and file to release resources
630        if(groupID)
631                HDF5CloseGroup /Z groupID
632        endif
633
634        return err
635end
636
637// Write in a single NxCansas element
638// This method should only be called by CreateStrNxCansas
639Function saveNxCansasStrs(fileID,parent,group,var,valueWave,attr,attrValues)
640        Variable fileID
641        String parent,group,var
642        Wave /T attr,attrValues, valueWave
643        int i, numAttrs
644       
645        variable err=0, groupID
646        String NXentry_name
647       
648        groupID = NxCansas_CreateGroup(fileID,parent)
649
650        // Save data to disk
651        if(!stringmatch(var,""))
652                HDF5SaveData /O /Z /IGOR=0 valueWave, groupID, var
653                if (V_flag != 0)
654                        err = 1
655                        abort "Cannot save wave to HDF5 dataset " + var + " with V_flag of " + num2str(V_flag)
656                endif
657        endif
658               
659        NxCansas_writeAttributes(fileID,parent+var,attr,attrValues)
660       
661        // Close group and file to release resources
662        if(groupID)
663                HDF5CloseGroup /Z groupID
664        endif
665
666        return err
667end
668
669//
670///////////////////////////////////////////////////////////////////////////
671
672///////////////////////////////////////////////////////////////////////////
673//
674// NXcanSAS Reader and Utilities
675
676Function LoadNXcanSASData(fileStr,outstr,doPlot,forceOverwrite)
677        String fileStr, outstr
678        Variable doPlot,forceOverwrite
679       
680        Variable refnum,fileID
681        Variable rr,gg,bb
682        SetDataFolder root:             //build sub-folders for each data set under root
683       
684        String filename
685        String angst = StrVarOrDefault("root:Packages:NIST:gAngstStr", "A")
686       
687        // Check fullpath and dialog
688        if(stringmatch(fileStr, ""))
689                fileID = NxCansas_DoOpenFileDialog()
690        else
691                fileID = NxCansas_OpenFile(fileStr)
692        Endif
693       
694        filename = ParseFilePath(3,fileStr,":",0,0)
695        String basestr
696        if (!cmpstr(outstr, ""))                //Outstr = "", cmpstr returns 0
697                baseStr = ShortFileNameString(CleanupName(filename,0))
698                baseStr = CleanupName(baseStr,0)                //in case the user added odd characters
699        else
700                baseStr = outstr                        //for output, hopefully correct length as passed in
701        endif
702        String/G loadDir = "root:" + baseStr
703       
704        String I_dataStore = baseStr + "_i"
705        String Q_dataStore = baseStr + "_q"
706        String dQ_dataStore = baseStr + "_dq"
707        String dQl_dataStore = baseStr + "_dql"
708        String dQw_dataStore = baseStr + "_dqw"
709        String dI_dataStore = baseStr + "_s"
710       
711        //go back to the root folder and clean up before leaving
712        NewDataFolder/O/S $loadDir
713        Make/O/N=52 $(loadDir + ":realsRead")
714        Make/O/T/N=11 $(loadDir + ":textRead")
715       
716        if(fileID)
717                HDF5ListGroup /F/R/Type=1/Z fileID,"/"
718                String groupList = S_HDF5ListGroup
719               
720                //
721                // TODO: Differentiate between 1D, 2D, and USANS data (resolutions) (DO I NEED TO?)
722                //
723       
724                Variable groupID
725                Variable inc = 1
726                String entryUnformatted = "/sasentry%d/"
727                String entryBase
728                sPrintf entryBase,entryUnformatted,inc
729                // Open first group
730                HDF5OpenGroup /Z fileID, entryBase + "sasdata/", groupID
731                do
732                        // Load in data
733                        HDF5LoadData /O/Z/N=$I_dataStore fileID, entryBase + "sasdata/I"
734                        HDF5LoadData /O/Z/N=$Q_dataStore fileID, entryBase + "sasdata/Q"
735                        HDF5LoadData /O/Z/N=$dQ_dataStore fileID, entryBase + "sasdata/dQ"
736                        HDF5LoadData /O/Z/N=$dQl_dataStore fileID, entryBase + "sasdata/dQl"
737                        HDF5LoadData /O/Z/N=$dQw_dataStore fileID, entryBase + "sasdata/dQw"
738                        HDF5LoadData /O/Z/N=$dI_dataStore fileID, entryBase + "sasdata/Idev"
739                        // Load in Meta Data
740                        LoadMetaData(fileID,loadDir,entryBase)
741                        // Open next group to see if it exists
742                        inc += 1
743                        sPrintf entryBase,entryUnformatted,inc
744                        HDF5OpenGroup /Z fileID, entryBase + "sasdata/", groupID
745                while(groupID != 0)
746               
747                //plot if desired
748                if(doPlot)
749                        Print GetDataFolder(1)
750                       
751                        String w0 = Q_dataStore
752                        String w1 = I_dataStore
753                        String w2 = dI_dataStore
754                       
755                        // assign colors randomly
756                        rr = abs(trunc(enoise(65535)))
757                        gg = abs(trunc(enoise(65535)))
758                        bb = abs(trunc(enoise(65535)))
759                       
760                        // if target window is a graph, and user wants to append, do so
761                   DoWindow/B Plot_Manager
762                        if(WinType("") == 1)
763                                DoAlert 1,"Do you want to append this data to the current graph?"
764                               
765                                if(V_Flag == 1)
766                                        AppendToGraph $w1 vs $w0
767                                        ModifyGraph mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
768                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
769                                        ModifyGraph tickUnit(left)=1
770                                else
771                                //new graph
772                                        Display $w1 vs $w0
773                                        ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
774                                        ModifyGraph grid=1,mirror=2,standoff=0
775                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
776                                        ModifyGraph tickUnit(left)=1
777                                        Label left "I(q)"
778                                        Label bottom "q ("+angst+"\\S-1\\M)"
779                                        Legend
780                                endif
781                        else
782                        // graph window was not target, make new one
783                                Display $w1 vs $w0
784                                ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
785                                ModifyGraph grid=1,mirror=2,standoff=0
786                                ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
787                                ModifyGraph tickUnit(left)=1
788                                Label left "I(q)"
789                                Label bottom "q ("+angst+"\\S-1\\M)"
790                                Legend
791                        endif
792                endif
793               
794        endif
795       
796        // Close the file
797        if(fileID)
798                HDF5CloseFile /Z fileID
799        endif
800
801end
802
803Function LoadMetaData(fileID,loadDir,parentBase)
804        String parentBase,loadDir
805        Variable fileID
806        Variable groupID
807        SetDataFolder $(loadDir)
808        Wave rw = $(loadDir + ":realsRead")
809        Wave/T textw = $(loadDir + ":textRead")
810       
811        // Title
812        HDF5OpenGroup /Z fileID, parentBase, groupID
813        HDF5LoadData /O/Z/N=title fileID, parentBase + "title"
814        Wave/T title = $(loadDir + ":title")
815       
816        // SASinstrument
817        String instrParent = parentBase + "sasinstrument/"
818       
819        // SASaperture
820        String apertureParent = instrParent + "sasaperture/"
821        HDF5OpenGroup /Z fileID, apertureParent, groupID
822        HDF5LoadData /O/Z/N=xg fileID, apertureParent + "x_gap"
823        Wave xg = $(loadDir + ":xg")
824       
825        // SAScollimation
826        String collimationParent = instrParent + "sascollimation/"
827        HDF5OpenGroup /Z fileID, collimationParent, groupID
828        HDF5LoadData /O/Z/N=cdis fileID, collimationParent + "distance"
829        Wave cdis = $(loadDir + ":cdis")
830       
831        // SASdetector
832        String detectorParent = instrParent + "sasdetector/"
833        HDF5OpenGroup /Z fileID, detectorParent, groupID
834        HDF5LoadData /O/Z/N=detname fileID, detectorParent + "name"
835        HDF5LoadData /O/Z/N=sdd fileID, detectorParent + "SDD"
836        HDF5LoadData /O/Z/N=bcx fileID, detectorParent + "beam_center_x"
837        HDF5LoadData /O/Z/N=bcy fileID, detectorParent + "beam_center_y"
838        HDF5LoadData /O/Z/N=xps fileID, detectorParent + "x_pixel_size"
839        HDF5LoadData /O/Z/N=xpy fileID, detectorParent + "y_pixel_size"
840        Wave/T detname = $(loadDir + ":detname")
841        Wave sdd = $(loadDir + ":sdd")
842        Wave bcx = $(loadDir + ":bcx")
843        Wave bcy = $(loadDir + ":bcy")
844        Wave xps = $(loadDir + ":xps")
845        Wave xpy = $(loadDir + ":xpy")
846       
847        // SASsource
848        String sourceParent = instrParent + "sassource/"
849        HDF5OpenGroup /Z fileID, sourceParent, groupID
850        HDF5LoadData /O/Z/N=wvel fileID, sourceParent + "incident_wavelength"
851        HDF5LoadData /O/Z/N=wvels fileID, sourceParent + "incident_wavelength_spread"
852        Wave wvel = $(loadDir + ":wvel")
853        Wave wvels = $(loadDir + ":wvels")
854       
855        // SASsample
856        String sampleParent = parentBase + "sassample/"
857        HDF5OpenGroup /Z fileID, sampleParent, groupID
858        HDF5LoadData /O/Z/N=smplname fileID, sampleParent + "name"
859        HDF5LoadData /O/Z/N=smplthick fileID, sampleParent + "thickness"
860        HDF5LoadData /O/Z/N=smpltrans fileID, sampleParent + "transmission"
861        Wave/T smplname = $(loadDir + ":smplname")
862        Wave smplthick = $(loadDir + ":smplthick")
863        Wave smpltrans = $(loadDir + ":smpltrans")
864       
865        textw[0] = title[0]
866        textw[6] = smplname[0]
867        textw[9] = detname[0]
868        rw[4] = smplthick[0]
869        rw[5] = smpltrans[0]
870        rw[10] = xps[0]
871        rw[13] = xpy[0]
872        rw[16] = bcx[0]
873        rw[17] = bcy[0]
874        rw[18] = sdd[0]
875        rw[24] = xg[0]
876        rw[25] = cdis[0]
877        rw[26] = wvel[0]
878        rw[27] = wvels[0]
879       
880        KillWaves title,smplname,detname,smplthick,smpltrans,xps,xpy,bcx,bcy,sdd,xg,cdis,wvel,wvels
881       
882End
883
884//
885///////////////////////////////////////////////////////////////////////////
886
887
888///////////////////////////////////////////////////////////////////////////
889//
890// Generic Read/Write operations.
891
892//Needed to test whether file is NXcanSAS. The load routine will then either give an error if HDF5 XOP is not present or load the file if it is.
893Function isNXcanSAS(filestr)
894        String filestr
895       
896        Variable fileID=0,groupID=0
897        Int isHDF5File = 0
898       
899        fileID = NxCansas_OpenFile(filestr)
900        HDF5ListGroup /F/R/Type=1/Z fileID,"/"
901        Variable length = strlen(S_HDF5ListGroup)
902       
903        if (numtype(length) != 2)
904                isHDF5File = 1
905        endif
906       
907        if (fileID != 0)
908                // Close the file
909                HDF5CloseFile /Z fileID
910        endif
911       
912        return isHDF5File
913
914end
915
916//
917///////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.