source: sans/Dev/branches/nxcansas_writer/NCNR_User_Procedures/Reduction/USANS/WriteUSANSNXcanSAS.ipf @ 1173

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

Fixed most of the issues saving USANS data in NXcanSAS format.

File size: 16.2 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma Version=2.20
3#pragma IgorVersion=6.1
4
5#include <HDF5 Browser>
6
7//////////////////////////////////////////////////////////////////////////////////
8//
9// Write out an NXcanSAS compliant file using all known USANS information
10
11//************************
12// Vers 1.03 20190617
13//
14//************************
15
16//
17Function WriteUSANSNXcanSAS(type,fullpath,lo,hi,dialog)
18       
19        String type,fullpath
20        Variable lo,hi,dialog           //=1 will present dialog for name
21       
22        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
23        NVAR dQv = root:Packages:NIST:USANS:Globals:MainPanel:gDQv
24       
25        Variable fileID
26        String destStr=USANSFolder+":"+type
27        String dateStr=date()+" "+time()
28
29        String parentBase,nxcansasBase
30        String/G base = "root:NXcanSAS_USANS_file"
31       
32        Variable sasentry = NumVarOrDefault("root:Packages:NIST:gSASEntryNumber", 1)
33        sPrintf parentBase,"%s:sasentry%d",base,sasentry // Igor memory base path for all
34        sPrintf nxcansasBase,"/sasentry%d/",sasentry // HDF5 base path for all
35       
36        NewDataFolder/O/S $(base)
37       
38        // Define common attribute waves
39        Make/O/T/N=1 empty = {""}
40        Make/O/T/N=1 units = {"units"}
41        Make/O/T/N=1 m = {"m"}
42        Make/O/T/N=1 mm = {"mm"}
43        Make/O/T/N=1 cm = {"cm"}
44        Make/O/T/N=1 angstrom = {"A"}
45        Make/O/T/N=1 inv_cm = {"1/cm"}
46        Make/O/T/N=1 inv_angstrom = {"1/A"}
47       
48        Variable refNum,integer,realval
49               
50        if(dialog || stringmatch(fullpath, ""))
51                fileID = NxCansas_DoSaveFileDialog()
52        else
53                fileID = NxCansas_CreateFile(fullpath)
54        Endif
55       
56        if(!fileID)
57                abort "Unable to create file at " + fullpath + "."
58        else
59                //*****these waves MUST EXIST, or IGOR Pro will crash, with a type 2 error****
60                WAVE qvals = $(destStr + ":Qvals")
61                WAVE inten = $(destStr + ":DetCts")
62                WAVE sig = $(destStr + ":ErrDetCts")
63        endif
64       
65        //check each wave
66        If(!(WaveExists(qvals)))
67                Abort "qvals DNExist in WriteUSANSWaves()"
68        Endif
69        If(!(WaveExists(inten)))
70                Abort "inten DNExist in WriteUSANSWaves()"
71        Endif
72        If(!(WaveExists(sig)))
73                Abort "sig DNExist in WriteUSANSWaves()"
74        Endif
75       
76        //write out partial set?
77        Duplicate/O qvals,tq,ti,te
78        ti=inten
79        te=sig
80        if( (lo!=hi) && (lo<hi))
81                redimension/N=(hi-lo+1) tq,ti,te,dumWave                //lo to hi, inclusive
82                tq=qvals[p+lo]
83                ti=inten[p+lo]
84                te=sig[p+lo]
85        endif
86       
87        //Use the evil extra column for the resolution "information". Should probably switch to using slit_length in collimation.
88        Duplicate/O qvals,dumWave
89        dumWave = dQv
90       
91        Make/O/N= (numpnts(dumWave)) dQw = 0
92       
93        // Run Name and title
94        NewDataFolder/O/S $(parentBase)
95       
96        //
97        // FIXME: Get useful title - For now, sending empty string
98        //
99       
100        Make/T/N=1 $(parentBase + ":title") = {""} //StringByKey("LABEL",note(inten),":",";")}
101        CreateStrNxCansas(fileID,nxcansasBase,"","title",$(parentBase + ":title"),empty,empty)
102       
103        //
104        // TODO: Any way to programatically get the old filename?
105        //
106       
107        Make/T/N=1 $(parentBase + ":run") = {""}
108        CreateStrNxCansas(fileID,nxcansasBase,"","run",$(parentBase + ":run"),empty,empty)
109       
110        // SASData
111        String dataParent = nxcansasBase + "sasdata/"
112        // Create SASdata entry
113        String dataBase = parentBase + ":sasdata"
114        NewDataFolder/O/S $(dataBase)
115        Make/O/T/N=5 $(dataBase + ":attr") = {"canSAS_class","signal","I_axes","NX_class","Q_indices", "timestamp"}
116        Make/O/T/N=5 $(dataBase + ":attrVals") = {"SASdata","I","Q","NXdata","0",dateStr}
117        CreateStrNxCansas(fileID,dataParent,"","",empty,$(dataBase + ":attr"),$(dataBase + ":attrVals"))
118        // Create q entry
119        NewDataFolder/O/S $(dataBase + ":q")
120        Make/T/N=2 $(dataBase + ":q:attr") = {"units","resolutions"}
121        Make/T/N=2 $(dataBase + ":q:attrVals") = {"1/angstrom","dQl,dQw"}
122        CreateVarNxCansas(fileID,dataParent,"sasdata","Q",tq,$(dataBase + ":q:attr"),$(dataBase + ":q:attrVals"))
123        // Create i entry
124        NewDataFolder/O/S $(dataBase + ":i")
125        Make/T/N=2 $(dataBase + ":i:attr") = {"units","uncertainties"}
126        Make/T/N=2 $(dataBase + ":i:attrVals") = {"1/cm","Idev"}
127        CreateVarNxCansas(fileID,dataParent,"sasdata","I",ti,$(dataBase + ":i:attr"),$(dataBase + ":i:attrVals"))
128        // Create idev entry
129        CreateVarNxCansas(fileID,dataParent,"sasdata","Idev",te,units,inv_cm)
130        // Create qdev entry
131        CreateVarNxCansas(fileID,dataParent,"sasdata","dQl",dumWave,units,inv_angstrom)
132        CreateVarNxCansas(fileID,dataParent,"sasdata","dQw",dQw,units,inv_angstrom)
133       
134        // Write the meta data to the file
135        WriteUSANSNXcanSASMetaData(fileID,type,parentBase,nxcansasBase,dateStr)
136       
137        //write confirmation of write operation to history area
138        Print "Averaged NXcanSAS File written: ", GetFileNameFromPathNoSemi(fullPath)
139        KillWaves/Z dumWave
140        KillDataFolder/Z $base
141       
142        // Close the file
143        if(fileID)
144                HDF5CloseFile /Z fileID
145        endif
146       
147End
148
149Function WriteNXcanSASUSANSDesmeared(fullpath,lo,hi,dialog)
150       
151        String fullpath
152        Variable lo,hi,dialog           //=1 will present dialog for name
153       
154        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
155        NVAR dQv = root:Packages:NIST:USANS:Globals:MainPanel:gDQv
156       
157        Variable fileID
158        String destStr=""
159        destStr = USANSFolder+":DSM"
160        String dateStr=date()+" "+time()
161
162        String parentBase,nxcansasBase
163        String/G base = "root:NXcanSAS_USANS_file"
164       
165        Variable sasentry = NumVarOrDefault("root:Packages:NIST:gSASEntryNumber", 1)
166        sPrintf parentBase,"%s:sasentry%d",base,sasentry // Igor memory base path for all
167        sPrintf nxcansasBase,"/sasentry%d/",sasentry // HDF5 base path for all
168       
169        KillDataFolder/Z $base
170       
171        // Define common attribute waves
172        Make/T/N=1 empty = {""}
173        Make/T/N=1 units = {"units"}
174        Make/T/N=1 m = {"m"}
175        Make/T/N=1 mm = {"mm"}
176        Make/T/N=1 cm = {"cm"}
177        Make/T/N=1 angstrom = {"A"}
178        Make/T/N=1 inv_cm = {"1/cm"}
179        Make/T/N=1 inv_angstrom = {"1/A"}
180       
181        Variable refNum,integer,realval
182       
183        //*****these waves MUST EXIST, or IGOR Pro will crash, with a type 2 error****
184        WAVE qvals =$(destStr + "Q_dsm")
185        WAVE inten=$(destStr + "I_dsm")
186        WAVE sig=$(destStr + "S_dsm")
187               
188        if(dialog || stringmatch(fullpath, ""))
189                fileID = NxCansas_DoSaveFileDialog()
190        else
191                fileID = NxCansas_CreateFile(fullpath)
192        Endif
193       
194        //check each wave
195        If(!(WaveExists(qvals)))
196                Abort "qvals DNExist in WriteUSANSWaves()"
197        Endif
198        If(!(WaveExists(inten)))
199                Abort "inten DNExist in WriteUSANSWaves()"
200        Endif
201        If(!(WaveExists(sig)))
202                Abort "sig DNExist in WriteUSANSWaves()"
203        Endif
204       
205        //Use the evil extra column for the resolution "information". Should probably switch to using slit_length in collimation.
206        //write out partial set?
207        Duplicate/O qvals,tq,ti,te
208        ti=inten
209        te=sig
210        if( (lo!=hi) && (lo<hi))
211                redimension/N=(hi-lo+1) tq,ti,te,res1,res2,res3         //lo to hi, inclusive
212                tq=qvals[p+lo]
213                ti=inten[p+lo]
214                te=sig[p+lo]
215        endif
216       
217        Make/N= (numpnts(dumWave)) dQw = 0
218       
219        // Run Name and title
220        NewDataFolder/O/S $(parentBase)
221        Make/T/N=1 $(parentBase + ":title") = {StringByKey("LABEL",note(inten),":",";")}
222        CreateStrNxCansas(fileID,nxcansasBase,"","title",$(parentBase + ":title"),empty,empty)
223        Make/T/N=1 $(parentBase + ":run") = {""}
224        CreateStrNxCansas(fileID,nxcansasBase,"","run",$(parentBase + ":run"),empty,empty)
225       
226        // SASData
227        String dataParent = nxcansasBase + "sasdata/"
228        // Create SASdata entry
229        String dataBase = parentBase + ":sasdata"
230        NewDataFolder/O/S $(dataBase)
231        Make/O/T/N=5 $(dataBase + ":attr") = {"canSAS_class","signal","I_axes","NX_class","Q_indices", "timestamp"}
232        Make/O/T/N=5 $(dataBase + ":attrVals") = {"SASdata","I","Q","NXdata","0",dateStr}
233        CreateStrNxCansas(fileID,dataParent,"","",empty,$(dataBase + ":attr"),$(dataBase + ":attrVals"))
234        // Create q entry
235        NewDataFolder/O/S $(dataBase + ":q")
236        Make/T/N=2 $(dataBase + ":q:attr") = {"units","resolutions"}
237        Make/T/N=2 $(dataBase + ":q:attrVals") = {"1/angstrom","dQ"}
238        CreateVarNxCansas(fileID,dataParent,"sasdata","Q",tq,$(dataBase + ":q:attr"),$(dataBase + ":q:attrVals"))
239        // Create i entry
240        NewDataFolder/O/S $(dataBase + ":i")
241        Make/T/N=2 $(dataBase + ":i:attr") = {"units","uncertainties"}
242        Make/T/N=2 $(dataBase + ":i:attrVals") = {"1/cm","Idev"}
243        CreateVarNxCansas(fileID,dataParent,"sasdata","I",ti,$(dataBase + ":i:attr"),$(dataBase + ":i:attrVals"))
244        // Create idev entry
245        CreateVarNxCansas(fileID,dataParent,"sasdata","Idev",te,units,inv_cm)
246        // Create qdev entry
247        CreateVarNxCansas(fileID,dataParent,"sasdata","dQl",dumWave,units,inv_angstrom)
248        CreateVarNxCansas(fileID,dataParent,"sasdata","dQw",res1,units,inv_angstrom)
249        CreateVarNxCansas(fileID,dataParent,"sasdata","Qmean",res2,units,inv_angstrom)
250
251        // Write USANS meta data
252        WriteUSANSNXcanSASMetaData(fileID,"SMEARED",parentBase,nxcansasBase,dateStr)
253       
254        //write confirmation of write operation to history area
255        Print "Averaged NXcanSAS File written: ", GetFileNameFromPathNoSemi(fullPath)
256        KillWaves/Z dumWave
257        KillDataFolder/Z $base
258       
259        // Close the file
260        if(fileID)
261                HDF5CloseFile /Z fileID
262        endif
263       
264End     
265
266Function WriteUSANSNXcanSASMetaData(fileID,type,parentBase,nxcansasBase,dateStr)
267        Variable fileID
268        String type,parentBase,nxcansasBase,dateStr
269       
270        // tailor the output given the type of data written out...
271        SVAR USANSFolder = root:Packages:NIST:USANS:Globals:gUSANSFolder
272        WAVE inten_EMP=$(USANSFolder+":EMP:DetCts")
273        String samStr="",empStr="",samLabelStr="",paramStr="",empLevStr="",bkgLevStr=""
274        String pkStr="", processNote=""
275        NVAR TransWide = $(USANSFolder+":Globals:MainPanel:gTransWide")
276        NVAR TransRock = $(USANSFolder+":Globals:MainPanel:gTransRock")
277        NVAR empCts = $(USANSFolder+":Globals:MainPanel:gEmpCts")
278        NVAR bkgCts = $(USANSFolder+":Globals:MainPanel:gBkgCts")
279        NVAR thick = $(USANSFolder+":Globals:MainPanel:gThick")
280       
281        strswitch(type)
282                case "SAM":             
283                        samStr = type +" FILES: "+StringByKey("FILE",note(inten),":",";")
284                        empStr = "Uncorrected SAM data"
285                        empLevStr = "Uncorrected SAM data"
286                        bkgLevStr = "Uncorrected SAM data"
287                        paramStr = "Uncorrected SAM data"
288                        pkStr += "SAM PEAK ANGLE: "+num2str(QpkFromNote("SAM"))
289                        break                                           
290                case "EMP":     
291                        samStr = type +" FILES: "+StringByKey("FILE",note(inten),":",";")
292                        empStr = "Uncorrected EMP data"
293                        empLevStr = "Uncorrected EMP data"
294                        bkgLevStr = "Uncorrected EMP data"
295                        paramStr = "Uncorrected EMP data"
296                        pkStr += "EMP PEAK ANGLE: "+num2str(QpkFromNote("EMP"))
297                        break
298                case "SMEARED":
299                        samStr = "SMEARED FILES: "+StringByKey("FILE",note(inten),":",";")
300                        empStr = "EMP FILES: "+StringByKey("FILE",note(inten_EMP),":",";")     
301                        empLevStr = "EMP LEVEL: " + num2str(empCts)
302                        bkgLevStr = "BKG LEVEL: " + num2str(bkgCts)
303                        paramStr = "Ds = "+num2str(thick)+" cm ; "
304                        paramStr += "Twide = "+num2Str(TransWide)+" ; "
305                        paramStr += "Trock = "+num2str(TransRock)       
306                        pkStr += "SAM PEAK ANGLE: "+num2str(QpkFromNote("SAM"))
307                        pkStr += " ; EMP PEAK ANGLE: "+num2str(QpkFromNote("EMP"))
308                default:                //"COR" is the default 
309                        samStr = type +" FILES: "+StringByKey("FILE",note(inten),":",";")
310                        empStr = "EMP FILES: "+StringByKey("FILE",note(inten_EMP),":",";")     
311                        empLevStr = "EMP LEVEL: " + num2str(empCts)
312                        bkgLevStr = "BKG LEVEL: " + num2str(bkgCts)
313                        paramStr = "Ds = "+num2str(thick)+" cm ; "
314                        paramStr += "Twide = "+num2Str(TransWide)+" ; "
315                        paramStr += "Trock = "+num2str(TransRock)       
316                        pkStr += "SAM PEAK ANGLE: "+num2str(QpkFromNote("SAM"))
317                        pkStr += " ; EMP PEAK ANGLE: "+num2str(QpkFromNote("EMP"))                             
318        endswitch
319
320        processNote = samStr+"\n"+dateStr+"\n"+samLabelStr+"\n"+empStr+"\n"+paramStr+"\n"+pkStr+"\n"
321        processNote += empLevStr + " ; "+bkglevStr+"\n"
322       
323        Make/O/T/N=1 empty = {""}
324        Make/O/T/N=1 units = {"units"}
325        Make/O/T/N=1 m = {"m"}
326        Make/O/T/N=1 mm = {"mm"}
327        Make/O/T/N=1 cm = {"cm"}
328        Make/O/T/N=1 angstrom = {"A"}
329        Make/O/T/N=1 inv_cm = {"1/cm"}
330        Make/O/T/N=1 inv_angstrom = {"1/A"}
331       
332        // SASinstrument
333        String instrParent = nxcansasBase + "sasinstrument/"
334        // Create SASinstrument entry
335        String instrumentBase = parentBase + ":sasinstrument"
336        NewDataFolder/O/S $(instrumentBase)
337        Make/O/T/N=5 $(instrumentBase + ":attr") = {"canSAS_class","NX_class"}
338        Make/O/T/N=5 $(instrumentBase + ":attrVals") = {"SASinstrument","NXinstrument"}
339        CreateStrNxCansas(fileID,instrParent,"","",empty,$(instrumentBase + ":attr"),$(instrumentBase + ":attrVals"))
340       
341        // SASaperture
342        String apertureParent = instrParent + "sasaperture/"
343        // Create SASaperture entry
344        String apertureBase = instrumentBase + ":sasaperture"
345        NewDataFolder/O/S $(apertureBase)
346        Make/O/T/N=5 $(apertureBase + ":attr") = {"canSAS_class","NX_class"}
347        Make/O/T/N=5 $(apertureBase + ":attrVals") = {"SASaperture","NXaperture"}
348        CreateStrNxCansas(fileID,apertureParent,"","",empty,$(apertureBase + ":attr"),$(apertureBase + ":attrVals"))
349        // Create SASaperture shape entry
350        Make/O/T/N=1 $(apertureBase + ":shape") = {"slit"}
351        CreateStrNxCansas(fileID,apertureParent,"sasaperture","shape",$(apertureBase + ":shape"),empty,empty)
352        // Create SASaperture x_gap entry
353        Make/O/N=1 $(apertureBase + ":x_gap") = {0.1}
354        CreateVarNxCansas(fileID,apertureParent,"sasaperture","x_gap",$(apertureBase + ":x_gap"),units,cm)
355        // Create SASaperture y_gap entry
356        Make/O/N=1 $(apertureBase + ":y_gap") = {5.0}
357        CreateVarNxCansas(fileID,apertureParent,"sasaperture","y_gap",$(apertureBase + ":y_gap"),units,cm)
358
359        // SASdetector
360        String detectorParent = instrParent + "sasdetector/"
361        // Create SASdetector entry
362        String detectorBase = instrumentBase + ":sasdetector"
363        NewDataFolder/O/S $(detectorBase)
364        Make/O/T/N=2 $(detectorBase + ":attr") = {"canSAS_class","NX_class"}
365        Make/O/T/N=2 $(detectorBase + ":attrVals") = {"SASdetector","NXdetector"}
366        CreateStrNxCansas(fileID,detectorParent,"","",empty,$(detectorBase + ":attr"),$(detectorBase + ":attrVals"))
367        // Create SASdetector name entry
368        Make/O/T/N=1 $(detectorBase + ":name") = {"BT5 DETECTOR ARRAY"}
369        CreateStrNxCansas(fileID,detectorParent,"","name",$(detectorBase + ":name"),empty,empty)
370
371        // SASsource
372        String sourceParent = instrParent + "sassource/"
373        // Create SASdetector entry
374        String sourceBase = instrumentBase + ":sassource"
375        NewDataFolder/O/S $(sourceBase)
376        Make/O/T/N=2 $(sourceBase + ":attr") = {"canSAS_class","NX_class"}
377        Make/O/T/N=2 $(sourceBase + ":attrVals") = {"SASsource","NXsource"}
378        CreateStrNxCansas(fileID,sourceParent,"","",empty,$(sourceBase + ":attr"),$(sourceBase + ":attrVals"))
379        // Create SASsource radiation entry
380        Make/O/T/N=1 $(sourceBase + ":radiation") = {"Reactor Neutron Source"}
381        CreateStrNxCansas(fileID,sourceParent,"","radiation",$(sourceBase + ":radiation"),empty,empty)
382        // Create SASsource incident_wavelength entry
383        Make/O/N=1 $(sourceBase + ":incident_wavelength") = {2.38}
384        CreateVarNxCansas(fileID,sourceParent,"","incident_wavelength",$(sourceBase + ":incident_wavelength"),units,angstrom)
385        // Create SASsource incident_wavelength_spread entry
386        Make/O/N=1 $(sourceBase + ":incident_wavelength_spread") = {0.06}
387        CreateVarNxCansas(fileID,sourceParent,"","incident_wavelength_spread",$(sourceBase + ":incident_wavelength_spread"),units,angstrom)
388       
389        // SASsample
390        String sampleParent = nxcansasBase + "sassample/"
391        // Create SASsample entry
392        String sampleBase = parentBase + ":sassample"
393        NewDataFolder/O/S $(sampleBase)
394        Make/O/T/N=5 $(sampleBase + ":attr") = {"canSAS_class","NX_class"}
395        Make/O/T/N=5 $(sampleBase + ":attrVals") = {"SASsample","NXsample"}
396        CreateStrNxCansas(fileID,sampleParent,"","",empty,$(sampleBase + ":attr"),$(sampleBase + ":attrVals"))
397        // Create SASsample name entry
398       
399        //
400        // FIXME: reinstate sample name once format is correct (same as title)
401        //
402       
403        Make/O/T/N=1 $(sampleBase + ":name") = {StringByKey("LABEL",note(inten),":",";")}
404        CreateStrNxCansas(fileID,sampleParent,"","name",$(sampleBase + ":name"),empty,empty)
405        // Create SASsample thickness entry
406        Make/O/N=1 $(sampleBase + ":thickness") = {thick}
407        CreateVarNxCansas(fileID,sampleParent,"","thickness",$(sampleBase + ":thickness"),units,cm)
408        // Create SASsample transmission entry
409        Make/O/N=1 $(sampleBase + ":transmission") = {TransWide}
410        CreateVarNxCansas(fileID,sampleParent,"","transmission",$(sampleBase + ":transmission"),empty,empty)
411       
412        // SASProcess
413        String processParent = nxcansasBase + "sasprocess/"
414        // Create SASsample entry
415        String processBase = parentBase + ":sasprocess"
416        NewDataFolder/O/S $(processBase)
417        Make/O/T/N=2 $(processBase + ":attr") = {"canSAS_class","NX_class"}
418        Make/O/T/N=2 $(processBase + ":attrVals") = {"SASprocess","NXprocess"}
419        CreateStrNxCansas(fileID,processParent,"","",empty,$(processBase + ":attr"),$(processBase + ":attrVals"))
420        // Create SASsample name entry
421        Make/O/T/N=1 $(processBase + ":name") = {"NIST IGOR"}
422        CreateStrNxCansas(fileID,processParent,"","name",$(processBase + ":name"),empty,empty)
423        // Create SASsample thickness entry
424        Make/O/T/N=1 $(processBase + ":processnote") = {processNote}
425        CreateStrNxCansas(fileID,processParent,"","note",$(processBase + ":processnote"),empty,empty)
426End
Note: See TracBrowser for help on using the repository browser.