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

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

Load in multiple detectors and fix errors happening when loading data.

File size: 15.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        String location = base + parent
93        NewDataFolder/O/S $(location)
94        Make/O/T/N=1 $(location + ":vals") = {""}
95        Make/O/T/N=3 $(location + ":attr") = {"NX_class", "canSAS_class", "version"}
96        Make/O/T/N=3 $(location + ":attrVals") = {"NXentry", "SASentry", "1.0"}
97        CreateStrNxCansas(fileID,nxParent,"","",$(location + ":vals"),$(location + ":attr"),$(location + ":attrVals"))
98        Make/O/T/N=1 $(location + ":entryAttr") = {""}
99        Make/O/T/N=1 $(location + ":entryAttrVals") = {""}
100        CreateStrNxCansas(fileID,nxParent,"","definition",{"NXcanSAS"},$(location + ":entryAttr"),$(location + ":entryAttrVals"))
101End
102
103//
104///////////////////////////////////////////////////////////////////////////
105
106///////////////////////////////////////////////////////////////////////////
107// Functions used to save data to file
108
109// Intermediate error handler for saving variable waves - this function should be called instead of saveNxCansas
110Function CreateVarNxCansas(fileID,parent,group,var,valueWave,attr,attrValues)
111        Variable fileID
112        String parent,group,var
113        Wave valueWave
114        Wave /T attr,attrValues
115        Variable err
116        err = saveNxCansasVars(fileID,parent,group,var,valueWave,attr,attrValues)
117        if(err)
118                Print "NxCansas write err = ",err
119        endif
120End
121// Intermediate error handler for saving string waves - this function should be called instead of saveNxCansas
122Function CreateStrNxCansas(fileID,parent,group,var,valueWave,attr,attrValues)
123        Variable fileID
124        String parent,group,var
125        Wave /T valueWave,attr,attrValues
126        Variable err
127        err = saveNxCansasStrs(fileID,parent,group,var,valueWave,attr,attrValues)
128        if(err)
129                Print "NxCansas write err = ",err
130        endif
131End
132
133Function NxCansas_writeAttributes(fileID,path,attrNames,attrVals)
134        Variable fileID
135        String path
136        Wave/T attrNames, attrVals
137        int numAttrs,i
138        numAttrs = numpnts(attrNames)
139        Duplicate/O/T attrNames, names
140        Duplicate/O/T attrVals, vals
141       
142        for(i=0; i < numAttrs; i += 1)
143                String name_i = names[i]
144                String vals_i = vals[i]
145                Make/O/T/N=1 vals_i_wave
146                vals_i_wave[0] = vals_i
147                if(!stringmatch(name_i,""))
148                        HDF5SaveData /A=name_i vals_i_wave, fileID, path
149                endif
150        endfor
151       
152End
153
154Function NxCansas_CreateGroup(fileID,parent)
155        Variable fileID
156        String parent
157        Variable groupID
158        try     
159                if(!fileID)
160                        abort "HDF5 file does not exist"
161                endif
162               
163                // Create the group if it doesn't already exist
164                HDF5CreateGroup /Z fileID, parent, groupID
165                       
166        catch
167                // DO something if error is thrown
168                Print "NxCansas write err in saveNxCansas = ",V_AbortCode
169        endtry
170        return groupID
171End
172
173// Write in a single NxCansas element (from the STRUCTURE)
174// This method should only be called by CreateVarNxCansas
175Function saveNxCansasVars(fileID,parent,group,var,valueWave,attr,attrValues)
176
177        Variable fileID
178        String parent,group,var
179        Wave valueWave
180        Wave /T attr,attrValues
181        int i, numAttrs
182       
183        variable err=0, groupID
184        String NXentry_name
185       
186        groupID = NxCansas_CreateGroup(fileID,parent)
187
188        // Save data to disk
189        if(!stringmatch(var,""))
190                HDF5SaveData /O /Z /IGOR=0 valueWave, groupID, var
191                if (V_flag != 0)
192                        err = 1
193                        abort "Cannot save wave to HDF5 dataset " + var + " with V_flag of " + num2str(V_flag)
194                endif
195        endif
196               
197        NxCansas_writeAttributes(fileID,parent+var,attr,attrValues)
198       
199        // Close group and file to release resources
200        if(groupID)
201                HDF5CloseGroup /Z groupID
202        endif
203
204        return err
205end
206
207// Write in a single NxCansas element
208// This method should only be called by CreateStrNxCansas
209Function saveNxCansasStrs(fileID,parent,group,var,valueWave,attr,attrValues)
210        Variable fileID
211        String parent,group,var
212        Wave /T attr,attrValues, valueWave
213        int i, numAttrs
214       
215        variable err=0, groupID
216        String NXentry_name
217       
218        groupID = NxCansas_CreateGroup(fileID,parent)
219
220        // Save data to disk
221        if(!stringmatch(var,""))
222                HDF5SaveData /O /Z /IGOR=0 valueWave, groupID, var
223                if (V_flag != 0)
224                        err = 1
225                        abort "Cannot save wave to HDF5 dataset " + var + " with V_flag of " + num2str(V_flag)
226                endif
227        endif
228               
229        NxCansas_writeAttributes(fileID,parent+var,attr,attrValues)
230       
231        // Close group and file to release resources
232        if(groupID)
233                HDF5CloseGroup /Z groupID
234        endif
235
236        return err
237end
238
239//
240///////////////////////////////////////////////////////////////////////////
241
242///////////////////////////////////////////////////////////////////////////
243//
244// NXcanSAS Reader and Utilities
245
246Function LoadNXcanSASData(fileStr,outstr,doPlot,forceOverwrite)
247        String fileStr, outstr
248        Variable doPlot,forceOverwrite
249       
250        Variable refnum,fileID
251        Variable rr,gg,bb
252        SetDataFolder root:             //build sub-folders for each data set under root
253       
254        String filename
255        String I_dataS,Q_dataS,dQ_dataS,dQl_dataS,dQw_dataS,dI_dataS
256        String angst = StrVarOrDefault("root:Packages:NIST:gAngstStr", "A")
257        String/G loadDir = "root:"
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 baseFormat = baseStr + "_%d"
275       
276        if(fileID)
277                HDF5ListGroup /F/R/Type=1/Z fileID,"/"
278                String groupList = S_HDF5ListGroup
279                Variable groupID
280                Variable inc=1,ii=0,isMultiData=0
281                String entryUnformatted = "/sasentry%d/"
282                String dataUnformatted = "sasdata%d/"
283                String addDigit = "%d"
284                String entryBase
285                String dataBase = "sasdata/"
286                sPrintf entryBase,entryUnformatted,inc
287                // Open first group
288                HDF5OpenGroup /Z fileID, entryBase + dataBase, groupID
289                If (groupID == 0)
290                        sPrintF dataBase,dataUnformatted,0
291                        HDF5OpenGroup /z fileID, entryBase + dataBase, groupID
292                        isMultiData = 1
293                        sPrintF baseStr,baseformat,0
294                EndIf
295               
296                // Multiple SASentry groups
297                do
298                        //go back to the root folder and clean up before leaving
299                        // Multiple SASdata groups
300                        do
301                                if (isMultiData == 1)
302                                        sPrintF baseStr,baseformat,ii
303                                EndIf
304                                loadDir = "root:" + baseStr
305                                NewDataFolder/O/S $(loadDir)
306                                // Load in data
307                                HDF5LoadData /O/Z/N=$(baseStr + "_i") fileID, entryBase + dataBase + "I"
308                                HDF5LoadData /O/Z/N=$(baseStr + "_q") fileID, entryBase + dataBase + "Q"
309                                HDF5LoadData /O/Z/N=$(baseStr + "_dq") fileID, entryBase + dataBase + "dQ"
310                                HDF5LoadData /O/Z/N=$(baseStr + "_dql") fileID, entryBase + dataBase + "dQl"
311                                HDF5LoadData /O/Z/N=$(baseStr + "_dqw") fileID, entryBase + dataBase + "dQw"
312                                HDF5LoadData /O/Z/N=$(baseStr + "_s") fileID, entryBase + dataBase + "Idev"
313                                if (isMultiData == 1)
314                                        sprintf dataBase,dataUnformatted,ii
315                                        // Open next group to see if it exists
316                                        HDF5OpenGroup /Z fileID, entryBase + dataBase, groupID
317                                else
318                                        groupID = 0
319                                endIf
320                                ii += 1
321                                // Load in Meta Data
322                                LoadMetaData(fileID,loadDir,entryBase)
323                        while (groupID != 0)
324                        inc += 1
325                        If (isMultiData == 1)
326                                sprintf dataBase,dataUnformatted,ii
327                        endIf
328                        // Open next group to see if it exists
329                sPrintf entryBase,entryUnformatted,inc
330                        HDF5OpenGroup /Z fileID, entryBase + dataBase, groupID
331                while(groupID != 0)
332               
333                //plot if desired
334                if(doPlot)
335                        Print GetDataFolder(1)
336                       
337                        String w0 = (baseStr + "_q")
338                        String w1 = (baseStr + "_i")
339                        String w2 = (baseStr + "_s")
340                       
341                        // assign colors randomly
342                        rr = abs(trunc(enoise(65535)))
343                        gg = abs(trunc(enoise(65535)))
344                        bb = abs(trunc(enoise(65535)))
345                       
346                        // if target window is a graph, and user wants to append, do so
347                   DoWindow/B Plot_Manager
348                        if(WinType("") == 1)
349                                DoAlert 1,"Do you want to append this data to the current graph?"
350                               
351                                if(V_Flag == 1)
352                                        AppendToGraph $w1 vs $w0
353                                        ModifyGraph mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
354                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
355                                        ModifyGraph tickUnit(left)=1
356                                else
357                                //new graph
358                                        Display $w1 vs $w0
359                                        ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
360                                        ModifyGraph grid=1,mirror=2,standoff=0
361                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
362                                        ModifyGraph tickUnit(left)=1
363                                        Label left "I(q)"
364                                        Label bottom "q ("+angst+"\\S-1\\M)"
365                                        Legend
366                                endif
367                        else
368                        // graph window was not target, make new one
369                                Display $w1 vs $w0
370                                ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
371                                ModifyGraph grid=1,mirror=2,standoff=0
372                                ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
373                                ModifyGraph tickUnit(left)=1
374                                Label left "I(q)"
375                                Label bottom "q ("+angst+"\\S-1\\M)"
376                                Legend
377                        endif
378                endif
379        endif
380       
381        // Close the file
382        if(fileID)
383                HDF5CloseFile /Z fileID
384        endif
385
386end
387
388Function LoadMetaData(fileID,loadDir,parentBase)
389        String parentBase,loadDir
390        Variable fileID
391        Variable groupID
392        SetDataFolder $(loadDir)
393        Make/O/N=52 $(loadDir + ":realsRead")
394        Make/O/T/N=11 $(loadDir + ":textRead")
395        Wave rw = $(loadDir + ":realsRead")
396        Wave/T textw = $(loadDir + ":textRead")
397        print rw
398        int isMultiDetector = 0, ii = 0
399       
400        // Title
401        HDF5OpenGroup /Z fileID, parentBase, groupID
402        HDF5LoadData /O/Z/N=title fileID, parentBase + "title"
403        Wave/T title = $(loadDir + ":title")
404       
405        // SASinstrument
406        String instrParent = parentBase + "sasinstrument/"
407       
408        // SASaperture
409        String apertureParent = instrParent + "sasaperture/"
410        HDF5OpenGroup /Z fileID, apertureParent, groupID
411        HDF5LoadData /O/Z/N=xg fileID, apertureParent + "x_gap"
412        Wave xg = $(loadDir + ":xg")
413       
414        // SAScollimation
415        String collimationParent = instrParent + "sascollimation/"
416        HDF5OpenGroup /Z fileID, collimationParent, groupID
417        HDF5LoadData /O/Z/N=cdis fileID, collimationParent + "distance"
418        Wave cdis = $(loadDir + ":cdis")
419       
420        // SASdetector
421        String detectorParent = instrParent + "sasdetector/"
422        HDF5OpenGroup /Z fileID, detectorParent, groupID
423        If (groupID == 0)
424                isMultiDetector = 1
425                ii = 1
426                String detectorUnformatted = "sasdetector%d/"
427                sprintf detectorParent,instrParent + detectorUnformatted,ii
428                HDF5OpenGroup /Z fileID, detectorParent, groupID
429        EndIf
430        do
431                HDF5LoadData /O/Z/N=detname fileID, detectorParent + "name"
432                HDF5LoadData /O/Z/N=sdd fileID, detectorParent + "SDD"
433                HDF5LoadData /O/Z/N=bcx fileID, detectorParent + "beam_center_x"
434                HDF5LoadData /O/Z/N=bcy fileID, detectorParent + "beam_center_y"
435                HDF5LoadData /O/Z/N=xps fileID, detectorParent + "x_pixel_size"
436                HDF5LoadData /O/Z/N=xpy fileID, detectorParent + "y_pixel_size"
437                Wave/T detname = $(loadDir + ":detname")
438                Wave sdd = $(loadDir + ":sdd")
439                Wave bcx = $(loadDir + ":bcx")
440                Wave bcy = $(loadDir + ":bcy")
441                Wave xps = $(loadDir + ":xps")
442                Wave xpy = $(loadDir + ":xpy")
443                If (isMultiDetector)
444                        ii += 1
445                        sprintf detectorParent,instrParent + detectorUnformatted,ii
446                        HDF5OpenGroup /Z fileID, detectorParent, groupID
447                Else
448                        groupID = 0
449                EndIf
450        while (groupID != 0)
451       
452        // SASsource
453        String sourceParent = instrParent + "sassource/"
454        HDF5OpenGroup /Z fileID, sourceParent, groupID
455        HDF5LoadData /O/Z/N=wvel fileID, sourceParent + "incident_wavelength"
456        HDF5LoadData /O/Z/N=wvels fileID, sourceParent + "incident_wavelength_spread"
457        Wave wvel = $(loadDir + ":wvel")
458        Wave wvels = $(loadDir + ":wvels")
459       
460        // SASsample
461        String sampleParent = parentBase + "sassample/"
462        HDF5OpenGroup /Z fileID, sampleParent, groupID
463        HDF5LoadData /O/Z/N=smplname fileID, sampleParent + "name"
464        HDF5LoadData /O/Z/N=smplthick fileID, sampleParent + "thickness"
465        HDF5LoadData /O/Z/N=smpltrans fileID, sampleParent + "transmission"
466        Wave/T smplname = $(loadDir + ":smplname")
467        Wave smplthick = $(loadDir + ":smplthick")
468        Wave smpltrans = $(loadDir + ":smpltrans")
469       
470        textw[0] = title[0]
471        textw[6] = smplname[0]
472        textw[9] = detname[0]
473        rw[4] = smplthick[0]
474        rw[5] = smpltrans[0]
475        rw[10] = xps[0]
476        rw[13] = xpy[0]
477        rw[16] = bcx[0]
478        rw[17] = bcy[0]
479        rw[18] = sdd[0]
480        rw[24] = xg[0]
481        rw[25] = cdis[0]
482        rw[26] = wvel[0]
483        rw[27] = wvels[0]
484       
485        KillWaves title,smplname,detname,smplthick,smpltrans,xps,xpy,bcx,bcy,sdd,xg,cdis,wvel,wvels
486       
487End
488
489//
490///////////////////////////////////////////////////////////////////////////
491
492
493///////////////////////////////////////////////////////////////////////////
494//
495// Generic Read/Write operations.
496
497//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.
498Function isNXcanSAS(filestr)
499        String filestr
500       
501        Variable fileID=0,groupID=0
502        Int isHDF5File = 0
503       
504        fileID = NxCansas_OpenFile(filestr)
505        HDF5ListGroup /F/R/Type=1/Z fileID,"/"
506        Variable length = strlen(S_HDF5ListGroup)
507       
508        if (numtype(length) != 2)
509                isHDF5File = 1
510        endif
511       
512        if (fileID != 0)
513                // Close the file
514                HDF5CloseFile /Z fileID
515        endif
516       
517        return isHDF5File
518
519end
520
521//
522///////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.