voruby 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. data/Rakefile.rb +107 -224
  2. data/lib/misc.rb +1 -0
  3. data/lib/misc/misc.rb +60 -0
  4. data/lib/misc/propertyfile.rb +31 -0
  5. data/lib/symphony.rb +1 -0
  6. data/lib/symphony/symphony.rb +247 -0
  7. data/lib/voruby.rb +186 -0
  8. data/lib/voruby/active_votable/active_votable.rb +468 -347
  9. data/lib/voruby/adql/1.0/adql.rb +2418 -0
  10. data/lib/voruby/adql/support.rb +2 -0
  11. data/lib/voruby/misc.rb +351 -0
  12. data/lib/voruby/misc/connection_monitor.rb +97 -0
  13. data/lib/voruby/misc/libxml_ext.rb +121 -0
  14. data/lib/voruby/misc/rexml_ext.rb +223 -0
  15. data/lib/voruby/resolver/resolver.rb +12 -0
  16. data/lib/voruby/resolver/sesame.rb +299 -0
  17. data/lib/voruby/sky_query/sky_query.rb +192 -0
  18. data/lib/voruby/stc/1.10/coords.rb +2272 -0
  19. data/lib/voruby/stc/1.10/region.rb +892 -0
  20. data/lib/voruby/stc/1.10/stc.rb +3271 -0
  21. data/lib/voruby/stc/1.30/stc.rb +8666 -0
  22. data/lib/voruby/stc/support.rb +2 -0
  23. data/lib/voruby/ucd/ucd.rb +173 -0
  24. data/lib/voruby/voevent/1.1/voevent.rb +1124 -0
  25. data/lib/voruby/voevent/support.rb +5 -0
  26. data/lib/voruby/votable/1.0/votable.rb +1807 -0
  27. data/lib/voruby/votable/1.1/votable.rb +2100 -0
  28. data/lib/voruby/votable/votable.rb +305 -0
  29. data/lib/voruby/wesix/wesix.rb +491 -0
  30. data/lib/voruby/xlink/1.2/xlink.rb +21 -0
  31. data/test/voruby/active_votable/complex.vot +60 -0
  32. data/test/voruby/active_votable/error.vot +6 -0
  33. data/test/voruby/active_votable/large.vot +130040 -0
  34. data/test/voruby/active_votable/simple1.vot +38 -0
  35. data/test/voruby/active_votable/simple2.vot +38 -0
  36. data/test/voruby/active_votable/test.rb +193 -0
  37. data/test/voruby/adql/1.0/adql-alias.sql +1 -0
  38. data/test/voruby/adql/1.0/adql-alias.xml +26 -0
  39. data/test/voruby/adql/1.0/adql-avg.sql +1 -0
  40. data/test/voruby/adql/1.0/adql-avg.xml +31 -0
  41. data/test/voruby/adql/1.0/adql-circle.sql +1 -0
  42. data/test/voruby/adql/1.0/adql-circle.xml +46 -0
  43. data/test/voruby/adql/1.0/adql-expr.sql +1 -0
  44. data/test/voruby/adql/1.0/adql-expr.xml +34 -0
  45. data/test/voruby/adql/1.0/adql-function.sql +1 -0
  46. data/test/voruby/adql/1.0/adql-function.xml +41 -0
  47. data/test/voruby/adql/1.0/adql-group.sql +1 -0
  48. data/test/voruby/adql/1.0/adql-group.xml +51 -0
  49. data/test/voruby/adql/1.0/adql-having.sql +1 -0
  50. data/test/voruby/adql/1.0/adql-having.xml +25 -0
  51. data/test/voruby/adql/1.0/adql-like.sql +1 -0
  52. data/test/voruby/adql/1.0/adql-like.xml +17 -0
  53. data/test/voruby/adql/1.0/adql-order.sql +1 -0
  54. data/test/voruby/adql/1.0/adql-order.xml +37 -0
  55. data/test/voruby/adql/1.0/adql-simple.sql +1 -0
  56. data/test/voruby/adql/1.0/adql-simple.xml +12 -0
  57. data/test/voruby/adql/1.0/adql-top.sql +1 -0
  58. data/test/voruby/adql/1.0/adql-top.xml +33 -0
  59. data/test/voruby/adql/1.0/test.rb +2220 -0
  60. data/test/voruby/misc/test.rb +32 -0
  61. data/test/voruby/resolver/sesame/test.rb +56 -0
  62. data/test/voruby/sky_query/test.rb +107 -0
  63. data/test/voruby/stc/1.10/coords_test.rb +3704 -0
  64. data/test/voruby/stc/1.10/region_test.rb +993 -0
  65. data/test/voruby/stc/1.10/stc-catalog-entry-location.xml +112 -0
  66. data/test/voruby/stc/1.10/stc-obs-data-location.xml +126 -0
  67. data/test/voruby/stc/1.10/stc-region-circle.xml +5 -0
  68. data/test/voruby/stc/1.10/stc-region-convex.xml +11 -0
  69. data/test/voruby/stc/1.10/stc-region-convexhull.xml +5 -0
  70. data/test/voruby/stc/1.10/stc-region-ellipse.xml +7 -0
  71. data/test/voruby/stc/1.10/stc-region-intersection.xml +25 -0
  72. data/test/voruby/stc/1.10/stc-region-negation.xml +7 -0
  73. data/test/voruby/stc/1.10/stc-region-polygon.xml +13 -0
  74. data/test/voruby/stc/1.10/stc-region-sector.xml +6 -0
  75. data/test/voruby/stc/1.10/stc-region-union.xml +25 -0
  76. data/test/voruby/stc/1.10/stc-resource-profile.xml +60 -0
  77. data/test/voruby/stc/1.10/stc-search-location.xml +54 -0
  78. data/test/voruby/stc/1.10/stc_test.rb +4626 -0
  79. data/test/voruby/stc/1.30/stc-catalog-entry-location.xml +210 -0
  80. data/test/voruby/stc/1.30/stc-obs-data-location-arecibo.xml +353 -0
  81. data/test/voruby/stc/1.30/stc-obs-data-location-fits.xml +250 -0
  82. data/test/voruby/stc/1.30/stc-obs-data-location-xlink.xml +63 -0
  83. data/test/voruby/stc/1.30/stc-obs-data-location.xml +216 -0
  84. data/test/voruby/stc/1.30/stc-resource-profile-unusual-ref-pos.xml +39 -0
  85. data/test/voruby/stc/1.30/stc-resource-profile.xml +129 -0
  86. data/test/voruby/stc/1.30/stc-search-location-arecibo.xml +86 -0
  87. data/test/voruby/stc/1.30/stc-search-location.xml +101 -0
  88. data/test/voruby/stc/1.30/test.rb +6274 -0
  89. data/test/voruby/ucd/test.rb +48 -0
  90. data/test/voruby/voevent/1.1/test.rb +812 -0
  91. data/test/{voevent/voevent_v1_1.xml → voruby/voevent/1.1/voevent.xml} +2 -2
  92. data/test/voruby/voregistry/0.3/test.rb +137 -0
  93. data/test/voruby/votable/1.0/test.rb +714 -0
  94. data/test/voruby/votable/1.0/votable.basic.xml +660 -0
  95. data/test/voruby/votable/1.0/votable.html +86 -0
  96. data/test/voruby/votable/1.0/votable.ns.xml +56 -0
  97. data/test/voruby/votable/1.1/test.rb +785 -0
  98. data/test/voruby/votable/1.1/votable.basic.xml +38 -0
  99. data/test/voruby/votable/1.1/votable.html +86 -0
  100. data/test/voruby/votable/1.1/votable.ns.xml +56 -0
  101. data/test/voruby/votable/test.rb +15 -0
  102. data/test/voruby/wesix/test.rb +268 -0
  103. data/test/voruby/wesix/testr.fits +28 -0
  104. metadata +234 -247
  105. data/REQUIREMENTS +0 -6
  106. data/lib/voruby/active_votable/loader.rb +0 -5
  107. data/lib/voruby/adql/adql.rb +0 -2787
  108. data/lib/voruby/adql/ext.rb +0 -14
  109. data/lib/voruby/adql/loader.rb +0 -6
  110. data/lib/voruby/adql/operations.rb +0 -54
  111. data/lib/voruby/adql/parser.rb +0 -160
  112. data/lib/voruby/adql/transforms.rb +0 -573
  113. data/lib/voruby/ext.rb +0 -17
  114. data/lib/voruby/loader.rb +0 -4
  115. data/lib/voruby/misc/propertyfile.rb +0 -36
  116. data/lib/voruby/plastic/applications.rb +0 -174
  117. data/lib/voruby/plastic/constants.rb +0 -30
  118. data/lib/voruby/plastic/loader.rb +0 -10
  119. data/lib/voruby/plastic/plastic.rb +0 -1
  120. data/lib/voruby/resources/conesearch/conesearch.rb +0 -9
  121. data/lib/voruby/resources/conesearch/conesearch_v0_2.rb +0 -55
  122. data/lib/voruby/resources/conesearch/conesearch_v0_3.rb +0 -50
  123. data/lib/voruby/resources/conesearch/conesearch_v1_0.rb +0 -72
  124. data/lib/voruby/resources/conesearch/loader.rb +0 -4
  125. data/lib/voruby/resources/loader.rb +0 -50
  126. data/lib/voruby/resources/nodes.rb +0 -190
  127. data/lib/voruby/resources/openskynode/loader.rb +0 -4
  128. data/lib/voruby/resources/openskynode/openskynode.rb +0 -9
  129. data/lib/voruby/resources/openskynode/openskynode_v0_1.rb +0 -54
  130. data/lib/voruby/resources/sia/loader.rb +0 -5
  131. data/lib/voruby/resources/sia/sia.rb +0 -9
  132. data/lib/voruby/resources/sia/sia_v0_6.rb +0 -90
  133. data/lib/voruby/resources/sia/sia_v0_7.rb +0 -89
  134. data/lib/voruby/resources/sia/sia_v1_0.rb +0 -122
  135. data/lib/voruby/resources/stsci.rb +0 -59
  136. data/lib/voruby/resources/vodataservice/coverage_v0_2.rb +0 -195
  137. data/lib/voruby/resources/vodataservice/coverage_v0_3.rb +0 -158
  138. data/lib/voruby/resources/vodataservice/loader.rb +0 -5
  139. data/lib/voruby/resources/vodataservice/vodataservice.rb +0 -9
  140. data/lib/voruby/resources/vodataservice/vodataservice_v0_4.rb +0 -189
  141. data/lib/voruby/resources/vodataservice/vodataservice_v0_5.rb +0 -163
  142. data/lib/voruby/resources/vodataservice/vodataservice_v1_0.rb +0 -221
  143. data/lib/voruby/resources/voregistry/loader.rb +0 -4
  144. data/lib/voruby/resources/voregistry/voregistry.rb +0 -9
  145. data/lib/voruby/resources/voregistry/voregistry_v0_2.rb +0 -40
  146. data/lib/voruby/resources/voregistry/voregistry_v0_3.rb +0 -30
  147. data/lib/voruby/resources/voregistry/voregistry_v1_0.rb +0 -86
  148. data/lib/voruby/resources/voresource/loader.rb +0 -17
  149. data/lib/voruby/resources/voresource/voresource.rb +0 -9
  150. data/lib/voruby/resources/voresource/voresource_v0_10.rb +0 -327
  151. data/lib/voruby/resources/voresource/voresource_v0_9.rb +0 -405
  152. data/lib/voruby/resources/voresource/voresource_v1_0.rb +0 -230
  153. data/lib/voruby/services/ext.rb +0 -11
  154. data/lib/voruby/services/gestalt/footprint.rb +0 -95
  155. data/lib/voruby/services/gestalt/wcs_fixer.rb +0 -105
  156. data/lib/voruby/services/gestalt/wesix.rb +0 -155
  157. data/lib/voruby/services/loader.rb +0 -7
  158. data/lib/voruby/services/registry/registry.rb +0 -53
  159. data/lib/voruby/services/resolver/resolver.rb +0 -35
  160. data/lib/voruby/services/schema/schema.rb +0 -644
  161. data/lib/voruby/sesame/loader.rb +0 -6
  162. data/lib/voruby/sesame/sesame_v1_0.rb +0 -64
  163. data/lib/voruby/simple/loader.rb +0 -6
  164. data/lib/voruby/simple/parameters.rb +0 -196
  165. data/lib/voruby/simple/sap.rb +0 -446
  166. data/lib/voruby/spacetime/loader.rb +0 -3
  167. data/lib/voruby/spacetime/spacetime.rb +0 -607
  168. data/lib/voruby/stc/coords_v1_20.rb +0 -900
  169. data/lib/voruby/stc/loader.rb +0 -55
  170. data/lib/voruby/stc/region_v1_20.rb +0 -274
  171. data/lib/voruby/stc/stc_v1_20.rb +0 -1196
  172. data/lib/voruby/util.rb +0 -27
  173. data/lib/voruby/voevent/loader.rb +0 -7
  174. data/lib/voruby/voevent/voevent_v1_0.rb +0 -213
  175. data/lib/voruby/voevent/voevent_v1_1.rb +0 -196
  176. data/lib/voruby/votables/chandra.rb +0 -373
  177. data/lib/voruby/votables/data.rb +0 -179
  178. data/lib/voruby/votables/galex.rb +0 -377
  179. data/lib/voruby/votables/int.rb +0 -354
  180. data/lib/voruby/votables/libxml_parser.rb +0 -411
  181. data/lib/voruby/votables/libxml_votable.rb +0 -67
  182. data/lib/voruby/votables/loader.rb +0 -10
  183. data/lib/voruby/votables/meta.rb +0 -763
  184. data/lib/voruby/votables/misc.rb +0 -51
  185. data/lib/voruby/votables/nsa.rb +0 -410
  186. data/lib/voruby/votables/rexml_parser.rb +0 -408
  187. data/lib/voruby/votables/rexml_votable.rb +0 -67
  188. data/lib/voruby/votables/sdss.rb +0 -356
  189. data/lib/voruby/votables/transforms.rb +0 -388
  190. data/lib/voruby/votables/tree.rb +0 -45
  191. data/lib/voruby/votables/types.rb +0 -391
  192. data/lib/voruby/votables/votable.rb +0 -687
  193. data/test/active_votable/database.yml +0 -6
  194. data/test/active_votable/test.vot +0 -168492
  195. data/test/active_votable/unittest.rb +0 -41
  196. data/test/adql/test1.adql +0 -49
  197. data/test/adql/test2.adql +0 -51
  198. data/test/adql/test3.adql +0 -81
  199. data/test/adql/test4.adql +0 -53
  200. data/test/adql/test5.adql +0 -55
  201. data/test/adql/test6.adql +0 -18
  202. data/test/adql/test7.adql +0 -48
  203. data/test/adql/unittest.rb +0 -1672
  204. data/test/plastic/test.rb +0 -44
  205. data/test/plastic/test.vot +0 -5385
  206. data/test/plastic/unittest.rb +0 -66
  207. data/test/resources/conesearch/conesearch_v0_3.xml +0 -31
  208. data/test/resources/conesearch/conesearch_v1_0.xml +0 -86
  209. data/test/resources/conesearch/unittest_v0_3.rb +0 -22
  210. data/test/resources/conesearch/unittest_v1_0.rb +0 -24
  211. data/test/resources/openskynode/open_sky_node_v0_1.xml +0 -32
  212. data/test/resources/openskynode/unittest_v0_1.rb +0 -31
  213. data/test/resources/sia/simple_image_access_v0_7.xml +0 -36
  214. data/test/resources/sia/simple_image_access_v1_0.xml +0 -122
  215. data/test/resources/sia/unittest_v0_7.rb +0 -24
  216. data/test/resources/sia/unittest_v1_0.rb +0 -29
  217. data/test/resources/stsci.xml +0 -336
  218. data/test/resources/unittest_stsci.rb +0 -25
  219. data/test/resources/vodataservice/catalog_service_resource_v1_0.xml +0 -128
  220. data/test/resources/vodataservice/data_collection_resource_v0_5.xml +0 -54
  221. data/test/resources/vodataservice/data_collection_resource_v1_0.xml +0 -117
  222. data/test/resources/vodataservice/data_service_resource_v1_0.xml +0 -115
  223. data/test/resources/vodataservice/sky_service_resource_v0_10.xml +0 -45
  224. data/test/resources/vodataservice/table_service_resource_v1_0.xml +0 -122
  225. data/test/resources/vodataservice/tabular_sky_service_resource_v0_10.xml +0 -60
  226. data/test/resources/vodataservice/unittest_v0_5.rb +0 -126
  227. data/test/resources/vodataservice/unittest_v1_0.rb +0 -151
  228. data/test/resources/voregistry/authority_resource_v0_3.xml +0 -20
  229. data/test/resources/voregistry/authority_resource_v1_0.xml +0 -82
  230. data/test/resources/voregistry/registry_service_v0_3.xml +0 -20
  231. data/test/resources/voregistry/registry_service_v1_0.xml +0 -107
  232. data/test/resources/voregistry/unittest_v0_3.rb +0 -31
  233. data/test/resources/voregistry/unittest_v1_0.rb +0 -34
  234. data/test/resources/voresource/organisation_resource_v1_0.xml +0 -90
  235. data/test/resources/voresource/resource_organisation_v0_10.xml +0 -22
  236. data/test/resources/voresource/resource_service_v0_10.xml +0 -19
  237. data/test/resources/voresource/resource_v0_10.xml +0 -19
  238. data/test/resources/voresource/resource_v1_0.xml +0 -79
  239. data/test/resources/voresource/service_resource_v1_0.xml +0 -91
  240. data/test/resources/voresource/unittest_v0_10.rb +0 -61
  241. data/test/resources/voresource/unittest_v0_9.rb +0 -4
  242. data/test/resources/voresource/unittest_v1_0.rb +0 -190
  243. data/test/services/gestalt/unittest.rb +0 -74
  244. data/test/services/registry/unittest.rb +0 -34
  245. data/test/services/resolver/unittest.rb +0 -38
  246. data/test/simple/unittest.rb +0 -46
  247. data/test/spacetime/unittest.rb +0 -39
  248. data/test/stc/catalog_entry_location_v1_20.xml +0 -112
  249. data/test/stc/obs_data_location_v1_20.xml +0 -108
  250. data/test/stc/search_location_v1_20.xml +0 -54
  251. data/test/stc/stc_resource_profile_v1_20.xml +0 -60
  252. data/test/stc/unittest_v1_20.rb +0 -620
  253. data/test/voevent/unittest_v1_0.rb +0 -79
  254. data/test/voevent/unittest_v1_1.rb +0 -70
  255. data/test/voevent/voevent_v1_0.xml +0 -96
  256. data/test/votables/test.vot +0 -366
  257. data/test/votables/unittest.rb +0 -54
