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

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

Incorporate suggested changes for cleaner separation of VSANS, USANS, and SANS reduction methods. Plus fixes.

File size: 14.3 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//
15// Basic file open/create and file initialization routines
16
17// Generic open or create file
18Function NXcanSAS_OpenOrCreate(dialog,fullpath,base)
19        Variable dialog
20        String fullpath,base
21        Variable fileID
22        if(dialog || stringmatch(fullpath, ""))
23                fileID = NxCansas_DoSaveFileDialog(base)
24        else
25                fileID = NxCansas_CreateFile(fullpath,base)
26        Endif
27        if(!fileID)
28                abort "Unable to create file at " + fullpath + "."
29        EndIf
30        return fileID
31End
32
33// Select/create file through prompt
34Function NxCansas_DoSaveFileDialog(base)
35        String base
36        Variable refNum, fileID
37        String message = "Save a file"
38        String outputPath
39        String fileFilters = "Data Files (*.h5):.h5;"
40        fileFilters += "All Files:.*;"
41        Open /D /F=fileFilters /M=message refNum
42        outputPath = S_fileName
43        fileID = NxCansas_CreateFile(outputPath,base)
44        return fileID
45End
46
47// Create file with a known path
48Function NxCansas_CreateFile(fullpath, base)
49        String fullpath,base
50        Variable fileID
51        Make/T/O/N=1 $("root:NXfile_name") = fullpath
52        fullpath = ReplaceString(":\\", fullpath, ":")
53        fullpath = ReplaceString("\\", fullpath, ":")
54        HDF5CreateFile /O/Z fileID as fullpath
55        NXCansas_InitializeFile(fileID, base)
56        return fileID
57End
58
59// Open\ file with a known path
60Function NxCansas_OpenFile(fullpath)
61        String fullpath
62        String fileName
63        Variable fileID
64        fileName = ParseFilePath(3,fullpath,":",0,0)
65        Make/T/O/N=1 $("root:NXfile_name") = fileName
66        fullpath = ReplaceString(":\\", fullpath, ":")
67        fullpath = ReplaceString("\\", fullpath, ":")
68        HDF5OpenFile /Z fileID as fullpath
69        return fileID
70End
71
72// Select/create file through prompt
73Function NxCansas_DoOpenFileDialog()
74        Variable refNum,fileID
75        String message = "Select a file"
76        String inputPath,fileName
77        String fileFilters = "Data Files (*.h5):.h5;"
78        STRUCT HDF5BrowserData bd
79        fileFilters += "All Files:.*;"
80        Open /D /F=fileFilters /M=message refNum as fileName
81        inputPath = S_fileName
82        fileID = NxCansas_OpenFile(inputPath)
83        return fileID
84End
85
86// Initialize the file to a base state
87Function NxCansas_InitializeFile(fileID, base)
88        Variable fileID
89        String base
90        String parent,nxParent
91        Variable sasentry = NumVarOrDefault("root:Packages:NIST:gSASEntryNumber", 1)
92        sPrintf parent,":sasentry%d",sasentry
93        String location = base + parent
94        sPrintf nxParent,"/sasentry%d/",sasentry
95        NewDataFolder/O/S $(location)
96        Make/O/T/N=1 $(location + ":vals") = {""}
97        Make/O/T/N=3 $(location + ":attr") = {"NX_class", "canSAS_class", "version"}
98        Make/O/T/N=3 $(location + ":attrVals") = {"NXentry", "SASentry", "1.0"}
99        CreateStrNxCansas(fileID,nxParent,"","",$(location + ":vals"),$(location + ":attr"),$(location + ":attrVals"))
100        Make/O/T/N=1 $(location + ":entryAttr") = {""}
101        Make/O/T/N=1 $(location + ":entryAttrVals") = {""}
102        CreateStrNxCansas(fileID,nxParent,"","definition",{"NXcanSAS"},$(location + ":entryAttr"),$(location + ":entryAttrVals"))
103End
104
105//
106///////////////////////////////////////////////////////////////////////////
107
108///////////////////////////////////////////////////////////////////////////
109// Functions used to save data to file
110
111// Intermediate error handler for saving variable waves - this function should be called instead of saveNxCansas
112Function CreateVarNxCansas(fileID,parent,group,var,valueWave,attr,attrValues)
113        Variable fileID
114        String parent,group,var
115        Wave valueWave
116        Wave /T attr,attrValues
117        Variable err
118        err = saveNxCansasVars(fileID,parent,group,var,valueWave,attr,attrValues)
119        if(err)
120                Print "NxCansas write err = ",err
121        endif
122End
123// Intermediate error handler for saving string waves - this function should be called instead of saveNxCansas
124Function CreateStrNxCansas(fileID,parent,group,var,valueWave,attr,attrValues)
125        Variable fileID
126        String parent,group,var
127        Wave /T valueWave,attr,attrValues
128        Variable err
129        err = saveNxCansasStrs(fileID,parent,group,var,valueWave,attr,attrValues)
130        if(err)
131                Print "NxCansas write err = ",err
132        endif
133End
134
135Function NxCansas_writeAttributes(fileID,path,attrNames,attrVals)
136        Variable fileID
137        String path
138        Wave/T attrNames, attrVals
139        int numAttrs,i
140        numAttrs = numpnts(attrNames)
141        Duplicate/O/T attrNames, names
142        Duplicate/O/T attrVals, vals
143       
144        for(i=0; i < numAttrs; i += 1)
145                String name_i = names[i]
146                String vals_i = vals[i]
147                Make/O/T/N=1 vals_i_wave
148                vals_i_wave[0] = vals_i
149                if(!stringmatch(name_i,""))
150                        HDF5SaveData /A=name_i vals_i_wave, fileID, path
151                endif
152        endfor
153       
154End
155
156Function NxCansas_CreateGroup(fileID,parent)
157        Variable fileID
158        String parent
159        Variable groupID
160        try     
161                if(!fileID)
162                        abort "HDF5 file does not exist"
163                endif
164               
165                // Create the group if it doesn't already exist
166                HDF5CreateGroup /Z fileID, parent, groupID
167                       
168        catch
169                // DO something if error is thrown
170                Print "NxCansas write err in saveNxCansas = ",V_AbortCode
171        endtry
172        return groupID
173End
174
175// Write in a single NxCansas element (from the STRUCTURE)
176// This method should only be called by CreateVarNxCansas
177Function saveNxCansasVars(fileID,parent,group,var,valueWave,attr,attrValues)
178
179        Variable fileID
180        String parent,group,var
181        Wave valueWave
182        Wave /T attr,attrValues
183        int i, numAttrs
184       
185        variable err=0, groupID
186        String NXentry_name
187       
188        groupID = NxCansas_CreateGroup(fileID,parent)
189
190        // Save data to disk
191        if(!stringmatch(var,""))
192                HDF5SaveData /O /Z /IGOR=0 valueWave, groupID, var
193                if (V_flag != 0)
194                        err = 1
195                        abort "Cannot save wave to HDF5 dataset " + var + " with V_flag of " + num2str(V_flag)
196                endif
197        endif
198               
199        NxCansas_writeAttributes(fileID,parent+var,attr,attrValues)
200       
201        // Close group and file to release resources
202        if(groupID)
203                HDF5CloseGroup /Z groupID
204        endif
205
206        return err
207end
208
209// Write in a single NxCansas element
210// This method should only be called by CreateStrNxCansas
211Function saveNxCansasStrs(fileID,parent,group,var,valueWave,attr,attrValues)
212        Variable fileID
213        String parent,group,var
214        Wave /T attr,attrValues, valueWave
215        int i, numAttrs
216       
217        variable err=0, groupID
218        String NXentry_name
219       
220        groupID = NxCansas_CreateGroup(fileID,parent)
221
222        // Save data to disk
223        if(!stringmatch(var,""))
224                HDF5SaveData /O /Z /IGOR=0 valueWave, groupID, var
225                if (V_flag != 0)
226                        err = 1
227                        abort "Cannot save wave to HDF5 dataset " + var + " with V_flag of " + num2str(V_flag)
228                endif
229        endif
230               
231        NxCansas_writeAttributes(fileID,parent+var,attr,attrValues)
232       
233        // Close group and file to release resources
234        if(groupID)
235                HDF5CloseGroup /Z groupID
236        endif
237
238        return err
239end
240
241//
242///////////////////////////////////////////////////////////////////////////
243
244///////////////////////////////////////////////////////////////////////////
245//
246// NXcanSAS Reader and Utilities
247
248Function LoadNXcanSASData(fileStr,outstr,doPlot,forceOverwrite)
249        String fileStr, outstr
250        Variable doPlot,forceOverwrite
251       
252        Variable refnum,fileID
253        Variable rr,gg,bb
254        SetDataFolder root:             //build sub-folders for each data set under root
255       
256        String filename
257        String angst = StrVarOrDefault("root:Packages:NIST:gAngstStr", "A")
258       
259        // Check fullpath and dialog
260        if(stringmatch(fileStr, ""))
261                fileID = NxCansas_DoOpenFileDialog()
262        else
263                fileID = NxCansas_OpenFile(fileStr)
264        Endif
265       
266        filename = ParseFilePath(3,fileStr,":",0,0)
267        String basestr
268        if (!cmpstr(outstr, ""))                //Outstr = "", cmpstr returns 0
269                baseStr = ShortFileNameString(CleanupName(filename,0))
270                baseStr = CleanupName(baseStr,0)                //in case the user added odd characters
271        else
272                baseStr = outstr                        //for output, hopefully correct length as passed in
273        endif
274        String/G loadDir = "root:" + baseStr
275       
276        String I_dataStore = baseStr + "_i"
277        String Q_dataStore = baseStr + "_q"
278        String dQ_dataStore = baseStr + "_dq"
279        String dQl_dataStore = baseStr + "_dql"
280        String dQw_dataStore = baseStr + "_dqw"
281        String dI_dataStore = baseStr + "_s"
282       
283        //go back to the root folder and clean up before leaving
284        NewDataFolder/O/S $loadDir
285        Make/O/N=52 $(loadDir + ":realsRead")
286        Make/O/T/N=11 $(loadDir + ":textRead")
287       
288        if(fileID)
289                HDF5ListGroup /F/R/Type=1/Z fileID,"/"
290                String groupList = S_HDF5ListGroup
291               
292                //
293                // TODO: Differentiate between 1D, 2D, and USANS data (resolutions) (DO I NEED TO?)
294                //
295       
296                Variable groupID
297                Variable inc = 1
298                String entryUnformatted = "/sasentry%d/"
299                String entryBase
300                sPrintf entryBase,entryUnformatted,inc
301                // Open first group
302                HDF5OpenGroup /Z fileID, entryBase + "sasdata/", groupID
303                do
304                        // Load in data
305                        HDF5LoadData /O/Z/N=$I_dataStore fileID, entryBase + "sasdata/I"
306                        HDF5LoadData /O/Z/N=$Q_dataStore fileID, entryBase + "sasdata/Q"
307                        HDF5LoadData /O/Z/N=$dQ_dataStore fileID, entryBase + "sasdata/dQ"
308                        HDF5LoadData /O/Z/N=$dQl_dataStore fileID, entryBase + "sasdata/dQl"
309                        HDF5LoadData /O/Z/N=$dQw_dataStore fileID, entryBase + "sasdata/dQw"
310                        HDF5LoadData /O/Z/N=$dI_dataStore fileID, entryBase + "sasdata/Idev"
311                        // Load in Meta Data
312                        LoadMetaData(fileID,loadDir,entryBase)
313                        // Open next group to see if it exists
314                        inc += 1
315                        sPrintf entryBase,entryUnformatted,inc
316                        HDF5OpenGroup /Z fileID, entryBase + "sasdata/", groupID
317                while(groupID != 0)
318               
319                //plot if desired
320                if(doPlot)
321                        Print GetDataFolder(1)
322                       
323                        String w0 = Q_dataStore
324                        String w1 = I_dataStore
325                        String w2 = dI_dataStore
326                       
327                        // assign colors randomly
328                        rr = abs(trunc(enoise(65535)))
329                        gg = abs(trunc(enoise(65535)))
330                        bb = abs(trunc(enoise(65535)))
331                       
332                        // if target window is a graph, and user wants to append, do so
333                   DoWindow/B Plot_Manager
334                        if(WinType("") == 1)
335                                DoAlert 1,"Do you want to append this data to the current graph?"
336                               
337                                if(V_Flag == 1)
338                                        AppendToGraph $w1 vs $w0
339                                        ModifyGraph mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
340                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
341                                        ModifyGraph tickUnit(left)=1
342                                else
343                                //new graph
344                                        Display $w1 vs $w0
345                                        ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
346                                        ModifyGraph grid=1,mirror=2,standoff=0
347                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
348                                        ModifyGraph tickUnit(left)=1
349                                        Label left "I(q)"
350                                        Label bottom "q ("+angst+"\\S-1\\M)"
351                                        Legend
352                                endif
353                        else
354                        // graph window was not target, make new one
355                                Display $w1 vs $w0
356                                ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
357                                ModifyGraph grid=1,mirror=2,standoff=0
358                                ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
359                                ModifyGraph tickUnit(left)=1
360                                Label left "I(q)"
361                                Label bottom "q ("+angst+"\\S-1\\M)"
362                                Legend
363                        endif
364                endif
365               
366        endif
367       
368        // Close the file
369        if(fileID)
370                HDF5CloseFile /Z fileID
371        endif
372
373end
374
375Function LoadMetaData(fileID,loadDir,parentBase)
376        String parentBase,loadDir
377        Variable fileID
378        Variable groupID
379        SetDataFolder $(loadDir)
380        Wave rw = $(loadDir + ":realsRead")
381        Wave/T textw = $(loadDir + ":textRead")
382       
383        // Title
384        HDF5OpenGroup /Z fileID, parentBase, groupID
385        HDF5LoadData /O/Z/N=title fileID, parentBase + "title"
386        Wave/T title = $(loadDir + ":title")
387       
388        // SASinstrument
389        String instrParent = parentBase + "sasinstrument/"
390       
391        // SASaperture
392        String apertureParent = instrParent + "sasaperture/"
393        HDF5OpenGroup /Z fileID, apertureParent, groupID
394        HDF5LoadData /O/Z/N=xg fileID, apertureParent + "x_gap"
395        Wave xg = $(loadDir + ":xg")
396       
397        // SAScollimation
398        String collimationParent = instrParent + "sascollimation/"
399        HDF5OpenGroup /Z fileID, collimationParent, groupID
400        HDF5LoadData /O/Z/N=cdis fileID, collimationParent + "distance"
401        Wave cdis = $(loadDir + ":cdis")
402       
403        // SASdetector
404        String detectorParent = instrParent + "sasdetector/"
405        HDF5OpenGroup /Z fileID, detectorParent, groupID
406        HDF5LoadData /O/Z/N=detname fileID, detectorParent + "name"
407        HDF5LoadData /O/Z/N=sdd fileID, detectorParent + "SDD"
408        HDF5LoadData /O/Z/N=bcx fileID, detectorParent + "beam_center_x"
409        HDF5LoadData /O/Z/N=bcy fileID, detectorParent + "beam_center_y"
410        HDF5LoadData /O/Z/N=xps fileID, detectorParent + "x_pixel_size"
411        HDF5LoadData /O/Z/N=xpy fileID, detectorParent + "y_pixel_size"
412        Wave/T detname = $(loadDir + ":detname")
413        Wave sdd = $(loadDir + ":sdd")
414        Wave bcx = $(loadDir + ":bcx")
415        Wave bcy = $(loadDir + ":bcy")
416        Wave xps = $(loadDir + ":xps")
417        Wave xpy = $(loadDir + ":xpy")
418       
419        // SASsource
420        String sourceParent = instrParent + "sassource/"
421        HDF5OpenGroup /Z fileID, sourceParent, groupID
422        HDF5LoadData /O/Z/N=wvel fileID, sourceParent + "incident_wavelength"
423        HDF5LoadData /O/Z/N=wvels fileID, sourceParent + "incident_wavelength_spread"
424        Wave wvel = $(loadDir + ":wvel")
425        Wave wvels = $(loadDir + ":wvels")
426       
427        // SASsample
428        String sampleParent = parentBase + "sassample/"
429        HDF5OpenGroup /Z fileID, sampleParent, groupID
430        HDF5LoadData /O/Z/N=smplname fileID, sampleParent + "name"
431        HDF5LoadData /O/Z/N=smplthick fileID, sampleParent + "thickness"
432        HDF5LoadData /O/Z/N=smpltrans fileID, sampleParent + "transmission"
433        Wave/T smplname = $(loadDir + ":smplname")
434        Wave smplthick = $(loadDir + ":smplthick")
435        Wave smpltrans = $(loadDir + ":smpltrans")
436       
437        textw[0] = title[0]
438        textw[6] = smplname[0]
439        textw[9] = detname[0]
440        rw[4] = smplthick[0]
441        rw[5] = smpltrans[0]
442        rw[10] = xps[0]
443        rw[13] = xpy[0]
444        rw[16] = bcx[0]
445        rw[17] = bcy[0]
446        rw[18] = sdd[0]
447        rw[24] = xg[0]
448        rw[25] = cdis[0]
449        rw[26] = wvel[0]
450        rw[27] = wvels[0]
451       
452        KillWaves title,smplname,detname,smplthick,smpltrans,xps,xpy,bcx,bcy,sdd,xg,cdis,wvel,wvels
453       
454End
455
456//
457///////////////////////////////////////////////////////////////////////////
458
459
460///////////////////////////////////////////////////////////////////////////
461//
462// Generic Read/Write operations.
463
464//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.
465Function isNXcanSAS(filestr)
466        String filestr
467       
468        Variable fileID=0,groupID=0
469        Int isHDF5File = 0
470       
471        fileID = NxCansas_OpenFile(filestr)
472        HDF5ListGroup /F/R/Type=1/Z fileID,"/"
473        Variable length = strlen(S_HDF5ListGroup)
474       
475        if (numtype(length) != 2)
476                isHDF5File = 1
477        endif
478       
479        if (fileID != 0)
480                // Close the file
481                HDF5CloseFile /Z fileID
482        endif
483       
484        return isHDF5File
485
486end
487
488//
489///////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.