Changeset 10 for 1dwg/trunk


Ignore:
Timestamp:
Mar 13, 2008 2:10:59 PM (14 years ago)
Author:
prjemian
Message:

two more tests, handle pathologies in SASdata, added pragma for version=1.01 to cansasXML.ipf

Location:
1dwg/trunk/IgorPro
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • 1dwg/trunk/IgorPro/cansasXML.ipf

    r9 r10  
    11#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 
    910 
    1011FUNCTION CS_XmlReader(fileName) 
     
    4142        CS_appendMetaData("xmlFile", "", fileName) 
    4243        xmlFile = fileName 
    43         IF ( CS_fileExists(fileName) == 0 ) 
    44                 errorMsg = fileName + ": XML file not found" 
    45                 PRINT errorMsg 
    46                 SetDataFolder $origFolder 
    47                 RETURN(-1)                                              // could not find file 
    48         ENDIF 
    4944        fileID = XmlOpenFile(fileName)                  // open and parse the XMLfile 
    5045        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 
    5254                PRINT errorMsg 
    5355                SetDataFolder $origFolder 
     
    8587        STRSWITCH(version)       
    8688        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" 
    8890                returnCode = CS_1i_parseXml(fileID) 
    8991                IF (returnCode != 0) 
     
    121123        STRING/G Title, FolderList = "" 
    122124        STRING XPathStr, Title_folder, SASdata_folder 
    123         VARIABLE i, j, index, SASdata_index 
     125        VARIABLE i, j, index, SASdata_index, returnCode = 0 
    124126 
    125127        // locate all the SASentry elements 
     
    134136        ENDIF 
    135137 
    136         // 
     138        // Should we test here for all required elements?  That could be tedious.  And possibly unnecessary. 
     139 
    137140        // process each SASentry element 
    138141        // (safer to copy W_listxpath to a local variable and allow for other calls to XMLlistXpath) 
     
    140143        FOR (i = 0; i < numpnts(SASentryList); i += 1) 
    141144                index = CS_findElementIndex(SASentryList[i]) 
    142                 // Get each /SASentry/Title to create a data folder 
    143                 Title = CS_XmlStrFmXpath(fileID, SASentryList[i], "/Title") 
    144                 PRINT "\t Title:", Title 
    145145                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 
    147147                Title_folder = CleanupName(Title, 0) 
    148148                IF ( CheckName(Title_folder, 11) != 0 ) 
     
    161161                        SASdata_folder = ":" + Title_folder + ":" 
    162162                        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 
    164174                        CS_appendMetaData(  "Run", "", CS_XmlStrFmXpath(fileID, SASdataList[0]+"/",  "../Run["+num2str(j+1)+"]")) 
    165175                        CS_appendMetaData(  "Run_name", "", CS_XmlStrFmXpath(fileID, SASdataList[0]+"/",  "../Run["+num2str(j+1)+"]/@name")) 
     
    186196                                SASdata_folder =  ":" + Title_folder + ":" + SASdata_folder + ":" 
    187197                                //--- 
    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) 
    194214END 
    195215 
     
    306326// ================================================================== 
    307327 
     328FUNCTION/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) 
     357END 
     358 
     359// ================================================================== 
     360 
    308361FUNCTION CS_fileExists(fileName) 
     362        // checks if a file can be found and opened 
     363        // !!! not needed by 2008-03-13 change in XmlOpenFile() 
    309364        STRING fileName 
    310365        VARIABLE refNum 
     
    532587        STRING unit 
    533588        WAVE/T metadata 
    534         VARIABLE i 
     589        VARIABLE i, numPts 
    535590 
    536591        //      Q values come out in multiple columns. Different nodes means different columns in M_xmlcontent 
     
    540595        CS_simpleXmlWaveFmXpath(fileID, basePath, "//Idata/" + colName) 
    541596        WAVE/T  M_xmlcontent, W_xmlcontentnodes 
    542         IF (numpnts(M_XMLcontent) > 0) 
     597        numPts = numpnts(M_XMLcontent) 
     598        IF (numPts > 0) 
    543599                MatrixTranspose M_XMLcontent 
    544600                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) 
    546608                FOR (i = 0; i < DimSize(metadata, 0); i += 1) 
    547609                        IF (strlen(metadata[i][2]) > 0) 
     
    550612                        ENDIF 
    551613                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) 
    557622END 
    558623 
     
    564629        //  (1i in the function name signifies this is a function that supports INPUT from version 1.0 XML files) 
    565630        // 
     631        //      returns: 
     632        //              0       no error 
     633        //              1       number of points in waves is not the same as Qsas wave 
     634        // 
    566635        VARIABLE fileID 
    567636        STRING SASdataPath, SASdata_folder 
     637        WAVE/T metadata 
     638        VARIABLE numPts, numQ 
     639        SVAR errorMsg 
    568640 
    569641        // 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" 
    578673 
    579674        // move the waves to the sample folder 
    580675        // !!!!! 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. 
    582677        //              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 
    595682        IF (exists("Qmean") == 1) 
    596                 MoveWave Qmean, $SASdata_folder 
     683                MoveWave Qmean, $SASdata_folder // optional wave 
    597684        ENDIF 
    598685        IF (exists("Qfwhm") == 1) 
    599                 MoveWave Qfwhm, $SASdata_folder 
     686                MoveWave Qfwhm, $SASdata_folder // optional wave 
    600687        ENDIF 
    601688        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 
    604695END 
    605696 
     
    641732        // build a table of test data sets 
    642733        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 
    643736        fList = AddListItem("bimodal-test1.xml",                fList, ";", Inf)                // simple dataset 
    644737        fList = AddListItem("bimodal-test2-vector.xml", fList, ";", Inf)                // version 2.0 file (no standard yet) 
     
    647740        fList = AddListItem("ill_sasxml_example.xml",   fList, ";", Inf)                // from canSAS 2007 meeting, reformatted 
    648741        fList = AddListItem("isis_sasxml_example.xml",  fList, ";", Inf)                // from canSAS 2007 meeting, reformatted 
    649         fList = AddListItem("r586.xml",                                 fList, ";", Inf)                // from canSAS 2007 meeting, reformatted 
    650         fList = AddListItem("r597.xml",                                 fList, ";", Inf)                // from canSAS 2007 meeting, reformatted 
     742        fList = AddListItem("r586.xml",                                         fList, ";", Inf)                // from canSAS 2007 meeting, reformatted 
     743        fList = AddListItem("r597.xml",                                         fList, ";", Inf)                // from canSAS 2007 meeting, reformatted 
    651744        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 previous 
     745        fList = AddListItem("cs_collagen_full.xml",             fList, ";", Inf)                // more Q range than previous 
    653746        fList = AddListItem("cs_af1410.xml",                    fList, ";", Inf)                // multiple SASentry and SASdata elements 
    654747        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 file 
     748        fList = AddListItem("does-not-exist-file.xml",          fList, ";", Inf)                // non-existent file 
    656749        // try to load each data set in the table 
    657750        FOR ( i = 0; i < ItemsInList(fList) ; i += 1 ) 
Note: See TracChangeset for help on using the changeset viewer.