@@ -0,0 +1,305 @@
1
+ require 'open-uri'
2
+ require 'mathn'
3
+ require 'date'
4
+ require 'tempfile'
5
+
6
+ begin
7
+ require 'rubygems'
8
+ rescue LoadError; end
9
+ require 'xml/libxml'
10
+ require 'builder'
11
+
12
+ require 'voruby'
13
+ require 'voruby/misc/libxml_ext'
14
+
15
+ module VORuby
16
+ # A set of classes designed to read and manipulate the IVOA[http://www.ivoa.net/]
17
+ # standard for representing astronomical tabular data called
18
+ # VOTable[http://www.ivoa.net/Documents/latest/VOT.html].
19
+ #
20
+ # As a quick start, you might do something like this:
21
+ #
22
+ # require 'voruby/votable/votable'
23
+ # include VORuby
24
+ #
25
+ # votable = VOTable.from_xml(File.new('votable.basic.xml')) # this happens to be a 1.1 votable
26
+ # table = votable.resources.first.tables.first # get the first resource and table
27
+ #
28
+ # # See the name of each column
29
+ # puts table.fields.collect{ |field| field.name }.join('|')
30
+ #
31
+ # # Iterate through each row.
32
+ # table.data.format.trs.each do |row|
33
+ # row_as_string = row.tds.collect{ |td| td.value }.join('|')
34
+ # puts row_as_string
35
+ # end
36
+ #
37
+ # Methods that are pluralized (i.e. table.fields and format.trs above) normally return an
38
+ # array-like object called a HomogeneousNodeList. You can do most of the common array
39
+ # operations on it, including array assignment ([]=) and retrieval ([]), appending (<<)
40
+ # and iteration (each). So:
41
+ #
42
+ # table.fields << Field.new(...) # append a new field
43
+ # table.fields.prepend(Field.new(...)) # prepend a new field
44
+ # table.fields.each { |field| ... } # iterate through each field
45
+ # table.fields[2] = Field.new(...) # assign a new field to the third position
46
+ # table.fields[2] # retrieve the third field
47
+ # table.fields.delete_at(2) # delete the third field
48
+ # table.fields.clear # delete all fields
49
+ # table.fields.first # retrieve the first field
50
+ # table.fields.last # retrieve the last field
51
+ # table.fields.size # the number of fields present
52
+ #
53
+ # It also mixes in Enumerable so all the other standard methods are available.
54
+ #
55
+ # To build a simple VOTable from scratch all in one go one might do this:
56
+ #
57
+ # votable = VOTable.new(
58
+ # :version => '1.1',
59
+ # :coordinate_systems => [
60
+ # Coosys.new(:id => 'J2000', :equinox => 'J2000.', :epoch => 'J2000.', :system => 'eq_FK5')
61
+ # ],
62
+ # :resources => [
63
+ # Resource.new(
64
+ # :name => 'myFavouriteGalaxies',
65
+ # :tables => [
66
+ # Table.new(
67
+ # :name => 'results',
68
+ # :description => Description.new(:text => 'Velocities and Distance estimations'),
69
+ # :params => [
70
+ # Param.new(
71
+ # :name => 'Telescope',
72
+ # :datatype => 'float',
73
+ # :ucd => 'phys.size;instr.tel',
74
+ # :unit => 'm',
75
+ # :value => '3.6'
76
+ # )
77
+ # ],
78
+ # :fields => [
79
+ # Field.new(:name => 'RA', :id => 'col1', :ucd => 'pos.eq.ra;meta.main',
80
+ # :ref => 'J2000', :datatype => 'float', :width => 6, :precision => '2', :unit => 'deg'),
81
+ # Field.new(:name => 'Dec', :id => 'col2', :ucd => 'pos.eq.dec;meta.main',
82
+ # :ref => 'J2000', :datatype => 'float', :width => 6, :precision => '2', :unit => 'deg'),
83
+ # Field.new(:name => 'Name', :id => 'col3', :ucd => 'meta.id;meta.main',
84
+ # :datatype => 'char', :arraysize => '8*'),
85
+ # Field.new(:name => 'RVel', :id => 'col4', :ucd => 'src.veloc.hc', :datatype => 'int',
86
+ # :width => 5, :unit => 'km/s'),
87
+ # Field.new(:name => 'e_RVel', :id => 'col5', :ucd => 'stat.error;src.veloc.hc',
88
+ # :datatype => 'int', :width => 3, :unit => 'km/s'),
89
+ # Field.new(:name => 'R', :id => 'col6', :ucd => 'phys.distance', :datatype => 'float',
90
+ # :width => 4, :precision => '1', :unit => 'Mpc',
91
+ # :description => Description.new(:text => 'Distance of Galaxy, assuming H=75km/s/Mpc'))
92
+ # ],
93
+ # :data => Data.new(
94
+ # :format => TableData.new(
95
+ # :trs => [
96
+ # Tr.new(:tds => [
97
+ # Td.new(:text => '010.68'), Td.new(:text => '+41.27'), Td.new(:text => 'N 224'),
98
+ # Td.new(:text => '-297'), Td.new(:text => '5'), Td.new(:text => '0.7')
99
+ # ]),
100
+ # Tr.new(:tds => [
101
+ # Td.new(:text => '287.43'), Td.new(:text => '-63.85'), Td.new(:text => 'N 6744'),
102
+ # Td.new(:text => '839'), Td.new(:text => '6'), Td.new(:text => '10.4')
103
+ # ]),
104
+ # Tr.new(:tds => [
105
+ # Td.new(:text => '023.48'), Td.new(:text => '+30.66'), Td.new(:text => 'N 598'),
106
+ # Td.new(:text => '-182'), Td.new(:text => '3'), Td.new(:text => '0.7')
107
+ # ])
108
+ # ]
109
+ # )
110
+ # )
111
+ # )
112
+ # ]
113
+ # )
114
+ # ]
115
+ # )
116
+ #
117
+ # Of course, it's more likely you would have read the votable in directly from a file.
118
+ # To convert this votable to a (very) simple CSV-like file you could then:
119
+ #
120
+ # puts votable.resources.first.tables.first.fields.collect{ |field| field.name }.join(',')
121
+ # votable.resources.first.tables.first.data.format.trs.each do |tr|
122
+ # puts tr.tds.collect{ |td| td.text }.join(',')
123
+ # end
124
+ #
125
+ # Which would print out something like:
126
+ #
127
+ # RA,Dec,RVel,e_RVel,R
128
+ # 010.68,+41.27,N 224,-297,5,0.7
129
+ # 287.43,-63.85,N 6744,839,6,10.4
130
+ # 023.48,+30.66,N 598,-182,3,0.7
131
+ #
132
+ # You can also convert the votable to an HTML fragment by doing:
133
+ #
134
+ # votable.to_html
135
+ module VOTable
136
+ # Automatically determines the votable version in question and
137
+ # returns the appropriate domain object.
138
+ # _defn_:: a String, XML::Document, XML::Node or IO object representing the XML.
139
+ #
140
+ # votable = VOTable.from_xml(File.new('votable.basic.xml')) # assuming this is 1.1 document
141
+ # puts votable.class #=> VOTable::V1_1::VOTable
142
+ def self.from_xml(defn)
143
+ generic_vot = Base.new(defn).node
144
+
145
+ namespaces = (generic_vot.namespace || []).collect{ |ns| ns.href }
146
+ namespaces << generic_vot['noNamespaceSchemaLocation']
147
+
148
+ if namespaces.include?('http://www.ivoa.net/xml/VOTable/VOTable/v1.1') or generic_vot['version'] =~ /1\.1$/
149
+ return VOTable::V1_1::VOTable.new(generic_vot)
150
+ elsif namespaces.include?('http://www.ivoa.net/xml/VOTable/v1.0') or generic_vot['version'] =~ /1\.0$/
151
+ return VOTable::V1_0::VOTable.new(generic_vot)
152
+ else
153
+ return VOTable::V1_1::VOTable.new(generic_vot) # go with the most recent if namespace indeterminate
154
+ end
155
+ end
156
+
157
+ # Some helper methods for converting string values that have an associated
158
+ # data type (like TDs do through their associated FIELD).
159
+ module Castable
160
+ # Convert a string value into its corresponding basic object representation,
161
+ # if appropriate. This does *not* work on array values, only on scalars.
162
+ # Native ruby types map to votable datatypes in the following way:
163
+ #
164
+ # * 'boolean' => boolean (i.e TrueClass or FalseClass)
165
+ # * 'bit' => Integer (1 or 0)
166
+ # * 'unsignedByte' => Integer representation of the byte
167
+ # * 'short, 'int', 'long' => Integer
168
+ # * 'char', 'unicodeChar' => String
169
+ # * 'float', 'double' => Float or Bignum
170
+ # * 'floatComplex', 'doubleComplex' => Complex
171
+ def cast(txt, to='char')
172
+ case to
173
+ when 'boolean'
174
+ txt == '1' || txt.downcase == 'true' || txt.downcase == 't'
175
+ when 'bit' then txt.to_i
176
+ when 'unsignedByte' then txt[0]
177
+ when 'short' then txt.to_i
178
+ when 'int' then txt.to_i
179
+ when 'long' then txt.to_i
180
+ when 'double' then txt.to_f
181
+ when 'float' then txt.to_f
182
+ else
183
+ txt
184
+ end
185
+ end
186
+
187
+ # Serialize a ruby object to the format that is correct
188
+ # for a votable.
189
+ def convert_to_s(val, from='char')
190
+ case from
191
+ when 'boolean'
192
+ (val.is_a?(TrueClass) or val.to_s.downcase =~ /^t/ or val.to_s == '1') ?
193
+ 'true' : 'false'
194
+ when 'bit' then val.to_i.to_s
195
+ when 'short' then val.to_i.to_s
196
+ when 'int' then val.to_i.to_s
197
+ when 'long' then val.to_i.to_s
198
+ when 'float' then val.to_f.to_s
199
+ when 'double' then val.to_f.to_s
200
+ when 'floatComplex' then "#{val.real} #{val.image}"
201
+ when 'doubleComplex' then "#{val.real} #{val.image}"
202
+ else
203
+ val.to_s
204
+ end
205
+ end
206
+
207
+ # Much like #cast but understands arrays.
208
+ def as_obj(txt, datatype, arraysize=nil)
209
+ raise "Unable to determine datatype" if !datatype
210
+
211
+ txt_list = arraysize ? txt.split(/\s+/) : [txt]
212
+ values_list = []
213
+
214
+ # character string, do nothing
215
+ return txt if datatype == 'char' or datatype == 'unicodeChar'
216
+
217
+ # complex values are a bit different
218
+ if datatype == 'floatComplex' || datatype == 'doubleComplex'
219
+ txt_list = txt.split(/\s+/)
220
+ complex_numbers = []
221
+ i = 0
222
+ (0...txt_list.size/2).each do |n|
223
+ complex_numbers << Complex.new(txt_list[i].to_f, txt_list[i+1].to_f)
224
+ i += 2
225
+ end
226
+ return arraysize ? complex_numbers : complex_numbers.first
227
+ end
228
+
229
+ txt_list.each do |component|
230
+ values_list << cast(component, datatype)
231
+ end
232
+
233
+ arraysize ? values_list : values_list.first
234
+ end
235
+
236
+ # Much like #convert_to_s but understands arrays.
237
+ def as_string(obj, datatype, arraysize=nil)
238
+ raise "Unable to determine datatype" if !datatype
239
+ raise "Supposed to contain an array of size '#{arraysize}'" if arraysize and !obj.is_a?(Array)
240
+ raise "Supposed to contain a single value" if !arraysize and obj.is_a?(Array)
241
+
242
+ obj = [obj] if !obj.is_a?(Array)
243
+
244
+ values = []
245
+ obj.each do |val|
246
+ values << convert_to_s(val, datatype)
247
+ end
248
+
249
+ values.join(' ')
250
+ end
251
+ end
252
+
253
+ # The base class that all VOTable domain objects derive from.
254
+ # You'll never instantiate this directly.
255
+ class Base < XML::Object::Base
256
+ # Get the name of the element when serialized
257
+ # to XML that the object in question will take on.
258
+ def self.element_name
259
+ const_get('ELEMENT_NAME')
260
+ end
261
+
262
+ # Determine the xpath corresponding to the specified class.
263
+ # obj.xpath_for(Field) # => "*[local-name()='FIELD']"
264
+ def xpath_for(klass)
265
+ "*[local-name()='#{klass.element_name}']"
266
+ end
267
+
268
+ # Retrieve the domain object that corresponds to
269
+ # the specified class.
270
+ def get_element(klass)
271
+ subnode = self.node.find_first("*[local-name()='#{klass.element_name}']")
272
+ subnode ? klass.new(subnode) : nil
273
+ end
274
+
275
+ # Equality among domain objects.
276
+ # Two objects are considered equal if they're
277
+ # of the same class and their accessor methods
278
+ # themselves return objects which are equal.
279
+ def ==(obj)
280
+ return false if self.class != obj.class
281
+
282
+ self.methods_to_test_for_equality.each do |method|
283
+ return false if self.send(method) != obj.send(method)
284
+ end
285
+
286
+ true
287
+ end
288
+
289
+ private
290
+
291
+ def initialize_members(args)
292
+ if self.class.respond_to?(:serialization_order)
293
+ self.class.serialization_order.each do |name|
294
+ send("#{name}=", args[name]) if args.has_key?(name)
295
+ end
296
+ else
297
+ args.each do |name, value|
298
+ send("#{name}=", value)
299
+ end
300
+ end
301
+ end
302
+ end
303
+
304
+ end
305
+ end
@@ -0,0 +1,491 @@
1
+ require 'base64'
2
+ require 'open-uri'
3
+
4
+ begin
5
+ require 'rubygems'
6
+ rescue LoadError; end
7
+
8
+ gem 'soap4r'
9
+ require 'soap/wsdlDriver'
10
+
11
+ require 'voruby/votable/1.1/votable'
12
+
13
+ module VORuby
14
+ module Wesix
15
+ class SextractorParams
16
+ WESIX_NS = 'http://wesixtest.phyast.pitt.edu'
17
+
18
+ def initialize(params={})
19
+ params.each{ |key, value| self.send("#{key}=", value) }
20
+ end
21
+ end
22
+
23
+ # Object containing the parameters to be used by WESIX (e.g. SExtractor) to create the source catalog.
24
+ # You can preset values by passing a hash to the constructor:
25
+ #
26
+ # params = Params.new(:analysis_thresh => 2.0)
27
+ # params.detect_thresh = 2.0
28
+ # puts params.analysis_thresh # => 2.0
29
+ #
30
+ # Available methods are:
31
+ # #analysis_thresh, #backphoto_type, #back_filtersize, #back_size, #catalog_name, #catalog_type,
32
+ # #checkimage_name, #checkimage_type, #clean, #clean_param, #deblend_mincont, #deblend_nthresh,
33
+ # #detect_minarea, #detect_thresh, #detect_type, #filter, #filter_name, #flag_image, #gain,
34
+ # #mag_gamma, #mag_zeropoint, #mask_type, #memory_bufsize, #memory_objstack, #memory_pixstack,
35
+ # #parameters_name, #phot_apertures, #phot_autoparams1, #phot_autoparams2, #pixel_scale, #satur_level,
36
+ # #seeing_fwhm, #starnnw_name, #verbose_type, #query1, #query2, #string
37
+ class Params < SextractorParams
38
+ # Returns the schema required to convert this object into a
39
+ # fully-fledged SOAP object. Used by Service.
40
+ def self.soap_registration
41
+ {
42
+ :class => self,
43
+ :schema_type => XSD::QName.new(WESIX_NS, "SexParams"),
44
+ :schema_element => [
45
+ ["analysis_thresh", ["SOAP::SOAPDouble", XSD::QName.new(nil, "ANALYSIS_THRESH")]],
46
+ ["backphoto_type", ["SOAP::SOAPString", XSD::QName.new(nil, "BACKPHOTO_TYPE")]],
47
+ ["back_filtersize", ["SOAP::SOAPInt", XSD::QName.new(nil, "BACK_FILTERSIZE")]],
48
+ ["back_size", ["SOAP::SOAPInt", XSD::QName.new(nil, "BACK_SIZE")]],
49
+ ["catalog_name", ["SOAP::SOAPString", XSD::QName.new(nil, "CATALOG_NAME")]],
50
+ ["catalog_type", ["SOAP::SOAPString", XSD::QName.new(nil, "CATALOG_TYPE")]],
51
+ ["checkimage_name", ["SOAP::SOAPString", XSD::QName.new(nil, "CHECKIMAGE_NAME")]],
52
+ ["checkimage_type", ["SOAP::SOAPString", XSD::QName.new(nil, "CHECKIMAGE_TYPE")]],
53
+ ["clean", ["SOAP::SOAPString", XSD::QName.new(nil, "CLEAN")]],
54
+ ["clean_param", ["SOAP::SOAPDouble", XSD::QName.new(nil, "CLEAN_PARAM")]],
55
+ ["deblend_mincont", ["SOAP::SOAPDouble", XSD::QName.new(nil, "DEBLEND_MINCONT")]],
56
+ ["deblend_nthresh", ["SOAP::SOAPInt", XSD::QName.new(nil, "DEBLEND_NTHRESH")]],
57
+ ["detect_minarea", ["SOAP::SOAPInt", XSD::QName.new(nil, "DETECT_MINAREA")]],
58
+ ["detect_thresh", ["SOAP::SOAPDouble", XSD::QName.new(nil, "DETECT_THRESH")]],
59
+ ["detect_type", ["SOAP::SOAPString", XSD::QName.new(nil, "DETECT_TYPE")]],
60
+ ["filter", ["SOAP::SOAPString", XSD::QName.new(nil, "FILTER")]],
61
+ ["filter_name", ["SOAP::SOAPString", XSD::QName.new(nil, "FILTER_NAME")]],
62
+ ["flag_image", ["SOAP::SOAPString", XSD::QName.new(nil, "FLAG_IMAGE")]],
63
+ ["gain", ["SOAP::SOAPDouble", XSD::QName.new(nil, "GAIN")]],
64
+ ["mag_gamma", ["SOAP::SOAPDouble", XSD::QName.new(nil, "MAG_GAMMA")]],
65
+ ["mag_zeropoint", ["SOAP::SOAPDouble", XSD::QName.new(nil, "MAG_ZEROPOINT")]],
66
+ ["mask_type", ["SOAP::SOAPString", XSD::QName.new(nil, "MASK_TYPE")]],
67
+ ["memory_bufsize", ["SOAP::SOAPInt", XSD::QName.new(nil, "MEMORY_BUFSIZE")]],
68
+ ["memory_objstack", ["SOAP::SOAPInt", XSD::QName.new(nil, "MEMORY_OBJSTACK")]],
69
+ ["memory_pixstack", ["SOAP::SOAPInt", XSD::QName.new(nil, "MEMORY_PIXSTACK")]],
70
+ ["parameters_name", ["SOAP::SOAPString", XSD::QName.new(nil, "PARAMETERS_NAME")]],
71
+ ["phot_apertures", ["SOAP::SOAPInt", XSD::QName.new(nil, "PHOT_APERTURES")]],
72
+ ["phot_autoparams1", ["SOAP::SOAPDouble", XSD::QName.new(nil, "PHOT_AUTOPARAMS1")]],
73
+ ["phot_autoparams2", ["SOAP::SOAPDouble", XSD::QName.new(nil, "PHOT_AUTOPARAMS2")]],
74
+ ["pixel_scale", ["SOAP::SOAPDouble", XSD::QName.new(nil, "PIXEL_SCALE")]],
75
+ ["satur_level", ["SOAP::SOAPDouble", XSD::QName.new(nil, "SATUR_LEVEL")]],
76
+ ["seeing_fwhm", ["SOAP::SOAPDouble", XSD::QName.new(nil, "SEEING_FWHM")]],
77
+ ["starnnw_name", ["SOAP::SOAPString", XSD::QName.new(nil, "STARNNW_NAME")]],
78
+ ["verbose_type", ["SOAP::SOAPString", XSD::QName.new(nil, "VERBOSE_TYPE")]],
79
+ ["query1", ["SOAP::SOAPString", XSD::QName.new(nil, "query1")]],
80
+ ["query2", ["SOAP::SOAPString", XSD::QName.new(nil, "query2")]],
81
+ ["string", ["SOAP::SOAPString", XSD::QName.new(nil, "string")]]
82
+ ]
83
+ }
84
+ end
85
+
86
+ attr_accessor *soap_registration[:schema_element].collect{ |defn| defn.first }
87
+ end
88
+
89
+ # Object containing the measured parameters (all booleans) to be included in the output catalog
90
+ # generated by WESIX. You can preset values by passing a hash to the constructor:
91
+ #
92
+ # params = OutputParams.new(:flux_best => true)
93
+ # params.fluxerr_best = true
94
+ # puts params.flux_best # => true
95
+ #
96
+ # Available methods are:
97
+ # #alpha_b1950, #alpha_j2000, #alpha_sky, #background, #class_star, #cxx_image, #cxx_world,
98
+ # #cxy_image, #cxy_world, #cyy_image, #cyy_world, #delta_b1950, #delta_j2000, #delta_sky,
99
+ # #ellipticity, #elongation, #erra_image, #erra_world, #errb_image, #errb_world, #errcxx_image,
100
+ # #errcxx_world, #errcxy_image, #errcxy_world, #errcyy_image, #errcyy_world, #errtheta_b1950,
101
+ # #errtheta_image, #errtheta_j2000, #errtheta_sky, #errtheta_world, #errx2_image, #errx2_world,
102
+ # #errxy_image, #errxy_world, #erry2_image, #erry2_world, #flags, #fluxerr_aper, #fluxerr_auto,
103
+ # #fluxerr_best, #fluxerr_iso, #fluxerr_isocor, #flux_aper, #flux_auto, #flux_best, #flux_iso,
104
+ # #flux_isocor, #flux_max, #fwhm_image, #fwhm_world, #imaflags_iso, #iso0, #iso1, #iso2, #iso3,
105
+ # #iso4, #iso5, #iso6, #iso7, #isoarea_image, #isoarea_world, #kron_radius, #magerr_aper, #magerr_auto,
106
+ # #magerr_best, #magerr_iso, #magerr_isocor, #mag_aper, #mag_auto, #mag_best, #mag_iso, #mag_isocor, #mu_max,
107
+ # #mu_threshold, #nimaflags_iso, #number, #theta_b1950, #theta_image, #theta_j2000, #theta_sky, #theta_world,
108
+ # #threshold, #vignet, #xmax_image, #xmin_image, #xy_image, #xy_world, #ymax_image, #ymin_image, #a_image, #a_world,
109
+ # #b_image, #b_world, #params, #x2_image, #x2_world, #x_image, #x_world, #y2_image, #y2_world, #y_image, #y_world
110
+ class OutputParams < SextractorParams
111
+ # Returns the schema required to convert this object into a
112
+ # fully-fledged SOAP object. Used by Service.
113
+ def self.soap_registration
114
+ {
115
+ :class => self,
116
+ :schema_type => XSD::QName.new(WESIX_NS, "SexOutputParams"),
117
+ :schema_element => [
118
+ ["alpha_b1950", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ALPHA_B1950")]],
119
+ ["alpha_j2000", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ALPHA_J2000")]],
120
+ ["alpha_sky", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ALPHA_SKY")]],
121
+ ["background", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "BACKGROUND")]],
122
+ ["class_star", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "CLASS_STAR")]],
123
+ ["cxx_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "CXX_IMAGE")]],
124
+ ["cxx_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "CXX_WORLD")]],
125
+ ["cxy_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "CXY_IMAGE")]],
126
+ ["cxy_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "CXY_WORLD")]],
127
+ ["cyy_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "CYY_IMAGE")]],
128
+ ["cyy_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "CYY_WORLD")]],
129
+ ["delta_b1950", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "DELTA_B1950")]],
130
+ ["delta_j2000", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "DELTA_J2000")]],
131
+ ["delta_sky", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "DELTA_SKY")]],
132
+ ["ellipticity", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ELLIPTICITY")]],
133
+ ["elongation", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ELONGATION")]],
134
+ ["erra_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRA_IMAGE")]],
135
+ ["erra_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRA_WORLD")]],
136
+ ["errb_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRB_IMAGE")]],
137
+ ["errb_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRB_WORLD")]],
138
+ ["errcxx_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRCXX_IMAGE")]],
139
+ ["errcxx_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRCXX_WORLD")]],
140
+ ["errcxy_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRCXY_IMAGE")]],
141
+ ["errcxy_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRCXY_WORLD")]],
142
+ ["errcyy_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRCYY_IMAGE")]],
143
+ ["errcyy_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRCYY_WORLD")]],
144
+ ["errtheta_b1950", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRTHETA_B1950")]],
145
+ ["errtheta_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRTHETA_IMAGE")]],
146
+ ["errtheta_j2000", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRTHETA_J2000")]],
147
+ ["errtheta_sky", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRTHETA_SKY")]],
148
+ ["errtheta_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRTHETA_WORLD")]],
149
+ ["errx2_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRX2_IMAGE")]],
150
+ ["errx2_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRX2_WORLD")]],
151
+ ["errxy_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRXY_IMAGE")]],
152
+ ["errxy_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRXY_WORLD")]],
153
+ ["erry2_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRY2_IMAGE")]],
154
+ ["erry2_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ERRY2_WORLD")]],
155
+ ["flags", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLAGS")]],
156
+ ["fluxerr_aper", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUXERR_APER")]],
157
+ ["fluxerr_auto", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUXERR_AUTO")]],
158
+ ["fluxerr_best", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUXERR_BEST")]],
159
+ ["fluxerr_iso", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUXERR_ISO")]],
160
+ ["fluxerr_isocor", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUXERR_ISOCOR")]],
161
+ ["flux_aper", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUX_APER")]],
162
+ ["flux_auto", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUX_AUTO")]],
163
+ ["flux_best", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUX_BEST")]],
164
+ ["flux_iso", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUX_ISO")]],
165
+ ["flux_isocor", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUX_ISOCOR")]],
166
+ ["flux_max", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FLUX_MAX")]],
167
+ ["fwhm_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FWHM_IMAGE")]],
168
+ ["fwhm_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "FWHM_WORLD")]],
169
+ ["imaflags_iso", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "IMAFLAGS_ISO")]],
170
+ ["iso0", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISO0")]],
171
+ ["iso1", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISO1")]],
172
+ ["iso2", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISO2")]],
173
+ ["iso3", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISO3")]],
174
+ ["iso4", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISO4")]],
175
+ ["iso5", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISO5")]],
176
+ ["iso6", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISO6")]],
177
+ ["iso7", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISO7")]],
178
+ ["isoarea_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISOAREA_IMAGE")]],
179
+ ["isoarea_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "ISOAREA_WORLD")]],
180
+ ["kron_radius", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "KRON_RADIUS")]],
181
+ ["magerr_aper", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAGERR_APER")]],
182
+ ["magerr_auto", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAGERR_AUTO")]],
183
+ ["magerr_best", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAGERR_BEST")]],
184
+ ["magerr_iso", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAGERR_ISO")]],
185
+ ["magerr_isocor", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAGERR_ISOCOR")]],
186
+ ["mag_aper", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAG_APER")]],
187
+ ["mag_auto", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAG_AUTO")]],
188
+ ["mag_best", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAG_BEST")]],
189
+ ["mag_iso", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAG_ISO")]],
190
+ ["mag_isocor", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MAG_ISOCOR")]],
191
+ ["mu_max", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MU_MAX")]],
192
+ ["mu_threshold", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "MU_THRESHOLD")]],
193
+ ["nimaflags_iso", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "NIMAFLAGS_ISO")]],
194
+ ["number", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "NUMBER")]],
195
+ ["theta_b1950", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "THETA_B1950")]],
196
+ ["theta_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "THETA_IMAGE")]],
197
+ ["theta_j2000", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "THETA_J2000")]],
198
+ ["theta_sky", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "THETA_SKY")]],
199
+ ["theta_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "THETA_WORLD")]],
200
+ ["threshold", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "THRESHOLD")]],
201
+ ["vignet", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "VIGNET")]],
202
+ ["xmax_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "XMAX_IMAGE")]],
203
+ ["xmin_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "XMIN_IMAGE")]],
204
+ ["xy_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "XY_IMAGE")]],
205
+ ["xy_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "XY_WORLD")]],
206
+ ["ymax_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "YMAX_IMAGE")]],
207
+ ["ymin_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "YMIN_IMAGE")]],
208
+ ["a_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "a_IMAGE")]],
209
+ ["a_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "a_WORLD")]],
210
+ ["b_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "b_IMAGE")]],
211
+ ["b_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "b_WORLD")]],
212
+ ["params", ["SOAP::SOAPString", XSD::QName.new(nil, "params")]],
213
+ ["x2_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "x2_IMAGE")]],
214
+ ["x2_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "x2_WORLD")]],
215
+ ["x_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "x_IMAGE")]],
216
+ ["x_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "x_WORLD")]],
217
+ ["y2_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "y2_IMAGE")]],
218
+ ["y2_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "y2_WORLD")]],
219
+ ["y_image", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "y_IMAGE")]],
220
+ ["y_world", ["SOAP::SOAPBoolean", XSD::QName.new(nil, "y_WORLD")]]
221
+ ]
222
+ }
223
+ end
224
+
225
+ attr_accessor *soap_registration[:schema_element].collect{ |defn| defn.first }
226
+ end
227
+
228
+ # Allows access to WESIX[http://nvogre.phyast.pitt.edu:8080/wesix/],
229
+ # a webservice interface to the standard astronomical image analysis package SExtractor
230
+ # together with a cross matching service using OpenSkyQuery[http://openskyquery.net/].
231
+ #
232
+ # Supposing the FITS file you're interested in is available via a URL, to run a
233
+ # source extraction with sensible defaults:
234
+ #
235
+ # wesix = Service.new
236
+ # votable = wesix.extract('http://nvogre.phyast.pitt.edu:8080/wesix/testr.fits')
237
+ #
238
+ # If it happens to be on disk, you can:
239
+ #
240
+ # votable = wesix.extract(File.new('myfits.fits'))
241
+ #
242
+ # The returned object is a standard VOTable::V1_1::VOTable from which your sources can
243
+ # be extracted.
244
+ #
245
+ # Likewise, an extraction and crossmatch against the SDSS could be done in the following way:
246
+ #
247
+ # votable = wesix.xmatch('http://nvogre.phyast.pitt.edu:8080/wesix/testr.fits')
248
+ #
249
+ # or if it's on disk:
250
+ #
251
+ # votable = wesix.xmatch(File.new('myfits.fits'))
252
+ class Service
253
+ attr_reader :end_point
254
+
255
+ # Convenience method for Service#extract.
256
+ # votable = Service.extract('http://nvogre.phyast.pitt.edu:8080/wesix/testr.fits')
257
+ def self.extract(resource, transpose=false, *args)
258
+ wesix = Service.new
259
+ wesix.extract(resource, transpose, *args)
260
+ end
261
+
262
+ # Convenience method for Service#xmatch.
263
+ # votable = Service.xmatch('http://nvogre.phyast.pitt.edu:8080/wesix/testr.fits')
264
+ def self.xmatch(resource, transpose=false, *args)
265
+ wesix = Service.new
266
+ wesix.xmatch(resource, transpose, *args)
267
+ end
268
+
269
+ # Create a new wesix service instance.
270
+ # Currently the only valid key in the <tt>options</tt> hash is <tt>:end_point</tt>
271
+ # representing the location of the WESIX soap service, and defaults to
272
+ # http://nvogre.phyast.pitt.edu:8080/axis/services/WesixTest. Since at the moment this is
273
+ # the only existing instance of WESIX, you'll never need to specify it.
274
+ #
275
+ # wesix = Wesix.new
276
+ def initialize(options={})
277
+ self.end_point = options[:end_point] || 'http://nvogre.phyast.pitt.edu:8080/axis/services/WesixTest'
278
+ end
279
+
280
+ # Set the locaton of the WESIX webservice.
281
+ # In practice, you'll never need to use this.
282
+ def end_point=(end_point)
283
+ @end_point = end_point
284
+
285
+ # Create the driver.
286
+ # We don't use the WSDL since we won't expose all possible methods.
287
+ @extractor = SOAP::RPC::Driver.new(self.end_point)
288
+ #@extractor.wiredump_dev = STDOUT
289
+ @extractor.return_response_as_xml = true # in prep for dumping the result into a VORuby::VOTable
290
+
291
+ # Map the appropriate objects.
292
+ map = SOAP::Mapping::Registry.new
293
+ map.register(Params.soap_registration)
294
+ map.register(OutputParams.soap_registration)
295
+ @extractor.mapping_registry = map
296
+
297
+ # Define methods.
298
+ @extractor.add_method('wsextractor1VO', 'in0', 'in1')
299
+ @extractor.add_method('wsextractor1VOXmatch', 'in0', 'in1')
300
+ @extractor.add_method('wsextractorURL1VO', 'in0', 'in1')
301
+ @extractor.add_method('wsextractorURL1VOXmatch', 'in0', 'in1')
302
+
303
+ @extractor.add_method('wsextractor2VO', 'in0', 'in1', 'in2')
304
+ @extractor.add_method('wsextractor2VOXmatch', 'in0', 'in1', 'in2')
305
+ @extractor.add_method('wsextractorURL2VO', 'in0', 'in1', 'in2')
306
+ @extractor.add_method('wsextractorURL2VOXmatch', 'in0', 'in1', 'in2')
307
+
308
+ @extractor.add_method('wsextractor3VO', 'in0', 'in1', 'in2', 'in3')
309
+ @extractor.add_method('wsextractor3VOXmatch', 'in0', 'in1', 'in2', 'in3')
310
+ @extractor.add_method('wsextractorURL3VO', 'in0', 'in1', 'in2', 'in3')
311
+ @extractor.add_method('wsextractorURL3VOXmatch', 'in0', 'in1', 'in2', 'in3')
312
+ end
313
+
314
+ # Perform a source extraction on the specified FITS file.
315
+ #
316
+ # <tt>resource</tt> is the FITS file in question. It may be string representing a URL,
317
+ # a URI object or an object that responds to #read (such as a File).
318
+ #
319
+ # <tt>transpose</tt> is a boolean value indicating whether to transpose the image before SExtraction
320
+ # (sometimes necessary for SDSS images).
321
+ #
322
+ # The next two optional arguments are the parameters
323
+ # to be used by SExtractor to create the source catalog (as a Params object) and
324
+ # the measured parameters to be included in the output catalog (as an OutputParams object).
325
+ #
326
+ # A VOTable::V1_1::VOTable is returned.
327
+ #
328
+ # ===== Source extraction with defaults
329
+ #
330
+ # wesix.extract('http://nvogre.phyast.pitt.edu:8080/wesix/testr.fits') # from a URL
331
+ # wesix.extract(URL.parse('http://nvogre.phyast.pitt.edu:8080/wesix/testr.fits')) # this is the same as above
332
+ # wesix.extract(File.new('../fits/my_file.fits')) # from a local file
333
+ #
334
+ # ===== Source extraction with sextractor parameters defined
335
+ #
336
+ # wesix.extract(
337
+ # File.new('../fits/my_file.fits'), # local file, pass a string or URI object if the FITS file is remote
338
+ # false, # no transposition
339
+ # Params.new(:detect_thresh => 2.0, :analysis_thresh => 2.0)
340
+ # )
341
+ #
342
+ # ===== Source extraction with sextractor parameters and measured parameters defined
343
+ #
344
+ # wesix.extract(
345
+ # File.new('../fits/my_file.fits'), # local file, pass a string or URI object if the FITS file is remote
346
+ # false, # no transposition
347
+ # Params.new(:detect_thresh => 2.0, :analysis_thresh => 2.0),
348
+ # OutputParams.new(:flux_best => true, :fluxerr_best => true)
349
+ # )
350
+ def extract(resource, transpose=false, *args)
351
+ if resource.is_a?(URI) or resource.is_a?(String) # FITS file is on a remote machine
352
+ self.extract_from_url(resource.to_s, transpose, *args)
353
+ elsif resource.respond_to?(:read) # FITS file is on a local machine, stored as a diskfile
354
+ self.extract_from_file(resource, transpose, *args)
355
+ else
356
+ raise ArgumentError, 'resource must be a URI, String or respond to a method called #read'
357
+ end
358
+ end
359
+
360
+ # Alias for #extract_and_xmatch
361
+ def xmatch(resource, transpose=false, *args)
362
+ self.extract_and_xmatch(resource, transpose, *args)
363
+ end
364
+
365
+ # Perform a source extraction followed by a crossmatch on the specified FITS file.
366
+ #
367
+ # <tt>resource</tt> is the FITS file in question. It may be string representing a URL,
368
+ # a URI object or an object that responds to #read (such as a File).
369
+ #
370
+ # <tt>transpose</tt> is a boolean value indicating whether to transpose the image before SExtraction
371
+ # (sometimes necessary for SDSS images).
372
+ #
373
+ # The next two optional arguments are the parameters
374
+ # to be used by SExtractor to create the source catalog (as a Params object) and
375
+ # the measured parameters to be included in the output catalog (as an OutputParams object).
376
+ #
377
+ # A VOTable::V1_1::VOTable is returned.
378
+ #
379
+ # ===== Source extraction and crossmatch with defaults
380
+ #
381
+ # wesix.extract_and_xmatch('http://nvogre.phyast.pitt.edu:8080/wesix/testr.fits') # from a URL
382
+ # wesix.extract_and_xmatch(URL.parse('http://nvogre.phyast.pitt.edu:8080/wesix/testr.fits')) # this is the same as above
383
+ # wesix.extract_and_xmatch(File.new('../fits/my_file.fits')) # from a local file
384
+ #
385
+ # ===== Source extraction and crossmatch with sextractor parameters defined
386
+ #
387
+ # wesix.extract_and_xmatch(
388
+ # File.new('../fits/my_file.fits'), # local file, pass a string or URI object if the FITS file is remote
389
+ # false, # no transposition
390
+ # Params.new(:detect_thresh => 2.0, :analysis_thresh => 2.0)
391
+ # )
392
+ #
393
+ # ===== Source extraction and crossmatch with sextractor parameters and measured parameters defined
394
+ #
395
+ # wesix.extract_and_xmatch(
396
+ # File.new('../fits/my_file.fits'), # local file, pass a string or URI object if the FITS file is remote
397
+ # false, # no transposition
398
+ # Params.new(:detect_thresh => 2.0, :analysis_thresh => 2.0),
399
+ # OutputParams.new(:flux_best => true, :fluxerr_best => true)
400
+ # )
401
+ def extract_and_xmatch(resource, transpose=false, *args)
402
+ if resource.is_a?(URI) or resource.is_a?(String) # FITS file is on a remote machine
403
+ self.extract_and_xmatch_from_url(resource.to_s, transpose, *args)
404
+ elsif resource.respond_to?(:read) # FITS file is on a local machine, stored as a diskfile
405
+ self.extract_and_xmatch_from_file(resource, transpose, *args)
406
+ else
407
+ raise ArgumentError, 'resource must be a URI, String or respond to a method called #read'
408
+ end
409
+ end
410
+
411
+ # Perform a source extraction on a local FITS file.
412
+ # <tt>file</tt> is any object with a #read method (such as File).
413
+ # Otherwise exactly as #extract.
414
+ def extract_from_file(file, transpose=false, *args)
415
+ raise "resource does not respond to #read" if !file.respond_to?(:read)
416
+
417
+ file = SOAP::SOAPBase64.new(file.read)
418
+ file.type = XSD::QName.new('http://www.w3.org/2001/XMLSchema', 'base64Binary')
419
+ transpose = transpose ? 1 : 0
420
+
421
+ response = case args.size
422
+ when 0 then @extractor.wsextractor1VO(file, transpose) # basic
423
+ when 1 then @extractor.wsextractor2VO(file, args.first, transpose) # input params specified
424
+ when 2 then @extractor.wsextractor3VO(file, args.first, args.last, transpose) # input params/output flags specified
425
+ else
426
+ raise ArgumentError, "wrong number of optional arguments: #{args.size} > 2"
427
+ end
428
+
429
+ vot_node = XML::Parser.string(response).parse.root.find_first("//*[local-name()='VOTABLE']")
430
+ VORuby::VOTable.from_xml(vot_node)
431
+ end
432
+
433
+ # Perform a source extraction and crossmatch on a local FITS file.
434
+ # <tt>file</tt> is any object with a #read method (such as File).
435
+ # Otherwise exactly as #extract_and_xmatch.
436
+ def extract_and_xmatch_from_file(file, transpose=false, *args)
437
+ raise "resource does not respond to #read" if !file.respond_to?(:read)
438
+
439
+ file = SOAP::SOAPBase64.new(file.read)
440
+ file.type = XSD::QName.new('http://www.w3.org/2001/XMLSchema', 'base64Binary')
441
+ transpose = transpose ? 1 : 0
442
+
443
+ response = case args.size
444
+ when 0 then @extractor.wsextractor1VOXmatch(file, transpose) # basic
445
+ when 1 then @extractor.wsextractor2VOXmatch(file, args.first, transpose) # input params specified
446
+ when 2 then @extractor.wsextractor3VOXmatch(file, args.first, args.last, transpose) # input params/output flags specified
447
+ else
448
+ raise ArgumentError, "wrong number of optional arguments: #{args.size} > 2"
449
+ end
450
+
451
+ vot_node = XML::Parser.string(response).parse.root.find_first("//*[local-name()='VOTABLE']")
452
+ VORuby::VOTable.from_xml(vot_node)
453
+ end
454
+
455
+ # Perform a source extraction on a remotely accessible FITS file.
456
+ # <tt>url</tt> may be a string or a URI object. Otherwise exactly as for #extract.
457
+ def extract_from_url(url, transpose=false, *args)
458
+ transpose = transpose ? 1 : 0
459
+
460
+ response = case args.size
461
+ when 0 then @extractor.wsextractorURL1VO(url.to_s, transpose) # basic
462
+ when 1 then @extractor.wsextractorURL2VO(url.to_s, args.first, transpose) # input params specified
463
+ when 2 then @extractor.wsextractorURL3VO(url.to_s, args.first, args.last, transpose) # input params/output flags specified
464
+ else
465
+ raise ArgumentError, "wrong number of optional arguments: #{args.size} > 2"
466
+ end
467
+
468
+ vot_node = XML::Parser.string(response).parse.root.find_first("//*[local-name()='VOTABLE']")
469
+ VORuby::VOTable.from_xml(vot_node)
470
+ end
471
+
472
+ # Perform a source extraction and crossmatch on a remotely accessible FITS file.
473
+ # <tt>url</tt> may be a string or a URI object. Otherwise exactly as for #extract_and_xmatch.
474
+ def extract_and_xmatch_from_url(url, transpose=false, *args)
475
+ transpose = transpose ? 1 : 0
476
+
477
+ response = case args.size
478
+ when 0 then @extractor.wsextractorURL1VOXmatch(url.to_s, transpose) # basic
479
+ when 1 then @extractor.wsextractorURL2VOXmatch(url.to_s, args.first, transpose) # input params specified
480
+ when 2 then @extractor.wsextractorURL3VOXmatch(url.to_s, args.first, args.last, transpose) # input params/output flags specified
481
+ else
482
+ raise ArgumentError, "wrong number of optional arguments: #{args.size} > 2"
483
+ end
484
+
485
+ vot_node = XML::Parser.string(response).parse.root.find_first("//*[local-name()='VOTABLE']")
486
+ VORuby::VOTable.from_xml(vot_node)
487
+ end
488
+ end
489
+
490
+ end
491
+ end