- Timestamp:
- Mar 13, 2008 2:10:59 PM (13 years ago)
- Location:
- 1dwg/trunk/IgorPro
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
1dwg/trunk/IgorPro/cansasXML.ipf
r9 r10 1 1 #pragma rtGlobals=1 // Use modern global access method. 2 3 # file: cansasXML.ipf 4 # author: Pete R. Jemian <jemian@anl.gov> 5 # date: 2008-03-07 6 # purpose: implement an IgorPro file reader to read the canSAS 1-D reduced SAS data in XML files 7 # adheres to the cansas1d/1.0 standard 8 # URL: http://www.smallangles.net/wgwiki/index.php/cansas1d_documentation 2 #pragma version=1.01 3 4 // file: cansasXML.ipf 5 // author: Pete R. Jemian <jemian@anl.gov> 6 // date: 2008-03-13 7 // purpose: implement an IgorPro file reader to read the canSAS 1-D reduced SAS data in XML files 8 // adheres to the cansas1d/1.0 standard 9 // URL: http://www.smallangles.net/wgwiki/index.php/cansas1d_documentation 9 10 10 11 FUNCTION CS_XmlReader(fileName) … … 41 42 CS_appendMetaData("xmlFile", "", fileName) 42 43 xmlFile = fileName 43 IF ( CS_fileExists(fileName) == 0 )44 errorMsg = fileName + ": XML file not found"45 PRINT errorMsg46 SetDataFolder $origFolder47 RETURN(-1) // could not find file48 ENDIF49 44 fileID = XmlOpenFile(fileName) // open and parse the XMLfile 50 45 IF ( fileID < 0 ) 51 errorMsg = fileName + ": XML file not found" 46 SWITCH(fileID) // fileID holds the return code; check it 47 CASE -1: 48 errorMsg = fileName + ": failed to parse XML" 49 BREAK 50 CASE -2: 51 errorMsg = fileName + " either not found or cannot be opened for reading" 52 BREAK 53 ENDSWITCH 52 54 PRINT errorMsg 53 55 SetDataFolder $origFolder … … 85 87 STRSWITCH(version) 86 88 CASE "1.0": // version 1.0 of the canSAS 1-D reduced SAS data standard 87 PRINT fileName, " identified as: cansas1d/1.0 XML file"89 PRINT fileName, "\t\t identified as: cansas1d/1.0 XML file" 88 90 returnCode = CS_1i_parseXml(fileID) 89 91 IF (returnCode != 0) … … 121 123 STRING/G Title, FolderList = "" 122 124 STRING XPathStr, Title_folder, SASdata_folder 123 VARIABLE i, j, index, SASdata_index 125 VARIABLE i, j, index, SASdata_index, returnCode = 0 124 126 125 127 // locate all the SASentry elements … … 134 136 ENDIF 135 137 136 // 138 // Should we test here for all required elements? That could be tedious. And possibly unnecessary. 139 137 140 // process each SASentry element 138 141 // (safer to copy W_listxpath to a local variable and allow for other calls to XMLlistXpath) … … 140 143 FOR (i = 0; i < numpnts(SASentryList); i += 1) 141 144 index = CS_findElementIndex(SASentryList[i]) 142 // Get each /SASentry/Title to create a data folder143 Title = CS_XmlStrFmXpath(fileID, SASentryList[i], "/Title")144 PRINT "\t Title:", Title145 145 DUPLICATE/O/T metadata_file, metadata 146 CS_appendMetaData("title", SASentryList[i]+CS_XPath_NS("/Title"), Title)146 Title = CS_locateTitle(fileID, SASentryList[i]) // look in several places or use default title 147 147 Title_folder = CleanupName(Title, 0) 148 148 IF ( CheckName(Title_folder, 11) != 0 ) … … 161 161 SASdata_folder = ":" + Title_folder + ":" 162 162 PRINT "\t\t dataFolder:", SASdata_folder 163 CS_1i_extractSasData(fileID, SASdataList[0], SASdata_folder) 163 IF (CS_1i_extractSasData(fileID, SASdataList[0], SASdata_folder)) 164 // non-zero return code means an error, message is in errorMsg 165 // What to do now? 166 // Proceed with that knowledge or discard the data folder? 167 // Go with the discard for now. 168 returnCode += 1 // for later 169 PRINT "\t\t" + errorMsg 170 KillDataFolder/Z $Title_folder // only 1 SASdata 171 // RETURN(1) // Can't return now. What about other SASentry elements? 172 BREAK 173 ENDIF 164 174 CS_appendMetaData( "Run", "", CS_XmlStrFmXpath(fileID, SASdataList[0]+"/", "../Run["+num2str(j+1)+"]")) 165 175 CS_appendMetaData( "Run_name", "", CS_XmlStrFmXpath(fileID, SASdataList[0]+"/", "../Run["+num2str(j+1)+"]/@name")) … … 186 196 SASdata_folder = ":" + Title_folder + ":" + SASdata_folder + ":" 187 197 //--- 188 CS_1i_extractSasData(fileID, SASdataList[j], SASdata_folder) 189 ENDFOR 190 ENDIF 191 ENDFOR 192 193 RETURN(0) 198 IF (CS_1i_extractSasData(fileID, SASdataList[j], SASdata_folder)) 199 // non-zero return code means an error, message is in errorMsg 200 // What to do now? 201 // Proceed with that knowledge or discard the data folder? 202 // Go with the discard for now. 203 returnCode += 1 // for later 204 PRINT "\t\t" + errorMsg 205 KillDataFolder/Z $SASdata_folder // just this SASdata 206 // RETURN(1) // Can't return now. What about other SASentry elements? 207 BREAK 208 ENDIF 209 ENDFOR // many SASdata 210 ENDIF // 1 or many SASdata 211 ENDFOR // each SASentry 212 213 RETURN(returnCode) 194 214 END 195 215 … … 306 326 // ================================================================== 307 327 328 FUNCTION/S CS_locateTitle(fileID, SASentryPath) 329 VARIABLE fileID 330 STRING SASentryPath 331 WAVE/T metadata 332 STRING TitlePath, Title 333 // /SASroot/SASentry/Title is the expected location, but it could be empty 334 TitlePath = SASentryPath+CS_XPath_NS("/Title") 335 Title = CS_XmlStrFmXpath(fileID, TitlePath, "") 336 // search harder for a title 337 IF (strlen(Title) == 0) 338 TitlePath = SASentryPath+CS_XPath_NS("/@name") 339 Title = CS_XmlStrFmXpath(fileID, TitlePath, "") 340 ENDIF 341 IF (strlen(Title) == 0) 342 TitlePath = SASentryPath+CS_XPath_NS("/SASsample/ID") 343 Title = CS_XmlStrFmXpath(fileID, TitlePath, "") 344 ENDIF 345 IF (strlen(Title) == 0) 346 TitlePath = SASentryPath+CS_XPath_NS("/SASsample/@name") 347 Title = CS_XmlStrFmXpath(fileID, TitlePath, "") 348 ENDIF 349 IF (strlen(Title) == 0) 350 // last resort: make up a title 351 Title = "SASentry" 352 TitlePath = "" 353 ENDIF 354 PRINT "\t Title:", Title 355 CS_appendMetaData("title", TitlePath, Title) 356 RETURN(Title) 357 END 358 359 // ================================================================== 360 308 361 FUNCTION CS_fileExists(fileName) 362 // checks if a file can be found and opened 363 // !!! not needed by 2008-03-13 change in XmlOpenFile() 309 364 STRING fileName 310 365 VARIABLE refNum … … 532 587 STRING unit 533 588 WAVE/T metadata 534 VARIABLE i 589 VARIABLE i, numPts 535 590 536 591 // Q values come out in multiple columns. Different nodes means different columns in M_xmlcontent … … 540 595 CS_simpleXmlWaveFmXpath(fileID, basePath, "//Idata/" + colName) 541 596 WAVE/T M_xmlcontent, W_xmlcontentnodes 542 IF (numpnts(M_XMLcontent) > 0) 597 numPts = numpnts(M_XMLcontent) 598 IF (numPts > 0) 543 599 MatrixTranspose M_XMLcontent 544 600 MAKE/O/D/N=(numpnts(M_XMLcontent)) $wavName = str2num(M_xmlcontent[p][0]) 545 // don't forget the units! Assume that all rows have the same as the first row. 601 // don't forget the units! Assume that all rows have the same "unit" as in the first row. 602 unit = CS_XmlStrFmXpath(fileID, basePath, "/Idata[1]/"+colName+"/@unit") 603 SetScale d 0, 1, unit, $wavName // update the wave's "UNITS" string 604 SetScale x 0, 1, unit, $wavName // put it here, too, for the Data Browser 605 // put unit directly into wavenote of _this_ wave 606 CS_updateWaveNote(wavName, "unit", unit) // put UNIT in wavenote 607 // store all the metadata in the wavenote (for now, at least) 546 608 FOR (i = 0; i < DimSize(metadata, 0); i += 1) 547 609 IF (strlen(metadata[i][2]) > 0) … … 550 612 ENDIF 551 613 ENDFOR 552 unit = CS_XmlStrFmXpath(fileID, basePath, "/Idata[1]/"+colName+"/@unit") 553 SetScale d 0, 1, unit, $wavName // update the wave's "UNITS" string 554 SetScale x 0, 1, unit, $wavName // put it here, too, for the Data Browser 555 CS_updateWaveNote(wavName, "unit", unit) // put UNIT in wavenote 556 ENDIF 614 ELSE 615 // did not find any data 616 // no need to apply special handling here; do that in the caller 617 ENDIF 618 //IF (numPts) 619 // PRINT "\t\t\t\t" + wavName + ": found " + num2str(numPts) + " points" 620 //ENDIF 621 RETURN(numPts) 557 622 END 558 623 … … 564 629 // (1i in the function name signifies this is a function that supports INPUT from version 1.0 XML files) 565 630 // 631 // returns: 632 // 0 no error 633 // 1 number of points in waves is not the same as Qsas wave 634 // 566 635 VARIABLE fileID 567 636 STRING SASdataPath, SASdata_folder 637 WAVE/T metadata 638 VARIABLE numPts, numQ 639 SVAR errorMsg 568 640 569 641 // extract each Idata column into the waves: QQ, II, Qdev, Idev [Qmean] [Qfwhm] [Shadowfactor] 570 CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Q", "Qsas") 571 CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "I", "Isas") 572 CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Qdev", "Qdev") 573 CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Idev", "Idev") 574 CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Qmean", "Qmean") 575 CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Qfwhm", "Qfwhm") 576 CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Shadowfactor", "Shadowfactor") 577 // this looks too simple! 642 // ignore the return codes here, check below 643 numQ = CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Q", "Qsas") 644 IF (numQ != CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "I", "Isas")) 645 errorMsg = "number of points in Qsas and Isas waves are not identical" 646 RETURN(1) 647 ENDIF 648 IF (numQ != CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Qdev", "Qdev")) 649 errorMsg = "number of points in Qsas and Qdev waves is not identical" 650 RETURN(1) 651 ENDIF 652 IF (numQ != CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Idev", "Idev")) 653 errorMsg = "number of points in Qsas and Idev waves is not identical" 654 RETURN(1) 655 ENDIF 656 numPts = CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Qmean", "Qmean") 657 IF (numPts && (numQ != numPts) ) 658 errorMsg = "number of points in Qsas and Qmean waves is not identical" 659 RETURN(1) 660 ENDIF 661 numPts = CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Qfwhm", "Qfwhm") 662 IF (numPts && (numQ != numPts) ) 663 errorMsg = "number of points in Qsas and Qfwhm waves is not identical" 664 RETURN(1) 665 ENDIF 666 numPts = CS_1i_extractIdataColumn2Wave(fileID, SASdataPath, "Shadowfactor", "Shadowfactor") 667 IF (numPts && (numQ != numPts) ) 668 errorMsg = "number of points in Qsas and Shadowfactor waves is not identical" 669 RETURN(1) 670 ENDIF 671 672 PRINT "\t\t\t\t found " + num2str(numpnts(Qsas)) + " points" 578 673 579 674 // move the waves to the sample folder 580 675 // !!!!! Missing Qsas, Isas, Qdev, and/or Idev are a broken data set 581 // This should produce an exception. 676 // This should produce an exception. Should have been trapped by numPts tests. 582 677 // Best to return an error code but the caller chain is not ready to pass that to the top level, yet. 583 IF (exists("Qsas") == 1) 584 MoveWave Qsas, $SASdata_folder 585 ENDIF 586 IF (exists("Isas") == 1) 587 MoveWave Isas, $SASdata_folder 588 ENDIF 589 IF (exists("Qdev") == 1) 590 MoveWave Qdev, $SASdata_folder 591 ENDIF 592 IF (exists("Idev") == 1) 593 MoveWave Idev, $SASdata_folder 594 ENDIF 678 MoveWave Qsas, $SASdata_folder // required wave 679 MoveWave Isas, $SASdata_folder // required wave 680 MoveWave Qdev, $SASdata_folder // required wave 681 MoveWave Idev, $SASdata_folder // required wave 595 682 IF (exists("Qmean") == 1) 596 MoveWave Qmean, $SASdata_folder 683 MoveWave Qmean, $SASdata_folder // optional wave 597 684 ENDIF 598 685 IF (exists("Qfwhm") == 1) 599 MoveWave Qfwhm, $SASdata_folder 686 MoveWave Qfwhm, $SASdata_folder // optional wave 600 687 ENDIF 601 688 IF (exists("ShadowFactor") == 1) 602 MoveWave ShadowFactor, $SASdata_folder 603 ENDIF 689 MoveWave ShadowFactor, $SASdata_folder // optional wave 690 ENDIF 691 IF (exists("metadata") == 1) 692 Duplicate/O metadata, $SASdata_folder + "metadata" 693 ENDIF 694 RETURN(0) // no error 604 695 END 605 696 … … 641 732 // build a table of test data sets 642 733 fList = AddListItem("elmo.xml", fList, ";", Inf) // non-existent file 734 fList = AddListItem("cansasXML.ipf", fList, ";", Inf) // this file (should fail on XML parsing) 735 fList = AddListItem("book.xml", fList, ";", Inf) // good XML example file but not canSAS, not even close 643 736 fList = AddListItem("bimodal-test1.xml", fList, ";", Inf) // simple dataset 644 737 fList = AddListItem("bimodal-test2-vector.xml", fList, ";", Inf) // version 2.0 file (no standard yet) … … 647 740 fList = AddListItem("ill_sasxml_example.xml", fList, ";", Inf) // from canSAS 2007 meeting, reformatted 648 741 fList = AddListItem("isis_sasxml_example.xml", fList, ";", Inf) // from canSAS 2007 meeting, reformatted 649 fList = AddListItem("r586.xml", fList, ";", Inf) // from canSAS 2007 meeting, reformatted650 fList = AddListItem("r597.xml", fList, ";", Inf) // from canSAS 2007 meeting, reformatted742 fList = AddListItem("r586.xml", fList, ";", Inf) // from canSAS 2007 meeting, reformatted 743 fList = AddListItem("r597.xml", fList, ";", Inf) // from canSAS 2007 meeting, reformatted 651 744 fList = AddListItem("cs_collagen.xml", fList, ";", Inf) // another simple dataset, bare minimum info 652 fList = AddListItem("cs_collagen_full.xml", fList, ";", Inf) // more Q range than previous745 fList = AddListItem("cs_collagen_full.xml", fList, ";", Inf) // more Q range than previous 653 746 fList = AddListItem("cs_af1410.xml", fList, ";", Inf) // multiple SASentry and SASdata elements 654 747 fList = AddListItem("1998spheres.xml", fList, ";", Inf) // 2 SASentry, few thousand data points each 655 fList = AddListItem("does-not-exist-file.xml", fList, ";", Inf) // non-existent file748 fList = AddListItem("does-not-exist-file.xml", fList, ";", Inf) // non-existent file 656 749 // try to load each data set in the table 657 750 FOR ( i = 0; i < ItemsInList(fList) ; i += 1 )
Note: See TracChangeset
for help on using the changeset viewer.