source: sans/Dev/trunk/NCNR_User_Procedures/Common/NIST_XML_v40.ipf @ 664

Last change on this file since 664 was 664, checked in by ajj, 13 years ago
  • Remove name length checking from XML loading function - now handled by ShortFileNameString?.
  • Added call to ShortFileNameString? to case where there is only one dataset in an XML file (always at NIST!)
  • Added optional parameter to getXMLDataSetTitle (useFilename = 0/1) to force use of filename rather than title/run number
  • Single dataset in file default is now to use filename. For multiple datasets still use title/run number
  • Put run number before title when generating title string so that it doesn't get lost when the title is chopped
File size: 34.0 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=1.00
3#pragma IgorVersion=6.1
4
5
6#if( Exists("XmlOpenFile") )
7
8#include "cansasXML", version >= 1.10
9
10// The function is called "LoadNISTXMLData" but is actually more generic
11// and will load any canSAS XML v1 dataset
12// Dec 2008 :
13//                       Caveats - Assumes Q in /A and I in /cm
14// Takes outStr as output name. If outStr is specified then we must load only the first SASData in the firstSASEntry,
15// since anything else doesn't make sense. This is a bit of a hack to support NSORT.
16
17
18function LoadNISTXMLData(filestr,outStr,doPlot,forceOverwrite)
19        String filestr,outStr
20        Variable doPlot,forceOverwrite
21       
22       
23        Variable rr,gg,bb
24        NVAR/Z dQv = root:Packages:NIST:USANS_dQv
25
26               
27        Print "Trying to load canSAS XML format data"
28        Variable result = CS_XMLReader(filestr)
29       
30        String xmlReaderFolder = "root:Packages:CS_XMLreader:"
31       
32        if (result == 0)
33                        SetDataFolder xmlReaderFolder
34                                               
35                        Variable i,j,numDataSets
36                        Variable np
37                       
38                        String w0,w1,w2,w3,w4,w5,basestr,fileName
39                        String xmlDataFolder,xmlDataSetFolder
40                       
41                        Variable numSASEntries
42                       
43                        if(!cmpStr(outStr,""))
44                                //no outStr defined
45                                numSASEntries = CountObjects(xmlReaderFolder,4)
46                        else
47                                numSASEntries = 1
48                        endif
49                       
50                        for (i = 0; i < numSASEntries; i+=1)
51                                                               
52                                xmlDataFolder = xmlReaderFolder+GetIndexedObjName(xmlReaderFolder,4,i)+":"
53                                if (!cmpstr(outstr,""))
54                                        numDataSets = CountObjects(xmlDataFolder,4)
55                                else
56                                        numDataSets = 0
57                                endif
58                               
59                                if (numDataSets > 0)
60                                        //Multiple SASData sets in this SASEntry
61                                        for (j = 0; j < numDataSets; j+=1)
62                                               
63                                                xmlDataSetFolder = xmlDataFolder+GetIndexedObjName(xmlDataFolder,4,j)+":"
64                                       
65                                                SetDataFolder xmlDataSetFolder 
66                                                //                      enforce a short enough name here to keep Igor objects < 31 chars
67                                                // Multiple data sets so we need to use titles and run numbers for naming
68                                                basestr = ShortFileNameString(CleanupName(getXMLDataSetTitle(xmlDataSetFolder,j,useFilename=0),0))
69                                                baseStr = CleanupName(baseStr,0)                //in case the user added odd characters
70                                               
71                                                //String basestr = ParseFilePath(3, ParseFilePath(5,filestr,":",0,0),":",0,0)                           
72                                                fileName =  ParseFilePath(0,ParseFilePath(5,filestr,":",0,0),":",1,0)
73                                                       
74                                                       
75                                                //print "In NIST XML Loader"
76                                                //print "fileStr: ",fileStr
77                                                //print "basestr: ",basestr
78                                                //print "fileName: ",fileName
79                                                //remove the semicolon AND period from files from the VAX
80                                                print basestr
81                                                w0 = basestr + "_q"
82                                                w1 = basestr + "_i"
83                                                w2 = basestr + "_s"
84                                                w3 = basestr + "sq"
85                                                w4 = basestr + "qb"
86                                                w5 = basestr + "fs"
87                                               
88                                                if(DataFolderExists("root:"+baseStr))
89                                                        if(!forceOverwrite)
90                                                                DoAlert 1,"The data set " + basestr + " from file "+fileName+" has already been loaded. Do you want to load the new data file, overwriting the data in memory?"
91                                                                if(V_flag==2)   //user selected No, don't load the data
92                                                                        SetDataFolder root:
93                                                                        if(DataFolderExists("root:Packages:NIST"))
94                                                                                String/G root:Packages:NIST:gLastFileName = filename
95                                                                        endif           //set the last file loaded to the one NOT loaded
96                                                                        return  0       //quits the macro
97                                                                endif
98                                                        endif
99                                                        SetDataFolder $("root:"+baseStr)
100                                                else
101                                                        NewDataFolder/S $("root:"+baseStr)
102                                                endif
103                       
104                                                Duplicate/O $(xmlDataSetFolder+"Qsas") $w0
105                                                Duplicate/O $(xmlDataSetFolder+"Isas") $w1
106                                                Duplicate/O $(xmlDataSetFolder+"Idev") $w2
107
108                                               
109                                                if (exists(xmlDataSetFolder+"Qdev"))
110                                                        Wave Qsas = $(xmlDataSetFolder+"Qsas")
111                                                        Wave Qdev = $(xmlDataSetFolder+"Qdev")
112                                                       
113                                                        Duplicate/O Qdev, $w3
114                                                // make a resolution matrix for SANS data
115                                                         np=numpnts($w0)
116                                                        Make/D/O/N=(np,4) $(baseStr+"_res")
117                                                        Wave reswave =  $(baseStr+"_res")
118                                                       
119                                                        reswave[][0] = Qdev[p]          //sigQ
120                                                        reswave[][3] = Qsas[p]  //Qvalues
121                                                        if(exists(xmlDataSetFolder+"Qmean"))
122                                                                Wave Qmean = $(xmlDataSetFolder+"Qmean")
123                                                                Duplicate/O Qmean,$w4
124                                                                reswave[][1] = Qmean[p]         //qBar
125                                                        endif
126                                                        if(exists(xmlDataSetFolder+"Shadowfactor"))
127                                                                Wave Shadowfactor = $(xmlDataSetFolder+"Shadowfactor")
128                                                                Duplicate/O Shadowfactor, $w5
129                                                                reswave[][2] = Shadowfactor[p]          //fShad
130                                                        endif
131                                                elseif(exists(xmlDataSetFolder+"dQl"))
132                                                        //USAS Data
133                                                        Wave dQl = $(xmlDataSetFolder+"dQl")
134                                                        dQv = dQl[0]
135                                               
136                                                        USANS_CalcWeights(baseStr,dQv)
137                                                else
138                                                        //No resolution data
139                                                endif
140                                                        //get rid of the resolution waves that are in the matrix
141                                       
142                                                        SetScale d,0,0,"1/A",$w0
143                                                        SetScale d,0,0,"1/cm",$w1
144                                               
145                                                       
146                               
147                                                //////
148                                                if(DataFolderExists("root:Packages:NIST"))
149                                                        String/G root:Packages:NIST:gLastFileName = filename
150                                                endif
151                                       
152                                               
153                                                //plot if desired
154                                                if(doPlot)
155                                                        // assign colors randomly
156                                                        rr = abs(trunc(enoise(65535)))
157                                                        gg = abs(trunc(enoise(65535)))
158                                                        bb = abs(trunc(enoise(65535)))
159                                                       
160                                                        // if target window is a graph, and user wants to append, do so
161                                                   DoWindow/B Plot_Manager
162                                                        if(WinType("") == 1)
163                                                                DoAlert 1,"Do you want to append this data to the current graph?"
164                                                                if(V_Flag == 1)
165                                                                        AppendToGraph $w1 vs $w0
166                                                                        ModifyGraph mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1) =(rr,gg,bb),tickUnit=1
167                                                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
168                                                                        ModifyGraph tickUnit(left)=1
169                                                                else
170                                                                //new graph
171                                                                        Display $w1 vs $w0
172                                                                        ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
173                                                                        ModifyGraph grid=1,mirror=2,standoff=0
174                                                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
175                                                                        ModifyGraph tickUnit(left)=1
176                                                                        Legend
177                                                                endif
178                                                        else
179                                                        // graph window was not target, make new one
180                                                                Display $w1 vs $w0
181                                                                ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
182                                                                ModifyGraph grid=1,mirror=2,standoff=0
183                                                                ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
184                                                                ModifyGraph tickUnit(left)=1
185                                                                Legend
186                                                        endif
187                                                endif
188                                       
189                                        endfor
190                                       
191                                       
192                                else
193                                        //No multiple SASData sets for this SASEntry
194                                        SetDataFolder xmlDataFolder                                     
195                                       
196                                        print xmlDataFolder
197                                       
198                                        //if outstr has been specified, we'll find ourselves here....
199                                        //We should default to using the filename here to make life easier on people who have used the NIST reduction...
200                                        if (!cmpstr(outstr,""))
201                                                basestr = ShortFileNameString(CleanupName(getXMLDataSetTitle(xmlDataFolder,0,useFilename=1),0))
202                                        else
203                                                basestr = ShortFileNameString(CleanupName(outstr,0))
204                                        endif
205                                       
206                                        //String basestr = ParseFilePath(3, ParseFilePath(5,filestr,":",0,0),":",0,0)                           
207                                        fileName =  ParseFilePath(0,ParseFilePath(5,filestr,":",0,0),":",1,0)
208                                                                                                                               
209                                        //print "In NIST XML Loader"
210                                        //print "fileStr: ",fileStr
211                                        //print "basestr: ",basestr
212                                        //print "fileName: ",fileName
213                                        w0 = basestr + "_q"
214                                        w1 = basestr + "_i"
215                                        w2 = basestr + "_s"
216                                       
217                                        if(DataFolderExists("root:"+baseStr))
218                                                if(!forceOverwrite)
219                                                        DoAlert 1,"The data set " + basestr + " from file "+fileName+" has already been loaded. Do you want to load the new data file, overwriting the data in memory?"
220                                                        if(V_flag==2)   //user selected No, don't load the data
221                                                                SetDataFolder root:
222                                                                if(DataFolderExists("root:Packages:NIST"))
223                                                                        String/G root:Packages:NIST:gLastFileName = filename
224                                                                endif           //set the last file loaded to the one NOT loaded
225                                                                return  0       //quits the macro
226                                                        endif
227                                                endif
228                                                SetDataFolder $("root:"+baseStr)
229                                        else
230                                                NewDataFolder/S $("root:"+baseStr)
231                                        endif
232               
233                                        Duplicate/O $(xmlDataFolder+"Qsas") $w0
234                                        Duplicate/O $(xmlDataFolder+"Isas") $w1
235                                        Duplicate/O $(xmlDataFolder+"Idev") $w2
236       
237       
238                                               
239                                        if (exists(xmlDataFolder+"Qdev"))
240                                                Wave Qsas = $(xmlDataFolder+"Qsas")
241                                                Wave Qdev = $(xmlDataFolder+"Qdev")
242                                       
243                                        // make a resolution matrix for SANS data
244                                                np=numpnts($w0)
245                                                Make/D/O/N=(np,4) $(baseStr+"_res")
246                                                Wave reswave =  $(baseStr+"_res")
247                                               
248                                                reswave[][0] = Qdev[p]          //sigQ
249                                                reswave[][3] = Qsas[p]  //Qvalues
250                                                if(exists(xmlDataFolder+"Qmean"))
251                                                        Wave Qmean = $(xmlDataFolder+"Qmean")
252                                                        reswave[][1] = Qmean[p]         //qBar
253                                                endif
254                                                if(exists(xmlDataFolder+"Shadowfactor"))
255                                                        Wave Shadowfactor = $(xmlDataFolder+"Shadowfactor")
256                                                        reswave[][2] = Shadowfactor[p]          //fShad
257                                                endif
258                                        elseif(exists(xmlDataFolder+"dQl"))
259                                                //USAS Data
260                                                Wave dQl = $(xmlDataFolder+"dQl")
261                                                dQv = dQl[0]
262                                       
263                                                USANS_CalcWeights(baseStr,dQv)
264                                        else
265                                                //No resolution data
266                                        endif
267                                                //get rid of the resolution waves that are in the matrix
268                               
269                                                SetScale d,0,0,"1/A",$w0
270                                                SetScale d,0,0,"1/cm",$w1
271                                       
272                                               
273                       
274                                        //////
275                                        if(DataFolderExists("root:Packages:NIST"))
276                                                String/G root:Packages:NIST:gLastFileName = filename
277                                        endif
278                               
279                                       
280                                        //plot if desired
281                                        if(doPlot)
282                                                // assign colors randomly
283                                                rr = abs(trunc(enoise(65535)))
284                                                gg = abs(trunc(enoise(65535)))
285                                                bb = abs(trunc(enoise(65535)))
286                                               
287                                                // if target window is a graph, and user wants to append, do so
288                                           DoWindow/B Plot_Manager
289                                                if(WinType("") == 1)
290                                                        DoAlert 1,"Do you want to append this data to the current graph?"
291                                                        if(V_Flag == 1)
292                                                                AppendToGraph $w1 vs $w0
293                                                                ModifyGraph mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1) =(rr,gg,bb),tickUnit=1
294                                                                ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
295                                                                ModifyGraph tickUnit(left)=1
296                                                        else
297                                                        //new graph
298                                                                Display $w1 vs $w0
299                                                                ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
300                                                                ModifyGraph grid=1,mirror=2,standoff=0
301                                                                ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
302                                                                ModifyGraph tickUnit(left)=1
303                                                                Legend
304                                                        endif
305                                                else
306                                                // graph window was not target, make new one
307                                                        Display $w1 vs $w0
308                                                        ModifyGraph log=1,mode($w1)=3,marker($w1)=19,msize($w1)=2,rgb($w1)=(rr,gg,bb),tickUnit=1
309                                                        ModifyGraph grid=1,mirror=2,standoff=0
310                                                        ErrorBars/T=0 $w1 Y,wave=($w2,$w2)
311                                                        ModifyGraph tickUnit(left)=1
312                                                        Legend
313                                                endif
314                                        endif
315                               
316                                endif
317                        endfor
318        endif
319
320        //go back to the root folder and clean up before leaving
321        SetDataFolder root:
322        //KillDataFolder xmlReaderFolder
323       
324
325end
326
327
328function/S getXMLDataSetTitle(xmlDF,dsNum,[useFilename])
329        String xmlDF
330        Variable dsNum
331        Variable useFilename
332
333        SVAR title = root:Packages:NIST:gXMLLoader_Title
334
335        String mdstring = xmlDF+"metadata"
336        String filename
337
338        Wave/T meta = $mdstring
339
340        //Get filename to use if useFilename is specified or as a fall back if title is missing.
341        FindValue/TEXT="xmlFile"/TXOP=4/Z meta
342        filename = ParseFilePath(0,TrimWS(meta[V_Value][1]),":",1,0)
343       
344        if (useFilename)
345                return filename
346        endif
347       
348        //Check for value when there are multiple datasets
349        //Note that the use of FindValue here assumes that the tag is in column 0 so that V_Value
350        //represents the row number
351        //This will almost certainly break if your title was "Title" or "Run"
352        FindValue/TEXT="Title"/TXOP=4/Z meta
353        if (V_Value >= 0)
354        //This should always be true as title is required in canSAS XML format
355                title = TrimWS(meta[V_Value][1])
356        else
357                title = filename
358        endif   
359         //Check for Run value
360         //If you get a run value, put it at the start of the string so it isn't lost if there is truncation
361         //One hopes that the run number will be unique...
362         FindValue/TEXT="Run_"+num2str(dsNum)/TXOP=4/Z meta
363        if (V_Value >= 0)
364                title = TrimWS(meta[V_Value][1])+" "+title
365                //print title
366        else
367                FindValue/TEXT="Run"/TXOP=4/Z meta
368                if (V_Value >= 0)
369                        title = TrimWS(meta[V_Value][1])+" "+title
370                        //print title
371                endif
372        endif
373       
374        return title
375end
376
377
378//AJJ 12/5/08
379
380//Define struct for file contents
381Structure NISTXMLfile
382//      string filename
383        string Run
384        string title
385
386        //<SASdata>
387        Wave Q,I,Idev,Qdev,Qmean,Shadowfactor,dQl
388        string unitsQ,unitsI,unitsIdev,unitsQdev,unitsQmean,unitsShadowfactor,unitsdQl
389
390//      Variable flux_monitor
391//      string Q_resolution
392
393        //<SASsample>
394        string sample_ID
395        variable sample_thickness
396        string unitssample_thickness
397        variable sample_transmission
398
399        //SASinstrument
400        string nameSASinstrument
401        // SASinstrument/SASsource
402        string radiation
403//      string beam_shape
404        variable wavelength
405        string unitswavelength
406        variable wavelength_spread
407        string unitswavelength_spread
408 
409        //<SAScollimation>
410//      variable collimation_length
411//      string unitscollimation_length
412        variable source_aperture
413        string unitssource_aperture
414        string typesource_aperture
415        variable sample_aperture
416        string unitssample_aperture
417        string typesample_aperture
418
419        //SASdetector         <SASdetector>
420        string detector_name
421        variable offset_angle
422        string unitsoffset_angle
423        variable  SDD
424        string unitsSDD
425        variable beamcenter_X
426        string unitsbeamcenter_X
427        variable beamcenter_Y
428        string unitsbeamcenter_Y
429//      variable pixel_sizeX
430//      string unitspixel_sizeX
431//      variable pixel_sizeY
432//      string unitspixel_sizeY
433//      string detectortype
434
435        // <SASprocess name="NCNR-IGOR">
436        string nameSASprocess
437        string SASprocessnote
438//      string SASprocessdate
439//      string average_type
440//      string SAM_file
441//      string BKD_file
442//      string EMP_file
443//      string DIV_file
444//      string MASK_file
445//      string ABS_parameters
446//      variable TSTAND
447//      variable DSTAND
448//      string unitsDSTAND
449//      variable IZERO
450//      variable XSECT
451//      string unitsXSECT
452        string SASnote
453Endstructure
454
455
456//Function to write NIST canSAS XML files
457//Minimalist XML file - AJJ Dec 2008
458function writeNISTXML(fileName, NISTfile)
459        String fileName
460        Struct NISTXMLfile &NISTfile
461
462        variable fileID
463       
464        //create the sasXML file with SASroot
465        //no namespace, no prefix
466        fileID = xmlcreatefile(fileName,"SASroot","cansas1d/1.0","")
467
468        //create a version attribute for the root element
469        xmlsetAttr(fileID,"/SASroot","","version","1.0")
470        xmlsetAttr(fileID,"/SASroot","","xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance")
471        xmlsetAttr(fileID,"/SASroot","","xsi:schemaLocation","cansas1d/1.0 http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd")
472
473
474        //create the SASentry node
475        xmladdnode(fileID,"/SASroot","","SASentry","",1)
476               
477        //create the Title node
478        xmladdnode(fileID,"/SASroot/SASentry","","Title",NISTfile.Title,1)
479
480        //create the Run node
481        xmladdnode(fileID,"/SASroot/SASentry","","Run",NISTfile.Run,1)
482       
483        //create the SASdata node
484        xmladdnode(fileID,"/SASroot/SASentry","","SASdata","",1)
485
486        variable ii
487       
488        if (WaveExists(NISTfile.dQl) == 1)
489                for(ii=0 ; ii<numpnts(NISTfile.Q) ; ii+=1)
490                        xmladdnode(fileID,"/SASroot/SASentry/SASdata","","Idata","",1)
491                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","Q",num2str(NISTfile.Q[ii]),1)
492                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/Q","","unit",NISTfile.unitsQ)
493       
494                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","I",num2str(NISTfile.I[ii]),1)
495                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/I","","unit",NISTfile.unitsI)
496       
497                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","Idev",num2str(NISTfile.Idev[ii]),1)
498                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/Idev","","unit",NISTfile.unitsIdev)     
499       
500                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","Idev",num2str(NISTfile.dQl[ii]),1)
501                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/Idev","","unit",NISTfile.unitsdQl)               
502                endfor
503        else
504                for(ii=0 ; ii<numpnts(NISTfile.Q) ; ii+=1)
505                        xmladdnode(fileID,"/SASroot/SASentry/SASdata","","Idata","",1)
506                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","Q",num2str(NISTfile.Q[ii]),1)
507                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/Q","","unit",NISTfile.unitsQ)
508       
509                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","I",num2str(NISTfile.I[ii]),1)
510                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/I","","unit",NISTfile.unitsI)
511       
512                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","Idev",num2str(NISTfile.Idev[ii]),1)
513                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/Idev","","unit",NISTfile.unitsIdev)
514       
515                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","Qdev",num2str(NISTfile.Qdev[ii]),1)
516                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/Qdev","","unit",NISTfile.unitsQdev)
517       
518                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","Qmean",num2str(NISTfile.Qmean[ii]),1)
519                        xmlsetAttr(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]/Qmean","","unit",NISTfile.unitsQmean)
520       
521                        xmladdnode(fileID,"/SASroot/SASentry/SASdata/Idata["+num2istr(ii+1)+"]","","Shadowfactor",num2str(NISTfile.shadowfactor[ii]),1)
522                endfor
523        endif
524
525        //SASsample node
526        xmladdnode(fileID,"/SASroot/SASentry","","SASsample","",1)
527        xmladdnode(fileID,"/SASroot/SASentry/SASsample","","ID",NISTfile.sample_ID,1)
528
529        //SASInstrument node
530        xmladdnode(fileID,"/SASroot/SASentry","","SASinstrument","",1)
531        xmladdnode(fileID,"/SASroot/SASentry/SASinstrument","","name",NISTfile.nameSASinstrument,1)
532       
533        //SASsource
534        xmladdnode(fileID,"/SASroot/SASentry/SASinstrument","","SASsource","",1)
535        xmladdnode(fileID,"/SASroot/SASentry/SASinstrument/SASsource","","radiation",NISTfile.radiation,1)
536
537        //SAScollimation
538        xmladdnode(fileID,"/SASroot/SASentry/SASinstrument","","SAScollimation","",1)
539
540        //SASdetector
541        xmladdnode(fileID,"/SASroot/SASentry/SASinstrument","","SASdetector","",1)
542        xmladdnode(fileID,"/SASroot/SASentry/SASinstrument/SASdetector","","name",NISTfile.detector_name,1)
543
544
545        //SASprocess
546        xmladdnode(fileID,"/SASroot/SASentry","","SASprocess","",1)
547        xmlsetAttr(fileID,"/SASroot/SASentry/SASprocess","","name",NISTfile.nameSASprocess)     
548        xmladdnode(fileID,"/SASroot/SASentry/SASprocess","","SASprocessnote",NISTfile.SASprocessnote,1)
549       
550        //SASnote
551        xmladdnode(fileID,"/SASroot/SASentry","","SASnote",NISTfile.SASnote,1)
552       
553        xmlsavefile(fileID)
554        xmlclosefile(fileID,0)
555       
556end
557
558Function convertNISTtoNISTXML(fileStr)
559        String fileStr
560       
561        Struct NISTXMLfile nf
562       
563        Variable rr,gg,bb,refnum,dQv
564        SetDataFolder root:     
565       
566        if (cmpStr(fileStr,"") == 0)
567                //No filename given, open dialog
568                Open/D/R  refnum
569                if (cmpstr(S_filename,"") == 0)
570                        return 0
571                else
572                        fileStr = S_filename
573                endif
574        endif
575
576        //Load the waves, using default waveX names
577        //if no path or file is specified for LoadWave, the default Mac open dialog will appear
578        LoadWave/G/D/A/Q fileStr
579        String fileNamePath = S_Path+S_fileName
580        String basestr = CleanupName(ParseFilePath(3,ParseFilePath(5,fileNamePath,":",0,0),":",0,0),0)
581//      String baseStr = CleanupName(S_fileName,0)
582//              print "basestr :"+basestr
583        String fileName =  ParseFilePath(0,ParseFilePath(5,filestr,":",0,0),":",1,0)
584//              print "filename :"+filename
585        Variable numCols = V_flag
586        String outfileName = S_Path+basestr+".xml"
587
588       
589        if(numCols==3)          //simple 3-column data with no resolution information
590               
591                Wave nf.Q = $(StringFromList(0, S_waveNames ,";" ))
592                Wave nf.I = $(StringFromList(1, S_waveNames ,";" ))
593                Wave nf.Idev = $(StringFromList(2, S_waveNames ,";" ))
594                               
595                //Set units
596                nf.unitsQ = "1/A"
597                nf.unitsI = "1/cm"
598                nf.unitsIdev = "1/cm"
599                               
600        endif           //3-col data
601       
602        if(numCols == 6)                //6-column SANS or USANS data that has resolution information
603               
604                // put the names of the (default named) loaded waves into local names
605                Wave nf.Q = $(StringFromList(0, S_waveNames ,";" ))
606                Wave nf.I  = $(StringFromList(1, S_waveNames ,";" ))
607                Wave nf.Idev  = $(StringFromList(2, S_waveNames ,";" ))
608
609                //Set units
610                nf.unitsQ = "1/A"
611                nf.unitsI = "1/cm"
612                nf.unitsIdev = "1/cm"
613
614                WAVE resTest = $(StringFromList(3, S_waveNames ,";" ))
615
616                // need to switch based on SANS/USANS
617                if (isSANSResolution(resTest[0]))               //checks to see if the first point of the wave is <0]
618                        Wave nf.Qdev  = $(StringFromList(3, S_waveNames ,";" ))
619                        Wave nf.Qmean  = $(StringFromList(4, S_waveNames ,";" ))
620                        Wave nf.Shadowfactor  = $(StringFromList(5, S_waveNames ,";" ))
621                       
622                        //Set units
623                        nf.unitsQdev = "1/A"
624                        nf.unitsQmean = "1/A"
625                else
626                        Wave nf.dQl = $(StringFromList(3, S_waveNames ,";" ))
627                       
628                        //Set units
629                        nf.unitsdQl = "1/A"
630                       
631                endif
632               
633                //Tidy up
634                Variable i = 0
635                do
636                        WAVE wv= $(StringFromList(i,S_waveNames,";"))
637                        if( WaveExists(wv) == 0 )
638                                break
639                        endif
640                        KillWaves wv
641                        i += 1
642                while (1)       // exit is via break statement
643
644       
645        endif   //6-col data
646
647        //Get file header
648        setmetadataFromASCHeader(fileStr,nf)
649
650        //Set required metadata that we can't get from these files
651        nf.detector_name = "Ordela 128x128"
652        nf.nameSASinstrument = "NIST NG3/NG7 SANS"
653        nf.radiation = "neutron"
654        nf.sample_ID = nf.title
655        nf.nameSASProcess = "NIST Data Converter"
656        nf.sasnote = "Data converted from previous NIST format. SASProcessnote contains header from original text file."
657
658        writeNISTXML(outfileName, nf)
659
660end
661
662function setmetadataFromASCHeader(fileStr,NISTfile)
663        String fileStr
664        Struct NISTXMLfile &NISTfile
665
666        String hdr="",buffer=""
667        Variable lineNum = 0, fileref
668        Variable num
669       
670        Open/R fileref as fileStr
671        do
672                FReadLine fileref, buffer
673                if (stringmatch(buffer,"*The 6 columns are*") == 1)
674                        break
675                endif
676                buffer = RemoveEnding(buffer)
677                print buffer
678                //Get run value
679                if (stringmatch(buffer,"*file:*") == 1)
680                        NISTfile.run = TrimWS(StringFromList(0,StringFromList(1, buffer, ":"),"C"))
681                elseif (stringmatch(buffer,"combined file*") == 1)
682                        NISTfile.run = "Combined Data"
683                endif
684               
685                //Get title value
686                if (stringmatch(buffer,"*FIRST File LABEL:*") == 1)
687                        NISTfile.title = TrimWS(StringFromList(1,buffer, ":"))
688                elseif(stringmatch(buffer,"*LABEL:*") == 1)
689                        NISTfile.title = TrimWS(StringFromList(1,buffer, ":"))
690                endif
691               
692                hdr += buffer+"\n"
693        while(strlen(buffer) > 0)
694       
695        if (strlen(NISTfile.title) == 0)
696                NISTfile.title = CleanupName(ParseFilePath(3,ParseFilePath(5,fileStr,":",0,0),":",0,0),0)
697        endif
698        if (strlen(NISTfile.run) == 0)
699                NISTfile.run = "Unknown"
700        endif
701       
702        NISTfile.sasprocessnote = RemoveEnding(hdr)
703       
704end
705
706//for writing out data (q-i-s) from the "type" folder, and including reduction information
707//if fullpath is a complete HD path:filename, no dialog will be presented
708//if fullpath is just a filename, the save dialog will be presented
709//if dialog = 1, a dialog will always be presented
710//
711// root:myGlobals:Protocols:gProtoStr is the name of the currently active protocol
712//
713//AJJ Nov 2009 : This version of the function currently only works for Circular, Sector and Rectangular averages
714//i.e. anything that produces I vs Q. Need to add ability to handle Annular (I vs theta) but that requires namespace addition to XML format
715//and handling on load.
716Function WriteXMLWaves_W_Protocol(type,fullpath,dialog)
717        String type,fullpath
718        Variable dialog         //=1 will present dialog for name
719       
720        Struct NISTXMLfile nf
721       
722        String destStr=""
723        destStr = "root:Packages:NIST:"+type
724       
725        Variable refNum
726//      String fname,ave="C",hdrStr1="",hdrStr2=""
727//      Variable step=1
728       
729        //*****these waves MUST EXIST, or IGOR Pro will crash, with a type 2 error****
730        WAVE intw=$(destStr + ":integersRead")
731        WAVE rw=$(destStr + ":realsRead")
732        WAVE/T textw=$(destStr + ":textRead")
733        WAVE qvals =$(destStr + ":qval")
734        WAVE inten=$(destStr + ":aveint")
735        WAVE sig=$(destStr + ":sigave")
736        WAVE qbar = $(destStr + ":QBar")
737        WAVE sigmaq = $(destStr + ":SigmaQ")
738        WAVE fsubs = $(destStr + ":fSubS")
739
740
741        SVAR gProtoStr = root:myGlobals:Protocols:gProtoStr
742        Wave/T proto=$("root:myGlobals:Protocols:"+gProtoStr)
743
744       
745        //check each wave
746        If(!(WaveExists(intw)))
747                Abort "intw DNExist BinaryWrite_W_Protocol()"
748        Endif
749        If(!(WaveExists(rw)))
750                Abort "rw DNExist BinaryWrite_W_Protocol()"
751        Endif
752        If(!(WaveExists(textw)))
753                Abort "textw DNExist BinaryWrite_W_Protocol()"
754        Endif
755        If(!(WaveExists(qvals)))
756                Abort "qvals DNExist BinaryWrite_W_Protocol()"
757        Endif
758        If(!(WaveExists(inten)))
759                Abort "inten DNExist BinaryWrite_W_Protocol()"
760        Endif
761        If(!(WaveExists(sig)))
762                Abort "sig DNExist BinaryWrite_W_Protocol()"
763        Endif
764        If(!(WaveExists(qbar)))
765                Abort "qbar DNExist BinaryWrite_W_Protocol()"
766        Endif
767        If(!(WaveExists(sigmaq)))
768                Abort "sigmaq DNExist BinaryWrite_W_Protocol()"
769        Endif
770        If(!(WaveExists(fsubs)))
771                Abort "fsubs DNExist BinaryWrite_W_Protocol()"
772        Endif
773        If(!(WaveExists(proto)))
774                Abort "current protocol wave DNExist BinaryWrite_W_Protocol()"
775        Endif
776       
777        if(dialog)
778                PathInfo/S catPathName
779                fullPath = DoSaveFileDialog("Save data as")
780                If(cmpstr(fullPath,"")==0)
781                        //user cancel, don't write out a file
782                        Close/A
783                        Abort "no data file was written"
784                Endif
785                //Print "dialog fullpath = ",fullpath
786        Endif
787       
788        SVAR samFiles = $("root:Packages:NIST:"+type+":fileList")
789        //actually open the file here
790        //Open refNum as fullpath
791       
792        //Data
793        Wave nf.Q = qvals
794        nf.unitsQ = "1/A"
795        Wave nf.I = inten
796        nf.unitsI = "1/cm"
797        Wave nf.Idev = sig
798        nf.unitsIdev = "1/cm"
799        Wave nf.Qdev = sigmaq
800        nf.unitsQdev = "1/A"
801        Wave nf.Qmean = qbar
802        nf.unitsQmean = "1/A"
803        Wave nf.Shadowfactor = fSubS
804        nf.unitsShadowfactor = "none"
805       
806       
807        //write out the standard header information
808        //fprintf refnum,"FILE: %s\t\t CREATED: %s\r\n",textw[0],textw[1]
809       
810        //AJJ to fix with sensible values
811        nf.run = "Test"
812        String acct = textw[3]
813        nf.nameSASinstrument = acct[1,3]
814        nf.SASnote = ""
815        //
816        nf.sample_ID = textw[6]
817        nf.title = textw[6]
818        nf.radiation = "neutron"
819        nf.wavelength = rw[26]
820        nf.unitswavelength = "A"
821        nf.offset_angle = rw[19]
822        nf.unitsoffset_angle = "cm"
823        nf.SDD = rw[18]
824        nf.unitsSDD = "m"
825        nf.sample_transmission = rw[4]
826        nf.sample_thickness = rw[5]
827        nf.unitssample_thickness = "mm"
828       
829        nf.beamcenter_X = rw[16] 
830        nf.beamcenter_Y = rw[17]
831        nf.unitsbeamcenter_X = "pixels"
832        nf.unitsbeamcenter_Y = "pixels"
833        nf.source_aperture = rw[23]
834        nf.typesource_aperture = "pinhole"
835        nf.unitssource_aperture = "mm"
836        nf.sample_aperture = rw[24]
837        nf.typesample_aperture = "pinhole"
838        nf.unitssample_aperture = "mm"
839        //nf.collimation_length = total length - rw[25]
840        nf.wavelength_spread = rw[27]
841        nf.unitswavelength_spread = "percent"
842        //Do something with beamstop (rw[21])
843        nf.detector_name = textW[9]
844//      fprintf refnum,"MON CNT   LAMBDA   DET ANG   DET DIST   TRANS   THICK   AVE   STEP\r\n"
845//      fprintf refnum,hdrStr1
846
847//      fprintf refnum,"BCENT(X,Y)   A1(mm)   A2(mm)   A1A2DIST(m)   DL/L   BSTOP(mm)   DET_TYP \r\n"
848//      fprintf refnum,hdrStr2
849
850        //insert protocol information here
851        //-1 list of sample files
852        //0 - bkg
853        //1 - emp
854        //2 - div
855        //3 - mask
856        //4 - abs params c2-c5
857        //5 - average params
858        nf.SASprocessnote =  "SAM: "+samFiles+"\n"
859        nf.SASprocessnote += "BGD: "+proto[0]+"\n"
860        nf.SASprocessnote += "EMP: "+Proto[1]+"\n"
861        nf.SASprocessnote += "DIV: "+Proto[2]+"\n"
862        nf.SASprocessnote += "MASK: "+Proto[3]+"\n"
863        nf.SASprocessnote += "ABS Parameters (3-6): "+Proto[4]+"\n"
864        nf.SASprocessnote += "Average Choices: "+Proto[5]+"\n"
865       
866        nf.nameSASProcess = "NIST IGOR"
867
868        //Close refnum
869       
870        writeNISTXML(fullpath, nf)
871       
872        SetDataFolder root:             //(redundant)
873       
874        //write confirmation of write operation to history area
875        Print "Averaged XML File written: ", GetFileNameFromPathNoSemi(fullPath)
876        KillWaves/Z tempShortProto
877        Return(0)
878End
879
880Function WriteNSORTedXMLFile(qw,iw,sw,firstFileName,secondFileName,thirdFileName,normTo,norm12,norm23,[res])
881        Wave qw,iw,sw,res
882        String firstFileName,secondFileName,thirdFileName,normTo
883        Variable norm12,norm23
884
885        Variable err=0,refNum,numCols,dialog=1
886        String fullPath="",formatStr="",str2
887        //check each wave - else REALLY FATAL error when writing file
888        If(!(WaveExists(qw)))
889                err = 1
890                return err
891        Endif
892        If(!(WaveExists(iw)))
893                err = 1
894                return err
895        Endif
896        If(!(WaveExists(sw)))
897                err = 1
898                return err
899        Endif
900       
901        if(WaveExists(res))
902                numCols = 6
903        else
904                numCols = 3
905        endif
906       
907// 05SEP05 SRK -- added to automatically combine files from a table - see the end of NSORT.ipf for details
908// - use the flag set in DoCombineFiles() to decide if the table entries should be used
909//Ê Êroot:myGlobals:CombineTable:useTable= (1) (0)
910//if(exists("root:myGlobals:CombineTable:SaveName"))
911        NVAR/Z useTable = root:myGlobals:CombineTable:useTable
912        if(NVAR_Exists(useTable) && useTable==1)
913                SVAR str=root:myGlobals:CombineTable:SaveNameStr        //messy, but pass in as a global
914                fullPath = str
915//              str2 = "Is the file name "+str+" correct?"
916//              DoAlert 1,str2
917//              if(V_flag==1)
918                        dialog=0                //bypass the dialog if the name is good (assumed, since DoAlert is bypassed)
919//              endif
920        endif
921
922        if(dialog)
923                PathInfo/S catPathName
924                fullPath = DoSaveFileDialog("Save data as")             //won't actually open the file
925                If(cmpstr(fullPath,"")==0)
926                        //user cancel, don't write out a file
927                        Close/A
928                        Abort "no data file was written"
929                Endif
930                //Print "dialog fullpath = ",fullpath
931        Endif
932
933        Struct NISTxmlfile nf
934       
935        //Data
936        Wave nf.Q = qw
937        nf.unitsQ = "1/A"
938        Wave nf.I = iw
939        nf.unitsI = "1/cm"
940        Wave nf.Idev = sw
941        nf.unitsIdev = "1/cm"
942
943        //write out the standard header information
944        //fprintf refnum,"FILE: %s\t\t CREATED: %s\r\n",textw[0],textw[1]
945       
946        //AJJ to fix with sensible values
947        nf.run = ""
948        nf.nameSASinstrument = "NIST IGOR"
949        nf.SASnote = ""
950        //
951        nf.sample_ID = ParseFilePath(3, fullPath, ":", 0, 0)
952        nf.title = ParseFilePath(3, fullPath, ":", 0, 0)
953        nf.radiation = "neutron"
954        //Do something with beamstop (rw[21])
955        nf.detector_name = "NSORTed Data"       
956        nf.nameSASProcess = "NIST IGOR"
957       
958        nf.sasProcessNote = "COMBINED FILE CREATED: "+date()+"\n"
959        nf.sasProcessNote += "NSORT-ed : " +firstFileName+";"+secondFileName+";"+thirdFileName+"\n"
960        nf.sasProcessNote += "normalized to  "+normTo+"\n"
961        fprintf refNum, "multiplicative factor 1-2 = "+num2str(norm12)+" multiplicative factor 2-3 = "+num2str(norm23)+"\n"
962
963        if (numCols == 3)
964                writeNISTXML(fullpath,nf)
965        elseif (numCols == 6)
966                Make/O/N=(dimsize(res,0)) sigq = res[p][0]
967                Make/O/N=(dimsize(res,0)) qbar = res[p][1]
968                Make/O/N=(dimsize(res,0)) fs = res[p][2]
969       
970                Wave nf.Qdev = sigQ
971                nf.unitsQdev = "1/A"
972                Wave nf.Qmean = qbar
973                nf.unitsQmean = "1/A"
974                Wave nf.Shadowfactor = fs
975                nf.unitsShadowfactor = "none"
976       
977                writeNISTXML(fullpath,nf)
978       
979                Killwaves/Z sigq,qbar,fs
980        endif
981
982        Return err
983End
984
985
986
987
988
989End
990
991/// See WriteModelData_v40.ipf for 6 column equivalent
992Function ReWrite1DXMLData(folderStr)
993        String folderStr
994
995        String fullpath=""
996        Variable dialog=1
997        String dataSetFolderParent,basestr,fullBase
998       
999        Struct NISTXMLfile nf
1000
1001        //Abuse ParseFilePath to get path without folder name
1002        dataSetFolderParent = ParseFilePath(1,folderStr,":",1,0)
1003        //Abuse ParseFilePath to get basestr
1004        basestr = ParseFilePath(0,folderStr,":",1,0)
1005
1006        SetDataFolder $(dataSetFolderParent+basestr)
1007        WAVE/Z qw = $(baseStr+"_q")
1008        WAVE/Z iw = $(baseStr+"_i")
1009        WAVE/Z sw = $(baseStr+"_s")
1010        WAVE/Z resw = $(baseStr+"_res")
1011       
1012        if(WaveExists(qw) == 0)
1013                Abort "q is missing"
1014        endif
1015        if(WaveExists(iw) == 0)
1016                Abort "i is missing"
1017        endif
1018        if(WaveExists(sw) == 0)
1019                Abort "s is missing"
1020        endif
1021        if(WaveExists(resw) == 0)
1022                Abort "Resolution information is missing."
1023        endif
1024       
1025        Duplicate/O qw qbar,sigQ,fs
1026               
1027
1028               
1029        //Data
1030        Wave nf.Q = qw
1031        nf.unitsQ = "1/A"
1032        Wave nf.I = iw
1033        nf.unitsI = "1/cm"
1034        Wave nf.Idev = sw
1035        nf.unitsIdev = "1/cm"
1036        Wave nf.Qdev = sigQ
1037        nf.unitsQdev = "1/A"
1038        Wave nf.Qmean = qbar
1039        nf.unitsQmean = "1/A"
1040        Wave nf.Shadowfactor = fs
1041        nf.unitsShadowfactor = "none"
1042       
1043       
1044        //write out the standard header information
1045        //fprintf refnum,"FILE: %s\t\t CREATED: %s\r\n",textw[0],textw[1]
1046       
1047        //AJJ to fix with sensible values
1048        nf.run = ""
1049        nf.nameSASinstrument = "NIST IGOR Procedures"
1050        nf.SASnote = ""
1051        //
1052        nf.sample_ID = baseStr
1053        nf.title = baseStr
1054        nf.radiation = "neutron"
1055        //Do something with beamstop (rw[21])
1056        nf.detector_name = "Re-written data"
1057
1058        nf.SASprocessnote =  "Modified data written from folder "+baseStr+" on "+(date()+" "+time())
1059       
1060        nf.nameSASProcess = "NIST IGOR"
1061
1062        //Close refnum
1063       
1064        if(dialog)
1065                PathInfo/S catPathName
1066                fullPath = DoSaveFileDialog("Save data as",fname=baseStr+".xml")
1067                If(cmpstr(fullPath,"")==0)
1068                        //user cancel, don't write out a file
1069                        Close/A
1070                        Abort "no data file was written"
1071                Endif
1072                //Print "dialog fullpath = ",fullpath
1073        Endif
1074       
1075       
1076        writeNISTXML(fullpath,nf)
1077        //write confirmation of write operation to history area
1078        Print "XML File written: ", GetFileNameFromPathNoSemi(fullPath)
1079        KillWaves/Z tempShortProto
1080        Return(0)
1081End
1082
1083
1084
1085
1086#else   // if( Exists("XmlOpenFile") )
1087        // No XMLutils XOP: provide dummy function so that IgorPro can compile dependent support code
1088        FUNCTION LoadNISTXMLData(fileName,doPlot)
1089            String fileName
1090            Variable doPlot
1091            Abort  "XML function provided by XMLutils XOP is not available, get the XOP from : http://www.igorexchange.com/project/XMLutils (see http://www.smallangles.net/wgwiki/index.php/cansas1d_binding_IgorPro for details)"
1092            RETURN(-6)
1093        END
1094       
1095
1096        Function writeNISTXML(fileName, NISTfile)
1097                String fileName, NISTfile
1098                Abort  "XML function provided by XMLutils XOP is not available, get the XOP from : http://www.igorexchange.com/project/XMLutils (see http://www.smallangles.net/wgwiki/index.php/cansas1d_binding_IgorPro for details)"
1099                RETURN(-6)
1100        End
1101       
1102        Function WriteXMLWaves_W_Protocol(type,fullpath,dialog)
1103                String type,fullpath
1104                Variable dialog         //=1 will present dialog for name
1105       
1106            Abort  "XML function provided by XMLutils XOP is not available, get the XOP from : http://www.igorexchange.com/project/XMLutils (see http://www.smallangles.net/wgwiki/index.php/cansas1d_binding_IgorPro for details)"
1107                return(-6)
1108        end
1109       
1110        Function WriteNSORTedXMLFile(q3,i3,sig3,firstFileName,secondFileName,thirdFileName,normTo,norm12,norm23,[res])
1111                Wave q3,i3,sig3,res
1112                String firstFileName,secondFileName,thirdFileName,normTo
1113                Variable norm12,norm23
1114
1115                 Abort  "XML function provided by XMLutils XOP is not available, get the XOP from : http://www.igorexchange.com/project/XMLutils (see http://www.smallangles.net/wgwiki/index.php/cansas1d_binding_IgorPro for details)"
1116                return(-6)
1117        End
1118
1119        Function ReWrite1DXMLData(folderStr)
1120                String folderStr
1121       
1122                 Abort  "XML function provided by XMLutils XOP is not available, get the XOP from : http://www.igorexchange.com/project/XMLutils (see http://www.smallangles.net/wgwiki/index.php/cansas1d_binding_IgorPro for details)"
1123                return(-6)
1124        end
1125#endif
1126
1127        // if( Exists("XmlOpenFile")
1128//Needed to test whether file is XML. The load routine will then either give an error if XMLutils is not present or load the file if it is.
1129function isXML(filestr)
1130        String filestr
1131       
1132        String line
1133        Variable fileref
1134       
1135        Open/R fileref as filestr
1136        FReadLine fileref,  line
1137        Close fileref
1138       
1139        //Hopefully this will distinguish between other formats and the XML
1140        //Previous string match would match normal files that have a .xml file as their progenitor...
1141        return GrepString(line, "(?iU).*\<.*xml.*")     
1142
1143end
Note: See TracBrowser for help on using the repository browser.