Changeset 3241dd2 in sasview
- Timestamp:
- Sep 25, 2014 12:33:41 PM (10 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- a91bc5d
- Parents:
- 72cdbec
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sans/dataloader/readers/associations.py
r5777106 r3241dd2 91 91 logging.info("register_readers is now obsolete: use read_associations()") 92 92 import abs_reader 93 import cansas_reader94 93 import ascii_reader 95 94 import cansas_reader … … 98 97 import IgorReader 99 98 import red2d_reader 100 import tiff_reader99 #import tiff_reader 101 100 import nexus_reader 102 101 103 102 registry_function(abs_reader) 104 registry_function(cansas_reader)105 103 registry_function(ascii_reader) 106 104 registry_function(cansas_reader) … … 109 107 registry_function(IgorReader) 110 108 registry_function(red2d_reader) 111 registry_function(tiff_reader)109 #registry_function(tiff_reader) 112 110 registry_function(nexus_reader) 113 111 -
src/sans/dataloader/readers/cansas_constants.py
rac5b69d r3241dd2 37 37 if name != "SASentry": 38 38 return_me.current_level = \ 39 39 return_me.current_level.get("children").get(name, "") 40 40 if return_me.current_level == "": 41 41 return_me.current_level = \ … … 44 44 cl_datatype = return_me.current_level.get("storeas", "") 45 45 cl_units_optional = \ 46 return_me.current_level.get("units_required", "") 47 # Where are how to store the variable for the given namespace 48 # CANSAS_CONSTANTS tree is hierarchical, so is no value, inherit 49 return_me.ns_variable = cl_variable if cl_variable != "" else \ 50 return_me.ns_variable 51 return_me.ns_datatype = cl_datatype if cl_datatype != "" else \ 52 return_me.ns_datatype 46 return_me.current_level.get("units_required", "") 47 # Where are how to store the variable for the given 48 # namespace CANSAS_CONSTANTS tree is hierarchical, so 49 # is no value, inherit 50 return_me.ns_variable = cl_variable if cl_variable != "" \ 51 else return_me.ns_variable 52 return_me.ns_datatype = cl_datatype if cl_datatype != "" \ 53 else return_me.ns_datatype 53 54 return_me.ns_optional = cl_units_optional if \ 54 55 cl_units_optional != return_me.ns_optional \ 55 56 else return_me.ns_optional 56 57 except AttributeError: … … 61 62 62 63 63 """ 64 CANSAS_NS holds the base namespace and the default schema file information 65 """ 64 def get_namespace_map(self): 65 """ 66 Helper method to get the names namespace list 67 """ 68 return self.names 69 70 71 # CANSAS_NS holds the base namespace and default schema file information 66 72 CANSAS_NS = { 67 "1.0" : { 68 "ns" : "cansas1d/1.0", 69 "schema" : "cansas1d_v1_0.xsd" 70 }, 71 "1.1" : { 72 "ns" : "urn:cansas1d:1.1", 73 "schema" : "cansas1d_v1_1.xsd" 74 } 73 "1.0" : 74 { 75 "ns" : "cansas1d/1.0", 76 "schema" : "cansas1d_v1_0.xsd" 77 }, 78 "1.1" : 79 { 80 "ns" : "urn:cansas1d:1.1", 81 "schema" : "cansas1d_v1_1.xsd" 82 } 75 83 } 76 84 77 85 78 """ 79 The constants below hold information on where to store the CanSAS data when 80 loaded in using sasview 81 """ 86 # The constants below hold information on where to store the CanSAS data 87 # when loaded in using sasview 82 88 META_DATA = "{0}.meta_data[\"{2}\"] = \"{1}\"" 83 89 ANY = { … … 89 95 SASPROCESS_TERM = { 90 96 "variable" : None, 91 "attributes" : { 92 "unit" : {"variable" : None}, 93 "name" : {"variable" : None} 94 } 97 "attributes" : 98 { 99 "unit" : {"variable" : None}, 100 "name" : {"variable" : None} 101 } 95 102 } 96 103 SASPROCESS_SASPROCESSNOTE = { … … 103 110 "name" : {"variable" : "{0}.name = \'{1}\'"}, 104 111 "date" : {"variable" : "{0}.date = \'{1}\'"}, 105 "description" : {"variable" : \106 112 "description" : 113 {"variable" : "{0}.description = \'{1}\'"}, 107 114 "term" : SASPROCESS_TERM, 108 115 "SASprocessnote" : SASPROCESS_SASPROCESSNOTE, … … 112 119 RUN = { 113 120 "variable" : "{0}.run.append(\"{1}\")", 114 "attributes" : {"name" : {"variable" : \115 121 "attributes" : 122 {"name" : {"variable" : "{0}.run_name[node_value] = \"{1}\""}} 116 123 } 117 124 SASDATA_IDATA_Q = { 118 125 "variable" : "{0}.x = numpy.append({0}.x, {1})", 119 126 "unit" : "x_unit", 120 "attributes" : { 121 "unit" : { 122 "variable" : \ 123 "{0}._xunit = \"{1}\"", 124 "storeas" : "content" 125 } 126 } 127 "attributes" : 128 { 129 "unit" : 130 { 131 "variable" : "{0}._xunit = \"{1}\"", 132 "storeas" : "content" 133 } 134 }, 127 135 } 128 136 SASDATA_IDATA_I = { 129 137 "variable" : "{0}.y = numpy.append({0}.y, {1})", 130 138 "unit" : "y_unit", 131 "attributes" : { 132 "unit" : { 133 "variable" : \ 134 "{0}._yunit = \"{1}\"", 135 "storeas" : "content" 136 } 137 } 139 "attributes" : 140 { 141 "unit" : 142 { 143 "variable" : "{0}._yunit = \"{1}\"", 144 "storeas" : "content" 145 } 146 }, 138 147 } 139 148 SASDATA_IDATA_IDEV = { 140 "variable" : \ 141 "{0}.dy = numpy.append({0}.dy, {1})", 149 "variable" : "{0}.dy = numpy.append({0}.dy, {1})", 142 150 "unit" : "y_unit", 143 "attributes" : { 144 "unit" : { 145 "variable" : META_DATA, 146 "storeas" : "content" 147 } 148 }, 151 "attributes" : 152 { 153 "unit" : 154 { 155 "variable" : META_DATA, 156 "storeas" : "content" 157 } 158 }, 149 159 } 150 160 SASDATA_IDATA_QDEV = { 151 "variable" : \ 152 "{0}.dx = numpy.append({0}.dx, {1})", 161 "variable" : "{0}.dx = numpy.append({0}.dx, {1})", 153 162 "unit" : "x_unit", 154 "attributes" : { 155 "unit" : { 156 "variable" : META_DATA, 157 "storeas" : "content" 158 } 159 }, 163 "attributes" : 164 { 165 "unit" : 166 { 167 "variable" : META_DATA, 168 "storeas" : "content" 169 } 170 }, 160 171 } 161 172 SASDATA_IDATA_DQL = { 162 "variable" : \ 163 "{0}.dxl = numpy.append({0}.dxl, {1})", 173 "variable" : "{0}.dxl = numpy.append({0}.dxl, {1})", 164 174 "unit" : "x_unit", 165 "attributes" : { 166 "unit" : { 167 "variable" : META_DATA, 168 "storeas" : "content" 169 } 170 }, 175 "attributes" : 176 { 177 "unit" : 178 { 179 "variable" : META_DATA, 180 "storeas" : "content" 181 } 182 }, 171 183 } 172 184 SASDATA_IDATA_DQW = { 173 "variable" : \ 174 "{0}.dxw = numpy.append({0}.dxw, {1})", 185 "variable" : "{0}.dxw = numpy.append({0}.dxw, {1})", 175 186 "unit" : "x_unit", 176 "attributes" : { 177 "unit" : { 178 "variable" : META_DATA, 179 "storeas" : "content" 180 } 181 }, 187 "attributes" : 188 { 189 "unit" : 190 { 191 "variable" : META_DATA, 192 "storeas" : "content" 193 } 194 }, 182 195 } 183 196 SASDATA_IDATA_QMEAN = { … … 228 241 "variable" : "{0}.wavelength.append({1})", 229 242 "unit" : "wavelength_unit", 230 "attributes" : { 231 "unit" : { 232 "variable" : "{0}.wavelength_unit = \"{1}\"", 233 "storeas" : "content" 234 } 235 } 243 "attributes" : 244 { 245 "unit" : 246 { 247 "variable" : \ 248 "{0}.wavelength_unit = \"{1}\"", 249 "storeas" : "content" 250 } 251 } 236 252 } 237 253 SASTRANSSPEC_TDATA_T = { 238 254 "variable" : "{0}.transmission.append({1})", 239 255 "unit" : "transmission_unit", 240 "attributes" : { 241 "unit" : { 242 "variable" : "{0}.transmission_unit = \"{1}\"", 243 "storeas" : "content" 244 } 245 } 256 "attributes" : 257 { 258 "unit" : 259 { 260 "variable" : "{0}.transmission_unit = \"{1}\"", 261 "storeas" : "content" 262 } 263 } 246 264 } 247 265 SASTRANSSPEC_TDATA_TDEV = { … … 249 267 "{0}.transmission_deviation.append({1})", 250 268 "unit" : "transmission_deviation_unit", 251 "attributes" : { 252 "unit" : { 253 "variable" : "{0}.transmission_deviation_unit = \"{1}\"", 254 "storeas" : "content" 255 } 256 } 269 "attributes" : 270 { 271 "unit" : 272 { 273 "variable" : \ 274 "{0}.transmission_deviation_unit = \"{1}\"", 275 "storeas" : "content" 276 } 277 } 257 278 } 258 279 SASTRANSSPEC_TDATA = { … … 272 293 "<any>" : ANY, 273 294 }, 274 "attributes" : {"name" : {"variable" : \ 275 "{0}.name = \"{1}\""}, 276 "timestamp" : {"variable" : \ 277 "{0}.timestamp = \"{1}\""}, 278 } 295 "attributes" : 296 { 297 "name" : 298 { 299 "variable" : "{0}.name = \"{1}\""}, 300 "timestamp" : 301 { 302 "variable" : "{0}.timestamp = \"{1}\"" 303 }, 304 } 279 305 } 280 306 SASSAMPLE_THICK = { … … 282 308 "unit" : "sample.thickness_unit", 283 309 "storeas" : "float", 284 "attributes" : { 285 "units" : { 286 "variable" : "{0}.sample.thickness_unit = \"{1}\"", 287 "storeas" : "content" 288 } 289 }, 310 "attributes" : 311 { 312 "unit" : 313 { 314 "variable" : "{0}.sample.thickness_unit = \"{1}\"", 315 "storeas" : "content" 316 } 317 }, 290 318 } 291 319 SASSAMPLE_TRANS = { … … 297 325 "unit" : "sample.temperature_unit", 298 326 "storeas" : "float", 299 "attributes" : { 300 "units" : { 301 "variable" : "{0}.sample.temperature_unit = \"{1}\"", 302 "storeas" : "content" 303 } 304 }, 327 "attributes" : 328 { 329 "unit" : 330 { 331 "variable" : "{0}.sample.temperature_unit = \"{1}\"", 332 "storeas" : "content" 333 } 334 }, 305 335 } 306 336 SASSAMPLE_POS_ATTR = { 307 "unit s" : {337 "unit" : { 308 338 "variable" : \ 309 339 "{0}.sample.position_unit = \"{1}\"", … … 338 368 } 339 369 SASSAMPLE_ORIENT_ATTR = { 340 "units" : { 341 "variable" : "{0}.sample.orientation_unit = \"{1}\"", 342 "storeas" : "content" 343 } 370 "unit" : 371 { 372 "variable" : \ 373 "{0}.sample.orientation_unit = \"{1}\"", 374 "storeas" : "content" 375 } 344 376 } 345 377 SASSAMPLE_ORIENT_ROLL = { … … 370 402 } 371 403 SASSAMPLE = { 372 "attributes" : {"name" : {\373 404 "attributes" : 405 {"name" : {"variable" : "{0}.sample.name = \"{1}\""},}, 374 406 "variable" : None, 375 407 "children" : { … … 387 419 SASINSTR_SRC_BEAMSIZE_ATTR = { 388 420 "unit" : \ 389 "{0}.source.beam_size_unit = \"{1}\"",421 "{0}.source.beam_size_unit = \"{1}\"", 390 422 "storeas" : "content" 391 423 } … … 409 441 } 410 442 SASINSTR_SRC_BEAMSIZE = { 411 "attributes" : {"name" : {"variable" : \ 412 "{0}.source.beam_size_name = \"{1}\""}}, 443 "attributes" : 444 {"name" : {"variable" : \ 445 "{0}.source.beam_size_name = \"{1}\""}}, 413 446 "variable" : None, 414 447 "children" : { … … 422 455 "unit" : "source.wavelength_unit", 423 456 "storeas" : "float", 424 "attributes" : { 425 "unit" : { 426 "variable" : "{0}.source.wavelength_unit = \"{1}\"", 427 "storeas" : "content" 428 }, 429 } 457 "attributes" : 458 { 459 "unit" : 460 { 461 "variable" : "{0}.source.wavelength_unit = \"{1}\"", 462 "storeas" : "content" 463 }, 464 } 430 465 } 431 466 SASINSTR_SRC_WL_MIN = { … … 433 468 "unit" : "source.wavelength_min_unit", 434 469 "storeas" : "float", 435 "attributes" : { 436 "unit" : { 437 "variable" : "{0}.source.wavelength_min_unit = \"{1}\"", 438 "storeas" : "content" 439 }, 440 } 470 "attributes" : 471 { 472 "unit" : 473 { 474 "variable" : \ 475 "{0}.source.wavelength_min_unit = \"{1}\"", 476 "storeas" : "content" 477 }, 478 } 441 479 } 442 480 SASINSTR_SRC_WL_MAX = { … … 444 482 "unit" : "source.wavelength_max_unit", 445 483 "storeas" : "float", 446 "attributes" : { 447 "unit" : { 448 "variable" : "{0}.source.wavelength_max_unit = \"{1}\"", 449 "storeas" : "content" 450 }, 451 } 484 "attributes" : 485 { 486 "unit" : 487 { 488 "variable" : \ 489 "{0}.source.wavelength_max_unit = \"{1}\"", 490 "storeas" : "content" 491 }, 492 } 452 493 } 453 494 SASINSTR_SRC_WL_SPR = { … … 455 496 "unit" : "source.wavelength_spread_unit", 456 497 "storeas" : "float", 457 "attributes" : { 458 "unit" : { 459 "variable" : "{0}.source.wavelength_spread_unit = \"{1}\"", 460 "storeas" : "content" 461 }, 462 } 498 "attributes" : 499 { 500 "unit" : 501 { 502 "variable" : \ 503 "{0}.source.wavelength_spread_unit = \"{1}\"", 504 "storeas" : "content" 505 }, 506 } 463 507 } 464 508 SASINSTR_SRC = { … … 503 547 } 504 548 SASINSTR_COLL_APER_SIZE = { 505 "attributes" : {"unit" : {"variable" : \ 506 "{0}.size_unit = \"{1}\""}}, 549 "attributes" : 550 {"unit" : {"variable" : \ 551 "{0}.size_unit = \"{1}\""}}, 507 552 "children" : { 508 553 "storeas" : "float", … … 514 559 SASINSTR_COLL_APER_DIST = { 515 560 "storeas" : "float", 516 "attributes" : { 517 "storeas" : "content", 518 "unit" : {"variable" : \ 519 "{0}.distance_unit = \"{1}\""}}, 561 "attributes" : 562 { 563 "storeas" : "content", 564 "unit" : {"variable" : \ 565 "{0}.distance_unit = \"{1}\""} 566 }, 520 567 "variable" : "{0}.distance = {1}", 521 568 "unit" : "distance_unit", … … 535 582 } 536 583 SASINSTR_COLL = { 537 "attributes" : {"name" : {"variable" : \538 584 "attributes" : 585 {"name" : {"variable" : "{0}.name = \"{1}\""}}, 539 586 "variable" : None, 540 "children" : { 541 "length" : { 542 "variable" : "{0}.length = {1}", 543 "unit" : "length_unit", 544 "storeas" : "float", 545 "attributes" : { 546 "storeas" : \ 547 "content", 548 "unit" : {"variable" : "{0}.length_unit = \"{1}\""} 549 }, 550 }, 551 "aperture" : SASINSTR_COLL_APER, 552 }, 587 "children" : 588 { 589 "length" : 590 { 591 "variable" : "{0}.length = {1}", 592 "unit" : "length_unit", 593 "storeas" : "float", 594 "attributes" : 595 { 596 "storeas" : "content", 597 "unit" : {"variable" : "{0}.length_unit = \"{1}\""} 598 }, 599 }, 600 "aperture" : SASINSTR_COLL_APER, 601 }, 553 602 } 554 603 SASINSTR_DET_SDD = { 555 604 "variable" : "{0}.distance = {1}", 556 605 "unit" : "distance_unit", 557 "attributes" : { 558 "unit" : { 559 "variable" : \ 560 "{0}.distance_unit = \"{1}\"", 561 "storeas" : "content" 562 } 563 }, 606 "attributes" : 607 { 608 "unit" : 609 { 610 "variable" : "{0}.distance_unit = \"{1}\"", 611 "storeas" : "content" 612 } 613 }, 564 614 } 565 615 SASINSTR_DET_OFF_ATTR = { … … 622 672 "variable" : "{0}.beam_center.x = {1}", 623 673 "unit" : "beam_center_unit", 624 "attributes" : {625 "unit" : \626 627 628 674 "attributes" : 675 { 676 "unit" : "{0}.beam_center_unit = \"{1}\"", 677 "storeas" : "content" 678 } 629 679 } 630 680 SASINSTR_DET_BC_Y = { 631 681 "variable" : "{0}.beam_center.y = {1}", 632 682 "unit" : "beam_center_unit", 633 "attributes" : {634 "unit" : \635 636 637 683 "attributes" : 684 { 685 "unit" : "{0}.beam_center_unit = \"{1}\"", 686 "storeas" : "content" 687 } 638 688 } 639 689 SASINSTR_DET_BC_Z = { 640 690 "variable" : "{0}.beam_center.z = {1}", 641 691 "unit" : "beam_center_unit", 642 "attributes" : {643 "unit" : \644 645 646 692 "attributes" : 693 { 694 "unit" : "{0}.beam_center_unit = \"{1}\"", 695 "storeas" : "content" 696 } 647 697 } 648 698 SASINSTR_DET_BC = { … … 657 707 "variable" : "{0}.pixel_size.x = {1}", 658 708 "unit" : "pixel_size_unit", 659 "attributes" : {660 "unit" : \661 662 663 709 "attributes" : 710 { 711 "unit" : "{0}.pixel_size_unit = \"{1}\"", 712 "storeas" : "content" 713 } 664 714 } 665 715 SASINSTR_DET_PIXEL_Y = { 666 716 "variable" : "{0}.pixel_size.y = {1}", 667 717 "unit" : "pixel_size_unit", 668 "attributes" : {669 "unit" : \670 671 672 718 "attributes" : 719 { 720 "unit" : "{0}.pixel_size_unit = \"{1}\"", 721 "storeas" : "content" 722 } 673 723 } 674 724 SASINSTR_DET_PIXEL_Z = { 675 725 "variable" : "{0}.pixel_size.z = {1}", 676 726 "unit" : "pixel_size_unit", 677 "attributes" : {678 "unit" : \679 680 681 727 "attributes" : 728 { 729 "unit" : "{0}.pixel_size_unit = \"{1}\"", 730 "storeas" : "content" 731 } 682 732 } 683 733 SASINSTR_DET_PIXEL = { … … 692 742 "variable" : "{0}.slit_length = {1}", 693 743 "unit" : "slit_length_unit", 694 "attributes" : { 695 "unit" : { 696 "variable" : "{0}.slit_length_unit = \"{1}\"", 697 "storeas" : "content" 698 } 699 } 744 "attributes" : 745 { 746 "unit" : 747 { 748 "variable" : "{0}.slit_length_unit = \"{1}\"", 749 "storeas" : "content" 750 } 751 } 700 752 } 701 753 SASINSTR_DET = { … … 703 755 "variable" : None, 704 756 "attributes" : { 705 "name" : { 706 "storeas" : "content", 707 "variable" : "{0}.name = \"{1}\"", 708 } 757 "name" : 758 { 759 "storeas" : "content", 760 "variable" : "{0}.name = \"{1}\"", 761 } 709 762 }, 710 763 "children" : { … … 723 776 SASINSTR = { 724 777 "variable" : None, 725 "children" : {726 "variable" : None,727 "name" : {"variable" : \728 729 730 731 732 778 "children" : 779 { 780 "variable" : None, 781 "name" : {"variable" : "{0}.instrument = \"{1}\""}, 782 "SASsource" : SASINSTR_SRC, 783 "SAScollimation" : SASINSTR_COLL, 784 "SASdetector" : SASINSTR_DET, 785 }, 733 786 } 734 787 CANSAS_FORMAT = { 735 "SASentry" : {736 "units_optional" : True,737 "variable" : None,738 "storeas" : "content",739 "attributes" : {"name" : {"variable" : \740 "{0}.run_name[node_value] = \"{1}\""}},741 "children" : {742 "Title" : TITLE,743 "Run" : RUN,744 "SASdata" : SASDATA,745 "SAStransmission_spectrum" : \746 747 748 749 750 751 752 753 788 "SASentry" : 789 { 790 "units_optional" : True, 791 "variable" : None, 792 "storeas" : "content", 793 "attributes" : {"name" : {"variable" : \ 794 "{0}.run_name[node_value] = \"{1}\""}}, 795 "children" : { 796 "Title" : TITLE, 797 "Run" : RUN, 798 "SASdata" : SASDATA, 799 "SAStransmission_spectrum" : SASTRANSSPEC, 800 "SASsample" : SASSAMPLE, 801 "SASinstrument" : SASINSTR, 802 "SASprocess" : SASPROCESS, 803 "SASnote" : SASNOTE, 804 "<any>" : ANY, 805 } 806 } 754 807 } 755 808 809 756 810 class CurrentLevel: 757 811 """ … … 769 823 self.ns_datatype = "content" 770 824 self.ns_optional = True 825 826 def get_current_level(self): 827 """ 828 Helper method to get the current_level map 829 """ 830 return self.current_level 831 832 def get_data_type(self): 833 """ 834 Helper method to get the ns_datatype label 835 """ 836 return self.ns_datatype 837 838 def get_variable(self): 839 """ 840 Helper method to get the ns_variable label 841 """ 842 return self.ns_variable -
src/sans/dataloader/readers/cansas_reader.py
r51af54b r3241dd2 35 35 PREPROCESS = "xmlpreprocess" 36 36 ENCODING = "encoding" 37 RUN_NAME_DEFAULT = "None" 37 38 HAS_CONVERTER = True 38 39 try: 39 40 from sans.data_util.nxsunit import Converter 40 except :41 except ImportError: 41 42 HAS_CONVERTER = False 42 43 … … 74 75 # Called by outside packages: 75 76 # sans.perspectives.fitting.pagestate 76 def write_node(doc, parent, name, value, attr= {}):77 def write_node(doc, parent, name, value, attr=None): 77 78 """ 78 79 :param doc: document DOM … … 84 85 :return: True if something was appended, otherwise False 85 86 """ 87 if attr is None: 88 attr = {} 86 89 if value is not None: 87 90 node = doc.createElement(name) … … 103 106 ##CanSAS version - defaults to version 1.0 104 107 cansas_version = "1.0" 108 base_ns = "{cansas1d/1.0}" 105 109 106 110 logging = [] … … 116 120 allow_all = True 117 121 122 118 123 def __init__(self): 119 124 ## List of errors 120 125 self.errors = [] 126 self.encoding = None 127 121 128 122 129 def is_cansas(self, ext="xml"): 123 130 """ 124 131 Checks to see if the xml file is a CanSAS file 132 133 :param ext: The file extension of the data file 125 134 """ 126 135 if self.validate_xml(): … … 134 143 return False 135 144 136 def read(self, xml): 137 """ 138 Validate and read in an xml file in the canSAS format. 139 140 :param xml: A canSAS file path in proper XML format 141 """ 142 # X - Q value; Y - Intensity (Abs) 143 x_vals = numpy.empty(0) 144 y_vals = numpy.empty(0) 145 dx_vals = numpy.empty(0) 146 dy_vals = numpy.empty(0) 147 dxl = numpy.empty(0) 148 dxw = numpy.empty(0) 145 146 def load_file_and_schema(self, xml_file): 147 """ 148 Loads the file and associates a schema, if a known schema exists 149 150 :param xml_file: The xml file path sent to Reader.read 151 """ 152 base_name = xml_reader.__file__ 153 base_name = base_name.replace("\\","/") 154 base = base_name.split("/sans/")[0] 155 156 # Load in xml file and get the cansas version from the header 157 self.set_xml_file(xml_file) 158 self.cansas_version = self.xmlroot.get("version", "1.0") 159 160 # Generic values for the cansas file based on the version 161 cansas_defaults = CANSAS_NS.get(self.cansas_version, "1.0") 162 schema_path = "{0}/sans/dataloader/readers/schema/{1}".format\ 163 (base, cansas_defaults.get("schema")).replace("\\", "/") 164 165 # Link a schema to the XML file. 166 self.set_schema(schema_path) 167 return cansas_defaults 168 169 170 def read(self, xml_file): 171 """ 172 Validate and read in an xml_file file in the canSAS format. 173 174 :param xml_file: A canSAS file path in proper XML format 175 """ 149 176 150 177 # output - Final list of Data1D objects 151 178 output = [] 152 # ns - Namespace hierarchy for current xml object179 # ns - Namespace hierarchy for current xml_file object 153 180 ns_list = [] 154 181 155 182 # Check that the file exists 156 if os.path.isfile(xml ):157 basename = os.path.basename(xml )183 if os.path.isfile(xml_file): 184 basename = os.path.basename(xml_file) 158 185 _, extension = os.path.splitext(basename) 159 186 # If the file type is not allowed, return nothing 160 187 if extension in self.ext or self.allow_all: 161 188 # Get the file location of 162 base_name = xml_reader.__file__ 163 base_name = base_name.replace("\\","/") 164 base = base_name.split("/sans/")[0] 165 166 # Load in xml file and get the cansas version from the header 167 self.set_xml_file(xml) 168 root = self.xmlroot 169 if root is None: 170 root = {} 171 self.cansas_version = root.get("version", "1.0") 172 173 # Generic values for the cansas file based on the version 174 cansas_defaults = CANSAS_NS.get(self.cansas_version, "1.0") 175 schema_path = "{0}/sans/dataloader/readers/schema/{1}".format\ 176 (base, cansas_defaults.get("schema")).replace("\\", "/") 177 178 # Link a schema to the XML file. 179 self.set_schema(schema_path) 189 cansas_defaults = self.load_file_and_schema(xml_file) 180 190 181 191 # Try to load the file, but raise an error if unable to. … … 184 194 if self.is_cansas(extension): 185 195 # Get each SASentry from XML file and add it to a list. 186 entry_list = root.xpath('/ns:SASroot/ns:SASentry', 187 namespaces={'ns': cansas_defaults.get("ns")}) 196 entry_list = self.xmlroot.xpath( 197 '/ns:SASroot/ns:SASentry', 198 namespaces = {'ns': cansas_defaults.get("ns")}) 188 199 ns_list.append("SASentry") 189 200 190 201 # If multiple files, modify the name for each is unique 191 multiple_files = len(entry_list) - 1192 202 increment = 0 193 name = basename194 203 # Parse each SASentry item 195 204 for entry in entry_list: 196 205 # Define a new Data1D object with zeroes for 197 206 # x_vals and y_vals 198 data1d = Data1D(x_vals, y_vals, dx_vals, dy_vals) 199 data1d.dxl = dxl 200 data1d.dxw = dxw 207 data1d = Data1D(numpy.empty(0), numpy.empty(0), \ 208 numpy.empty(0), numpy.empty(0)) 209 data1d.dxl = numpy.empty(0) 210 data1d.dxw = numpy.empty(0) 201 211 202 212 # If more than one SASentry, increment each in order 203 if multiple_files: 213 name = basename 214 if len(entry_list) - 1 > 0: 204 215 name += "_{0}".format(increment) 205 216 increment += 1 … … 220 231 del extras[:] 221 232 222 # Final cleanup 223 # Remove empty nodes, verify array sizes are correct 224 for error in self.errors: 225 return_value.errors.append(error) 226 del self.errors[:] 227 numpy.trim_zeros(return_value.x) 228 numpy.trim_zeros(return_value.y) 229 numpy.trim_zeros(return_value.dy) 230 size_dx = return_value.dx.size 231 size_dxl = return_value.dxl.size 232 size_dxw = return_value.dxw.size 233 if size_dxl == 0 and size_dxw == 0: 234 return_value.dxl = None 235 return_value.dxw = None 236 numpy.trim_zeros(return_value.dx) 237 elif size_dx == 0: 238 return_value.dx = None 239 size_dx = size_dxl 240 numpy.trim_zeros(return_value.dxl) 241 numpy.trim_zeros(return_value.dxw) 233 return_value = self._final_cleanup(return_value) 242 234 output.append(return_value) 243 235 else: 244 value = self.find_invalid_xml()245 output.append("Invalid XML at: {0}".format(value))236 output.append("Invalid XML at: {0}".format(\ 237 self.find_invalid_xml())) 246 238 except: 247 239 # If the file does not match the schema, raise this error 248 raise RuntimeError, "%s cannot be read" % xml 240 raise RuntimeError, "%s cannot be read" % xml_file 249 241 return output 250 242 # Return a list of parsed entries that dataloader can manage 251 243 return None 244 245 246 def _final_cleanup(self, data1d): 247 """ 248 Final cleanup of the Data1D object to be sure it has all the 249 appropriate information needed for perspectives 250 251 :param data1d: Data1D object that has been populated 252 """ 253 # Final cleanup 254 # Remove empty nodes, verify array sizes are correct 255 for error in self.errors: 256 data1d.errors.append(error) 257 del self.errors[:] 258 numpy.trim_zeros(data1d.x) 259 numpy.trim_zeros(data1d.y) 260 numpy.trim_zeros(data1d.dy) 261 size_dx = data1d.dx.size 262 size_dxl = data1d.dxl.size 263 size_dxw = data1d.dxw.size 264 if size_dxl == 0 and size_dxw == 0: 265 data1d.dxl = None 266 data1d.dxw = None 267 numpy.trim_zeros(data1d.dx) 268 elif size_dx == 0: 269 data1d.dx = None 270 size_dx = size_dxl 271 numpy.trim_zeros(data1d.dxl) 272 numpy.trim_zeros(data1d.dxw) 273 return data1d 274 252 275 253 276 def _create_unique_key(self, dictionary, name, numb = 0): … … 268 291 269 292 270 def _unit_conversion(self, n ew_current_level, attr, data1d, \271 tagname, node_value, optional = True):293 def _unit_conversion(self, node, new_current_level, data1d, \ 294 tagname, node_value): 272 295 """ 273 296 A unit converter method used to convert the data included in the file … … 279 302 :param data1d: Where the values will be saved 280 303 :param node_value: The value of the current dom node 281 :param optional: Boolean that says if the units are required282 """304 """ 305 attr = node.attrib 283 306 value_unit = '' 284 307 if 'unit' in attr and new_current_level.get('unit') is not None: … … 291 314 local_unit = attr['unit'] 292 315 if local_unit.lower() != default_unit.lower() and \ 293 local_unit is not None and local_unit.lower() != "none" and\294 default_unit is not None:316 local_unit is not None and local_unit.lower() != "none" \ 317 and default_unit is not None: 295 318 if HAS_CONVERTER == True: 296 319 try: … … 299 322 data_conv_q = Converter(attr['unit']) 300 323 value_unit = default_unit 301 exec "node_value = data_conv_q(node_value, units=data1d.{0})".format(unitname) 302 except KeyError as e: 324 i_string = "node_value = data_conv_q" 325 i_string += "(node_value, units=data1d.{0})" 326 exec i_string.format(unitname) 327 except KeyError: 303 328 err_msg = "CanSAS reader: could not convert " 304 err_msg += "{0} unit {1}; ".format(tagname, local_unit) 305 intermediate = "err_msg += \"expecting [{1}] {2}\".format(data1d.{0}, sys.exc_info()[1])".format(unitname, "{0}", "{1}") 306 exec intermediate 329 err_msg += "{0} unit {1}; " 330 err_msg = err_msg.format(tagname, local_unit) 331 intermediate = "err_msg += " + \ 332 "\"expecting [{1}] {2}\"" + \ 333 ".format(data1d.{0}, " + \ 334 "sys.exc_info()[1])" 335 exec intermediate.format(unitname, "{0}", "{1}") 307 336 self.errors.append(err_msg) 308 337 raise ValueError(err_msg) 309 return310 338 except: 311 339 err_msg = \ … … 320 348 self.errors.append(err_msg) 321 349 raise ValueError, err_msg 322 return323 350 else: 324 351 value_unit = local_unit 325 352 except: 326 353 err_msg = "CanSAS reader: could not convert " 327 err_msg += "Q unit [%s]; " % attr['unit'], 328 exec "err_msg += \"expecting [%s]\n %s\" % (data1d.{0}, sys.exc_info()[1])".format(unitname) 354 err_msg += "Q unit [%s]; " % attr['unit'] 355 intermediate = "err_msg += \"expecting [%s]\n %s\" % " + \ 356 "(data1d.{0}, sys.exc_info()[1])" 357 exec intermediate.format(unitname) 329 358 self.errors.append(err_msg) 330 359 raise ValueError, err_msg 331 return332 360 elif 'unit' in attr: 333 361 value_unit = attr['unit'] … … 335 363 return node_value, value_unit 336 364 337 def _parse_entry(self, dom, names=["SASentry"], data1d=None, extras=[]): 338 """ 339 Parse a SASEntry - new recursive method for parsing the dom of 340 the CanSAS data format. This will allow multiple data files 341 and extra nodes to be read in simultaneously. 342 343 :param dom: dom object with a namespace base of names 344 :param names: A list of element names that lead up to the dom object 345 :param data1d: The data1d object that will be modified 346 :param extras: Any values that should go into meta_data when data1d 347 is not a Data1D object 348 """ 349 350 # A portion of every namespace entry 365 366 def _check_for_empty_data(self, data1d): 367 """ 368 Creates an empty data set if no data is passed to the reader 369 370 :param data1d: presumably a Data1D object 371 """ 351 372 if data1d == None: 373 self.errors = [] 352 374 x_vals = numpy.empty(0) 353 375 y_vals = numpy.empty(0) … … 359 381 data1d.dxl = dxl 360 382 data1d.dxw = dxw 383 return data1d 384 385 386 def _handle_special_cases(self, tagname, data1d, children): 387 """ 388 Handle cases where the data type in Data1D is a dictionary or list 389 390 :param tagname: XML tagname in use 391 :param data1d: The original Data1D object 392 :param children: Child nodes of node 393 :param node: existing node with tag name 'tagname' 394 """ 395 if tagname == "SASdetector": 396 data1d = Detector() 397 elif tagname == "SAScollimation": 398 data1d = Collimation() 399 elif tagname == "SAStransmission_spectrum": 400 data1d = TransmissionSpectrum() 401 elif tagname == "SASprocess": 402 data1d = Process() 403 for child in children: 404 if child.tag.replace(self.base_ns, "") == "term": 405 term_attr = {} 406 for attr in child.keys(): 407 term_attr[attr] = \ 408 ' '.join(child.get(attr).split()) 409 if child.text is not None: 410 term_attr['value'] = \ 411 ' '.join(child.text.split()) 412 data1d.term.append(term_attr) 413 elif tagname == "aperture": 414 data1d = Aperture() 415 if tagname == "Idata" and children is not None: 416 data1d = self._check_for_empty_resolution(data1d, children) 417 return data1d 418 419 420 def _check_for_empty_resolution(self, data1d, children): 421 """ 422 A method to check all resolution data sets are the same size as I and Q 423 """ 424 dql_exists = False 425 dqw_exists = False 426 dq_exists = False 427 di_exists = False 428 for child in children: 429 tag = child.tag.replace(self.base_ns, "") 430 if tag == "dQl": 431 dql_exists = True 432 if tag == "dQw": 433 dqw_exists = True 434 if tag == "Qdev": 435 dq_exists = True 436 if tag == "Idev": 437 di_exists = True 438 if dqw_exists and dql_exists == False: 439 data1d.dxl = numpy.append(data1d.dxl, 0.0) 440 elif dql_exists and dqw_exists == False: 441 data1d.dxw = numpy.append(data1d.dxw, 0.0) 442 elif dql_exists == False and dqw_exists == False \ 443 and dq_exists == False: 444 data1d.dx = numpy.append(data1d.dx, 0.0) 445 if di_exists == False: 446 data1d.dy = numpy.append(data1d.dy, 0.0) 447 return data1d 448 449 450 def _restore_original_case(self, 451 tagname_original, 452 tagname, 453 save_data1d, 454 data1d): 455 """ 456 Save the special case data to the appropriate location and restore 457 the original Data1D object 458 459 :param tagname_original: Unmodified tagname for the node 460 :param tagname: modified tagname for the node 461 :param save_data1d: The original Data1D object 462 :param data1d: If a special case was handled, an object of that type 463 """ 464 if tagname_original == "SASdetector": 465 save_data1d.detector.append(data1d) 466 elif tagname_original == "SAScollimation": 467 save_data1d.collimation.append(data1d) 468 elif tagname == "SAStransmission_spectrum": 469 save_data1d.trans_spectrum.append(data1d) 470 elif tagname_original == "SASprocess": 471 save_data1d.process.append(data1d) 472 elif tagname_original == "aperture": 473 save_data1d.aperture.append(data1d) 474 else: 475 save_data1d = data1d 476 return save_data1d 477 478 479 def _handle_attributes(self, node, data1d, cs_values, tagname): 480 """ 481 Process all of the attributes for a node 482 """ 483 attr = node.attrib 484 if attr is not None: 485 for key in node.keys(): 486 try: 487 node_value, unit = self._get_node_value(node, cs_values, \ 488 data1d, tagname) 489 cansas_attrib = \ 490 cs_values.current_level.get("attributes").get(key) 491 attrib_variable = cansas_attrib.get("variable") 492 if key == 'unit' and unit != '': 493 attrib_value = unit 494 else: 495 attrib_value = node.attrib[key] 496 store_attr = attrib_variable.format("data1d", \ 497 attrib_value, key) 498 exec store_attr 499 except AttributeError: 500 pass 501 return data1d 502 503 504 def _get_node_value(self, node, cs_values, data1d, tagname): 505 """ 506 Get the value of a node and any applicable units 507 508 :param node: The XML node to get the value of 509 :param cs_values: A CansasConstants.CurrentLevel object 510 :param attr: The node attributes 511 :param dataid: The working object to be modified 512 :param tagname: The tagname of the node 513 """ 514 #Get the text from the node and convert all whitespace to spaces 515 units = '' 516 node_value = node.text 517 if node_value == "": 518 node_value = None 519 if node_value is not None: 520 node_value = ' '.join(node_value.split()) 521 522 # If the value is a float, compile with units. 523 if cs_values.ns_datatype == "float": 524 # If an empty value is given, set as zero. 525 if node_value is None or node_value.isspace() \ 526 or node_value.lower() == "nan": 527 node_value = "0.0" 528 #Convert the value to the base units 529 node_value, units = self._unit_conversion(node, \ 530 cs_values.current_level, data1d, tagname, node_value) 531 532 # If the value is a timestamp, convert to a datetime object 533 elif cs_values.ns_datatype == "timestamp": 534 if node_value is None or node_value.isspace(): 535 pass 536 else: 537 try: 538 node_value = \ 539 datetime.datetime.fromtimestamp(node_value) 540 except ValueError: 541 node_value = None 542 return node_value, units 543 544 545 def _parse_entry(self, dom, names=None, data1d=None, extras=None): 546 """ 547 Parse a SASEntry - new recursive method for parsing the dom of 548 the CanSAS data format. This will allow multiple data files 549 and extra nodes to be read in simultaneously. 550 551 :param dom: dom object with a namespace base of names 552 :param names: A list of element names that lead up to the dom object 553 :param data1d: The data1d object that will be modified 554 :param extras: Any values that should go into meta_data when data1d 555 is not a Data1D object 556 """ 557 558 if extras is None: 559 extras = [] 560 if names is None or names == []: 561 names = ["SASentry"] 562 563 data1d = self._check_for_empty_data(data1d) 361 564 362 base_ns = "{0}{1}{2}".format("{", \565 self.base_ns = "{0}{1}{2}".format("{", \ 363 566 CANSAS_NS.get(self.cansas_version).get("ns"), "}") 364 unit = ''365 567 tagname = '' 366 568 tagname_original = '' … … 370 572 try: 371 573 # Get the element name and set the current names level 372 tagname = node.tag.replace( base_ns, "")574 tagname = node.tag.replace(self.base_ns, "") 373 575 tagname_original = tagname 374 576 if tagname == "fitting_plug_in" or tagname == "pr_inversion" or\ … … 376 578 continue 377 579 names.append(tagname) 378 attr = node.attrib379 580 children = node.getchildren() 380 581 if len(children) == 0: … … 383 584 384 585 # Look for special cases 385 if tagname == "SASdetector": 386 data1d = Detector() 387 elif tagname == "SAScollimation": 388 data1d = Collimation() 389 elif tagname == "SAStransmission_spectrum": 390 data1d = TransmissionSpectrum() 391 elif tagname == "SASprocess": 392 data1d = Process() 393 for child in node: 394 if child.tag.replace(base_ns, "") == "term": 395 term_attr = {} 396 for attr in child.keys(): 397 term_attr[attr] = \ 398 ' '.join(child.get(attr).split()) 399 if child.text is not None: 400 term_attr['value'] = \ 401 ' '.join(child.text.split()) 402 data1d.term.append(term_attr) 403 elif tagname == "aperture": 404 data1d = Aperture() 405 if tagname == "Idata" and children is not None: 406 dql = 0 407 dqw = 0 408 for child in children: 409 tag = child.tag.replace(base_ns, "") 410 if tag == "dQl": 411 dql = 1 412 if tag == "dQw": 413 dqw = 1 414 if dqw == 1 and dql == 0: 415 data1d.dxl = numpy.append(data1d.dxl, 0.0) 416 elif dql == 1 and dqw == 0: 417 data1d.dxw = numpy.append(data1d.dxw, 0.0) 418 586 data1d = self._handle_special_cases(tagname, data1d, children) 587 419 588 # Get where to store content 420 589 cs_values = CONSTANTS.iterate_namespace(names) … … 427 596 428 597 #Get the information from the node 429 node_value = node.text 430 if node_value == "": 431 node_value = None 432 if node_value is not None: 433 node_value = ' '.join(node_value.split()) 434 435 # If the value is a float, compile with units. 436 if cs_values.ns_datatype == "float": 437 # If an empty value is given, store as zero. 438 if node_value is None or node_value.isspace() \ 439 or node_value.lower() == "nan": 440 node_value = "0.0" 441 node_value, unit = self._unit_conversion(\ 442 cs_values.current_level, attr, data1d, \ 443 tagname, node_value, cs_values.ns_optional) 444 # If the value is a timestamp, convert to a datetime object 445 elif cs_values.ns_datatype == "timestamp": 446 if node_value is None or node_value.isspace(): 447 pass 448 else: 449 try: 450 node_value = \ 451 datetime.datetime.fromtimestamp(node_value) 452 except ValueError: 453 node_value = None 598 node_value, _ = self._get_node_value(node, cs_values, \ 599 data1d, tagname) 600 454 601 # If appending to a dictionary (meta_data | run_name) 455 602 # make sure the key is unique … … 481 628 exec store_me 482 629 # Get attributes and process them 483 if attr is not None: 484 for key in node.keys(): 485 try: 486 cansas_attrib = \ 487 cs_values.current_level.get("attributes").get(key) 488 attrib_variable = cansas_attrib.get("variable") 489 if key == 'unit' and unit != '': 490 attrib_value = unit 491 else: 492 attrib_value = node.attrib[key] 493 store_attr = attrib_variable.format("data1d", \ 494 attrib_value, key) 495 exec store_attr 496 except AttributeError as e: 497 pass 498 499 except TypeError as e: 630 data1d = self._handle_attributes(node, data1d, cs_values, \ 631 tagname) 632 633 except TypeError: 500 634 pass 501 except Exception as e :635 except Exception as excep: 502 636 exc_type, exc_obj, exc_tb = sys.exc_info() 503 637 fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 504 print(e, exc_type, fname, exc_tb.tb_lineno, tagname, exc_obj) 638 print(excep, exc_type, fname, exc_tb.tb_lineno, \ 639 tagname, exc_obj) 505 640 finally: 506 641 # Save special cases in original data1d object 507 642 # then restore the data1d 508 if tagname_original == "SASdetector": 509 save_data1d.detector.append(data1d) 510 elif tagname_original == "SAScollimation": 511 save_data1d.collimation.append(data1d) 512 elif tagname == "SAStransmission_spectrum": 513 save_data1d.trans_spectrum.append(data1d) 514 elif tagname_original == "SASprocess": 515 save_data1d.process.append(data1d) 516 elif tagname_original == "aperture": 517 save_data1d.aperture.append(data1d) 518 else: 519 save_data1d = data1d 643 save_data1d = self._restore_original_case(tagname_original, \ 644 tagname, save_data1d, data1d) 520 645 if tagname_original == "fitting_plug_in" or \ 521 646 tagname_original == "invariant" or \ … … 529 654 530 655 531 def _to_xml_doc(self, datainfo): 532 """ 533 Create an XML document to contain the content of a Data1D 534 535 :param datainfo: Data1D object 536 """ 537 if not issubclass(datainfo.__class__, Data1D): 538 raise RuntimeError, "The cansas writer expects a Data1D instance" 539 540 # Get PIs and create root element 656 def _get_pi_string(self): 657 """ 658 Creates the processing instructions header for writing to file 659 """ 541 660 pis = self.return_processing_instructions() 542 661 if len(pis) > 0: 543 662 pi_tree = self.create_tree(pis[0]) 544 663 i = 1 545 for i in range(1, len(pis) - 1):664 for i in range(1, len(pis) - 1): 546 665 pi_tree = self.append(pis[i], pi_tree) 547 666 pi_string = self.to_string(pi_tree) 548 667 else: 549 668 pi_string = "" 550 551 # Define namespaces and create SASroot object 669 return pi_string 670 671 672 def _create_main_node(self): 673 """ 674 Creates the primary xml header used when writing to file 675 """ 552 676 xsi = "http://www.w3.org/2001/XMLSchema-instance" 553 677 version = self.cansas_version 554 n s = CANSAS_NS.get(version).get("ns")678 n_s = CANSAS_NS.get(version).get("ns") 555 679 if version == "1.1": 556 680 url = "http://www.cansas.org/formats/1.1/" 557 681 else: 558 682 url = "http://svn.smallangles.net/svn/canSAS/1dwg/trunk/" 559 schema_location = "{0} {1}cansas1d.xsd".format(n s, url)683 schema_location = "{0} {1}cansas1d.xsd".format(n_s, url) 560 684 attrib = {"{" + xsi + "}schemaLocation" : schema_location, 561 685 "version" : version} 562 nsmap = {'xsi' : xsi, None: n s}563 564 main_node = self.create_element("{" + n s + "}SASroot", \686 nsmap = {'xsi' : xsi, None: n_s} 687 688 main_node = self.create_element("{" + n_s + "}SASroot", \ 565 689 attrib = attrib, \ 566 690 nsmap = nsmap) 567 568 # Create ElementTree, append SASroot and apply processing instructions 569 base_string = pi_string + self.to_string(main_node) 570 base_element = self.create_element_from_string(base_string) 571 doc = self.create_tree(base_element) 572 573 # Create SASentry Element 574 entry_node = self.create_element("SASentry") 575 root = doc.getroot() 576 root.append(entry_node) 577 578 # Add Title to SASentry 579 self.write_node(entry_node, "Title", datainfo.title) 580 581 # Add Run to SASentry 691 return main_node 692 693 694 def _write_run_names(self, datainfo, entry_node): 695 """ 696 Writes the run names to the XML file 697 698 :param datainfo: The Data1D object the information is coming from 699 :param entry_node: lxml node ElementTree object to be appended to 700 """ 582 701 if datainfo.run == None or datainfo.run == []: 583 RUN_NAME_DEFAULT = "None"584 702 datainfo.run.append(RUN_NAME_DEFAULT) 585 703 datainfo.run_name[RUN_NAME_DEFAULT] = RUN_NAME_DEFAULT … … 590 708 runname = {'name': datainfo.run_name[item]} 591 709 self.write_node(entry_node, "Run", item, runname) 592 593 # Data info 710 711 712 def _write_data(self, datainfo, entry_node): 713 """ 714 Writes the I and Q data to the XML file 715 716 :param datainfo: The Data1D object the information is coming from 717 :param entry_node: lxml node ElementTree object to be appended to 718 """ 594 719 node = self.create_element("SASdata") 595 720 self.append(node, entry_node) 596 721 597 722 for i in range(len(datainfo.x)): 598 pt = self.create_element("Idata") 599 node.append(pt) 600 self.write_node(pt, "Q", datainfo.x[i], {'unit': datainfo.x_unit}) 723 point = self.create_element("Idata") 724 node.append(point) 725 self.write_node(point, "Q", datainfo.x[i], \ 726 {'unit': datainfo.x_unit}) 601 727 if len(datainfo.y) >= i: 602 self.write_node(p t, "I", datainfo.y[i],728 self.write_node(point, "I", datainfo.y[i], 603 729 {'unit': datainfo.y_unit}) 604 730 if datainfo.dy != None and len(datainfo.dy) > i: 605 self.write_node(p t, "Idev", datainfo.dy[i],731 self.write_node(point, "Idev", datainfo.dy[i], 606 732 {'unit': datainfo.y_unit}) 607 733 if datainfo.dx != None and len(datainfo.dx) > i: 608 self.write_node(p t, "Qdev", datainfo.dx[i],734 self.write_node(point, "Qdev", datainfo.dx[i], 609 735 {'unit': datainfo.x_unit}) 610 736 if datainfo.dxw != None and len(datainfo.dxw) > i: 611 self.write_node(p t, "dQw", datainfo.dxw[i],737 self.write_node(point, "dQw", datainfo.dxw[i], 612 738 {'unit': datainfo.x_unit}) 613 739 if datainfo.dxl != None and len(datainfo.dxl) > i: 614 self.write_node(p t, "dQl", datainfo.dxl[i],740 self.write_node(point, "dQl", datainfo.dxl[i], 615 741 {'unit': datainfo.x_unit}) 616 742 617 # Transmission Spectrum Info 743 744 745 def _write_trans_spectrum(self, datainfo, entry_node): 746 """ 747 Writes the transmission spectrum data to the XML file 748 749 :param datainfo: The Data1D object the information is coming from 750 :param entry_node: lxml node ElementTree object to be appended to 751 """ 618 752 for i in range(len(datainfo.trans_spectrum)): 619 753 spectrum = datainfo.trans_spectrum[i] … … 624 758 node.setAttribute("timestamp", spectrum.timestamp) 625 759 for i in range(len(spectrum.wavelength)): 626 p t = self.create_element("Tdata")627 node.append(p t)628 self.write_node(p t, "Lambda", spectrum.wavelength[i],760 point = self.create_element("Tdata") 761 node.append(point) 762 self.write_node(point, "Lambda", spectrum.wavelength[i], 629 763 {'unit': spectrum.wavelength_unit}) 630 self.write_node(p t, "T", spectrum.transmission[i],764 self.write_node(point, "T", spectrum.transmission[i], 631 765 {'unit': spectrum.transmission_unit}) 632 766 if spectrum.transmission_deviation != None \ 633 767 and len(spectrum.transmission_deviation) >= i: 634 self.write_node(p t, "Tdev", \768 self.write_node(point, "Tdev", \ 635 769 spectrum.transmission_deviation[i], \ 636 770 {'unit': spectrum.transmission_deviation_unit}) 637 638 # Sample info 771 772 773 def _write_sample_info(self, datainfo, entry_node): 774 """ 775 Writes the sample information to the XML file 776 777 :param datainfo: The Data1D object the information is coming from 778 :param entry_node: lxml node ElementTree object to be appended to 779 """ 639 780 sample = self.create_element("SASsample") 640 781 if datainfo.sample.name is not None: … … 681 822 for item in datainfo.sample.details: 682 823 self.write_node(sample, "details", item) 683 684 # Instrument info 824 825 826 def _write_instrument(self, datainfo, entry_node): 827 """ 828 Writes the instrumental information to the XML file 829 830 :param datainfo: The Data1D object the information is coming from 831 :param entry_node: lxml node ElementTree object to be appended to 832 """ 685 833 instr = self.create_element("SASinstrument") 686 834 self.append(instr, entry_node) 687 688 835 self.write_node(instr, "name", datainfo.instrument) 689 690 # Source 836 return instr 837 838 839 def _write_source(self, datainfo, instr): 840 """ 841 Writes the source information to the XML file 842 843 :param datainfo: The Data1D object the information is coming from 844 :param instr: instrument node to be appended to 845 """ 691 846 source = self.create_element("SASsource") 692 847 if datainfo.source.name is not None: … … 728 883 datainfo.source.wavelength_spread, 729 884 {"unit": datainfo.source.wavelength_spread_unit}) 730 731 # Collimation 885 886 887 def _write_collimation(self, datainfo, instr): 888 """ 889 Writes the collimation information to the XML file 890 891 :param datainfo: The Data1D object the information is coming from 892 :param instr: lxml node ElementTree object to be appended to 893 """ 732 894 if datainfo.collimation == [] or datainfo.collimation == None: 733 895 coll = Collimation() … … 742 904 {"unit": item.length_unit}) 743 905 744 for apert in item.aperture:745 ap = self.create_element("aperture")746 if apert .name is not None:747 self.write_attribute(ap , "name", str(apert.name))748 if apert .type is not None:749 self.write_attribute(ap , "type", str(apert.type))750 self.append(ap , coll)906 for aperture in item.aperture: 907 apert = self.create_element("aperture") 908 if aperture.name is not None: 909 self.write_attribute(apert, "name", str(aperture.name)) 910 if aperture.type is not None: 911 self.write_attribute(apert, "type", str(aperture.type)) 912 self.append(apert, coll) 751 913 752 914 size = self.create_element("size") 753 if apert .size_name is not None:915 if aperture.size_name is not None: 754 916 self.write_attribute(size, 755 917 "name", 756 str(apert .size_name))757 written = self.write_node(size, "x", apert .size.x,758 {"unit": apert .size_unit})759 written = written | self.write_node(size, "y", apert .size.y,760 {"unit": apert .size_unit})761 written = written | self.write_node(size, "z", apert .size.z,762 {"unit": apert .size_unit})918 str(aperture.size_name)) 919 written = self.write_node(size, "x", aperture.size.x, 920 {"unit": aperture.size_unit}) 921 written = written | self.write_node(size, "y", aperture.size.y, 922 {"unit": aperture.size_unit}) 923 written = written | self.write_node(size, "z", aperture.size.z, 924 {"unit": aperture.size_unit}) 763 925 if written == True: 764 self.append(size, ap) 765 766 self.write_node(ap, "distance", apert.distance, 767 {"unit": apert.distance_unit}) 768 769 # Detectors 926 self.append(size, apert) 927 928 self.write_node(apert, "distance", aperture.distance, 929 {"unit": aperture.distance_unit}) 930 931 932 def _write_detectors(self, datainfo, instr): 933 """ 934 Writes the detector information to the XML file 935 936 :param datainfo: The Data1D object the information is coming from 937 :param inst: lxml instrument node to be appended to 938 """ 770 939 if datainfo.detector == None or datainfo.detector == []: 771 940 det = Detector() … … 827 996 if written == True: 828 997 self.append(pix, det) 829 830 # Processes info 998 999 1000 def _write_process_notes(self, datainfo, entry_node): 1001 """ 1002 Writes the process notes to the XML file 1003 1004 :param datainfo: The Data1D object the information is coming from 1005 :param entry_node: lxml node ElementTree object to be appended to 1006 1007 """ 831 1008 for item in datainfo.process: 832 1009 node = self.create_element("SASprocess") … … 844 1021 if len(item.notes) == 0: 845 1022 self.write_node(node, "SASprocessnote", "") 846 847 # Note info 1023 1024 1025 def _write_notes(self, datainfo, entry_node): 1026 """ 1027 Writes the notes to the XML file and creates an empty note if none 1028 exist 1029 1030 :param datainfo: The Data1D object the information is coming from 1031 :param entry_node: lxml node ElementTree object to be appended to 1032 1033 """ 848 1034 if len(datainfo.notes) == 0: 849 1035 node = self.create_element("SASnote") … … 854 1040 self.write_text(node, item) 855 1041 self.append(node, entry_node) 856 857 858 # Return the document, and the SASentry node associated with 859 # the data we just wrote 860 # If the calling function was not the cansas reader, return a minidom 861 # object rather than an lxml object. 1042 1043 1044 def _check_origin(self, entry_node, doc): 1045 """ 1046 Return the document, and the SASentry node associated with 1047 the data we just wrote. 1048 If the calling function was not the cansas reader, return a minidom 1049 object rather than an lxml object. 1050 1051 :param entry_node: lxml node ElementTree object to be appended to 1052 :param doc: entire xml tree 1053 """ 862 1054 frm = inspect.stack()[1] 863 1055 mod_name = frm[1].replace("\\", "/").replace(".pyc", "") … … 866 1058 mod_name = mod[1] 867 1059 if mod_name != "dataloader/readers/cansas_reader": 868 string = self.to_string(doc, p p=False)1060 string = self.to_string(doc, pretty_print=False) 869 1061 doc = parseString(string) 870 1062 node_name = entry_node.tag 871 1063 node_list = doc.getElementsByTagName(node_name) 872 1064 entry_node = node_list.item(0) 1065 return entry_node 1066 1067 1068 def _to_xml_doc(self, datainfo): 1069 """ 1070 Create an XML document to contain the content of a Data1D 1071 1072 :param datainfo: Data1D object 1073 """ 1074 if not issubclass(datainfo.__class__, Data1D): 1075 raise RuntimeError, "The cansas writer expects a Data1D instance" 1076 1077 # Get PIs and create root element 1078 pi_string = self._get_pi_string() 1079 1080 # Define namespaces and create SASroot object 1081 main_node = self._create_main_node() 1082 1083 # Create ElementTree, append SASroot and apply processing instructions 1084 base_string = pi_string + self.to_string(main_node) 1085 base_element = self.create_element_from_string(base_string) 1086 doc = self.create_tree(base_element) 1087 1088 # Create SASentry Element 1089 entry_node = self.create_element("SASentry") 1090 root = doc.getroot() 1091 root.append(entry_node) 1092 1093 # Add Title to SASentry 1094 self.write_node(entry_node, "Title", datainfo.title) 1095 1096 # Add Run to SASentry 1097 self._write_run_names(datainfo, entry_node) 1098 1099 # Add Data info to SASEntry 1100 self._write_data(datainfo, entry_node) 1101 1102 # Transmission Spectrum Info 1103 self._write_trans_spectrum(datainfo, entry_node) 1104 1105 # Sample info 1106 self._write_sample_info(datainfo, entry_node) 1107 1108 # Instrument info 1109 instr = self._write_instrument(datainfo, entry_node) 1110 1111 # Source 1112 self._write_source(datainfo, instr) 1113 1114 # Collimation 1115 self._write_collimation(datainfo, instr) 1116 1117 # Detectors 1118 self._write_detectors(datainfo, instr) 873 1119 1120 # Processes info 1121 self._write_process_notes(datainfo, entry_node) 1122 1123 # Note info 1124 self._write_notes(datainfo, entry_node) 1125 1126 # Return the document, and the SASentry node associated with 1127 # the data we just wrote 1128 # If the calling function was not the cansas reader, return a minidom 1129 # object rather than an lxml object. 1130 entry_node = self._check_origin(entry_node, doc) 1131 874 1132 return doc, entry_node 875 1133 … … 901 1159 doc, _ = self._to_xml_doc(datainfo) 902 1160 # Write the file 903 f d= open(filename, 'w')1161 file_ref = open(filename, 'w') 904 1162 if self.encoding == None: 905 1163 self.encoding = "UTF-8" 906 doc.write(f d, encoding=self.encoding,1164 doc.write(file_ref, encoding=self.encoding, 907 1165 pretty_print=True, xml_declaration=True) 908 f d.close()1166 file_ref.close() 909 1167 910 1168 … … 950 1208 conv(value, units=local_unit)) 951 1209 except: 952 exc_type, exc_value, exc_traceback= sys.exc_info()1210 _, exc_value, _ = sys.exc_info() 953 1211 err_mess = "CanSAS reader: could not convert" 954 1212 err_mess += " %s unit [%s]; expecting [%s]\n %s" \ -
src/sans/dataloader/readers/defaults.xml
r5777106 r3241dd2 9 9 <FileType extension='.asc' reader='IgorReader'/> 10 10 <FileType extension='.dat' reader='red2d_reader'/> 11 <!-- 12 Removed the tiff_reader for now. To reinstate, remove the XML comment 11 13 <FileType extension='.tif' reader='tiff_reader'/> 14 --> 12 15 <FileType extension='.abs' reader='abs_reader'/> 13 16 <FileType extension='.d1d' reader='hfir1d_reader'/> -
src/sans/dataloader/readers/xml_reader.py
rac5b69d r3241dd2 15 15 ############################################################################# 16 16 17 import logging 17 18 from lxml import etree 18 19 from lxml.builder import E … … 37 38 processing_instructions = None 38 39 39 def __init__(self, xml = None, schema = None , root = None):40 def __init__(self, xml = None, schema = None): 40 41 self.xml = xml 41 42 self.schema = schema 42 43 self.processing_instructions = {} 43 44 if xml is not None: 44 self.set_xml_file(xml , root)45 self.set_xml_file(xml) 45 46 else: 46 47 self.xmldoc = None … … 61 62 return self.xmldoc 62 63 63 def set_xml_file(self, xml , root = None):64 def set_xml_file(self, xml): 64 65 """ 65 66 Set the XML file and parse … … 69 70 self.xmldoc = etree.parse(self.xml, parser = PARSER) 70 71 self.xmlroot = self.xmldoc.getroot() 72 except etree.XMLSyntaxError as xml_error: 73 logging.info(xml_error) 71 74 except Exception: 72 75 self.xml = None … … 81 84 self.schema = schema 82 85 self.schemadoc = etree.parse(self.schema, parser = PARSER) 86 except etree.XMLSyntaxError as xml_error: 87 logging.info(xml_error) 83 88 except Exception: 84 89 self.schema = None … … 105 110 try: 106 111 first_error = schema.assertValid(self.xmldoc) 107 except etree.DocumentInvalid as e :108 first_error = str(e )112 except etree.DocumentInvalid as err: 113 first_error = str(err) 109 114 return first_error 110 115 … … 116 121 self.set_schema(self.schema) 117 122 118 def to_string(self, elem, p p=False, encoding=None):123 def to_string(self, elem, pretty_print=False, encoding=None): 119 124 """ 120 125 Converts an etree element into a string 121 126 """ 122 return etree.tostring(elem, pretty_print = pp, encoding = encoding) 127 return etree.tostring(elem, pretty_print = pretty_print, \ 128 encoding = encoding) 123 129 124 130 def break_processing_instructions(self, string, dic): -
test/sansdataloader/test/utest_cansas.py
rac5b69d r3241dd2 2 2 Unit tests for the new recursive cansas reader 3 3 """ 4 import logging 4 5 import warnings 5 6 warnings.simplefilter("ignore") … … 51 52 name = self.get_number_of_entries(dictionary, name, i) 52 53 return name 54 55 56 def test_invalid_xml(self): 57 """ 58 Should fail gracefully and send a message to logging.info() 59 """ 60 invalid = StringIO.StringIO('<a><c></b></a>') 61 reader = XMLreader(invalid) 53 62 54 63 … … 203 212 ## find the processing instructions and make into a dictionary 204 213 dic = self.get_processing_instructions(reader) 205 self.assertTrue(dic == {'xml-stylesheet': 'type="text/xsl" href="cansas1d.xsl" '}) 214 self.assertTrue(dic == {'xml-stylesheet': \ 215 'type="text/xsl" href="cansas1d.xsl" '}) 206 216 207 217 xml = "<test><a><b><c></c></b></a></test>"
Note: See TracChangeset
for help on using the changeset viewer.