voruby2-preview 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +339 -0
- data/Rakefile.rb +113 -0
- data/lib/symphony.rb +1 -0
- data/lib/symphony/symphony.rb +247 -0
- data/lib/voruby.rb +186 -0
- data/lib/voruby/misc/libxml_ext.rb +121 -0
- data/lib/voruby/misc/rexml_ext.rb +223 -0
- data/lib/voruby/resolver/resolver.rb +12 -0
- data/lib/voruby/resolver/sesame.rb +299 -0
- data/lib/voruby/votable/1.0/votable.rb +1807 -0
- data/lib/voruby/votable/1.1/votable.rb +2100 -0
- data/lib/voruby/votable/votable.rb +308 -0
- data/lib/voruby/wesix/wesix.rb +491 -0
- data/test/voruby/resolver/sesame/test.rb +56 -0
- data/test/voruby/votable/1.0/test.rb +714 -0
- data/test/voruby/votable/1.0/votable.basic.xml +660 -0
- data/test/voruby/votable/1.0/votable.html +86 -0
- data/test/voruby/votable/1.0/votable.ns.xml +56 -0
- data/test/voruby/votable/1.1/test.rb +785 -0
- data/test/voruby/votable/1.1/votable.basic.xml +38 -0
- data/test/voruby/votable/1.1/votable.html +86 -0
- data/test/voruby/votable/1.1/votable.large.xml +168492 -0
- data/test/voruby/votable/1.1/votable.ns.xml +56 -0
- data/test/voruby/votable/test.rb +15 -0
- data/test/voruby/wesix/test.rb +268 -0
- data/test/voruby/wesix/testr.fits +28 -0
- metadata +119 -0
@@ -0,0 +1,308 @@
|
|
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
|
+
require 'voruby/votable/1.1/votable'
|
150
|
+
return VOTable::V1_1::VOTable.new(generic_vot)
|
151
|
+
elsif namespaces.include?('http://www.ivoa.net/xml/VOTable/v1.0') or generic_vot['version'] =~ /1\.0$/
|
152
|
+
require 'voruby/votable/1.0/votable'
|
153
|
+
return VOTable::V1_0::VOTable.new(generic_vot)
|
154
|
+
else
|
155
|
+
require 'voruby/votable/1.1/votable'
|
156
|
+
return VOTable::V1_1::VOTable.new(generic_vot) # go with the most recent if namespace indeterminate
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# The base class that all VOTable domain objects derive from.
|
161
|
+
# You'll never instantiate this directly.
|
162
|
+
class Base < XML::Object::Base
|
163
|
+
# Get the name of the element when serialized
|
164
|
+
# to XML that the object in question will take on.
|
165
|
+
def self.element_name
|
166
|
+
const_get('ELEMENT_NAME')
|
167
|
+
end
|
168
|
+
|
169
|
+
# Determine the xpath corresponding to the specified class.
|
170
|
+
# obj.xpath_for(Field) # => "*[local-name()='FIELD']"
|
171
|
+
def xpath_for(klass)
|
172
|
+
"*[local-name()='#{klass.element_name}']"
|
173
|
+
end
|
174
|
+
|
175
|
+
# Retrieve the domain object that corresponds to
|
176
|
+
# the specified class.
|
177
|
+
def get_element(klass)
|
178
|
+
subnode = self.node.find_first("*[local-name()='#{klass.element_name}']")
|
179
|
+
subnode ? klass.new(subnode) : nil
|
180
|
+
end
|
181
|
+
|
182
|
+
# Equality among domain objects.
|
183
|
+
# Two objects are considered equal if they're
|
184
|
+
# of the same class and their accessor methods
|
185
|
+
# themselves return objects which are equal.
|
186
|
+
def ==(obj)
|
187
|
+
return false if self.class != obj.class
|
188
|
+
|
189
|
+
self.methods_to_test_for_equality.each do |method|
|
190
|
+
return false if self.send(method) != obj.send(method)
|
191
|
+
end
|
192
|
+
|
193
|
+
true
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def initialize_members(args)
|
199
|
+
if self.class.respond_to?(:serialization_order)
|
200
|
+
self.class.serialization_order.each do |name|
|
201
|
+
send("#{name}=", args[name]) if args.has_key?(name)
|
202
|
+
end
|
203
|
+
else
|
204
|
+
args.each do |name, value|
|
205
|
+
send("#{name}=", value)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Some helper methods for converting string values that have an associated
|
212
|
+
# data type (like TDs do through their associated FIELD).
|
213
|
+
module Castable
|
214
|
+
# Convert a string value into its corresponding basic object representation,
|
215
|
+
# if appropriate. This does *not* work on array values, only on scalars.
|
216
|
+
# Native ruby types map to votable datatypes in the following way:
|
217
|
+
#
|
218
|
+
# * 'boolean' => boolean (i.e TrueClass or FalseClass)
|
219
|
+
# * 'bit' => Integer (1 or 0)
|
220
|
+
# * 'unsignedByte' => Integer representation of the byte
|
221
|
+
# * 'short, 'int', 'long' => Integer
|
222
|
+
# * 'char', 'unicodeChar' => String
|
223
|
+
# * 'float', 'double' => Float or Bignum
|
224
|
+
# * 'floatComplex', 'doubleComplex' => Complex
|
225
|
+
def cast(txt, to='char')
|
226
|
+
case to
|
227
|
+
when 'boolean'
|
228
|
+
txt == '1' || txt.downcase == 'true' || txt.downcase == 't'
|
229
|
+
when 'bit' then txt.to_i
|
230
|
+
when 'unsignedByte' then txt[0]
|
231
|
+
when 'short' then txt.to_i
|
232
|
+
when 'int' then txt.to_i
|
233
|
+
when 'long' then txt.to_i
|
234
|
+
when 'double' then txt.to_f
|
235
|
+
when 'float' then txt.to_f
|
236
|
+
else
|
237
|
+
txt
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# Serialize a ruby object to the format that is correct
|
242
|
+
# for a votable.
|
243
|
+
def convert_to_s(val, from='char')
|
244
|
+
case from
|
245
|
+
when 'boolean'
|
246
|
+
(val.is_a?(TrueClass) or val.to_s.downcase =~ /^t/ or val.to_s == '1') ?
|
247
|
+
'true' : 'false'
|
248
|
+
when 'bit' then val.to_i.to_s
|
249
|
+
when 'short' then val.to_i.to_s
|
250
|
+
when 'int' then val.to_i.to_s
|
251
|
+
when 'long' then val.to_i.to_s
|
252
|
+
when 'float' then val.to_f.to_s
|
253
|
+
when 'double' then val.to_f.to_s
|
254
|
+
when 'floatComplex' then "#{val.real} #{val.image}"
|
255
|
+
when 'doubleComplex' then "#{val.real} #{val.image}"
|
256
|
+
else
|
257
|
+
val.to_s
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Much like #cast but understands arrays.
|
262
|
+
def as_obj(txt, datatype, arraysize=nil)
|
263
|
+
raise "Unable to determine datatype" if !datatype
|
264
|
+
|
265
|
+
txt_list = arraysize ? txt.split(/\s+/) : [txt]
|
266
|
+
values_list = []
|
267
|
+
|
268
|
+
# character string, do nothing
|
269
|
+
return txt if datatype == 'char' or datatype == 'unicodeChar'
|
270
|
+
|
271
|
+
# complex values are a bit different
|
272
|
+
if datatype == 'floatComplex' || datatype == 'doubleComplex'
|
273
|
+
txt_list = txt.split(/\s+/)
|
274
|
+
complex_numbers = []
|
275
|
+
i = 0
|
276
|
+
(0...txt_list.size/2).each do |n|
|
277
|
+
complex_numbers << Complex.new(txt_list[i].to_f, txt_list[i+1].to_f)
|
278
|
+
i += 2
|
279
|
+
end
|
280
|
+
return arraysize ? complex_numbers : complex_numbers.first
|
281
|
+
end
|
282
|
+
|
283
|
+
txt_list.each do |component|
|
284
|
+
values_list << cast(component, datatype)
|
285
|
+
end
|
286
|
+
|
287
|
+
arraysize ? values_list : values_list.first
|
288
|
+
end
|
289
|
+
|
290
|
+
# Much like #convert_to_s but understands arrays.
|
291
|
+
def as_string(obj, datatype, arraysize=nil)
|
292
|
+
raise "Unable to determine datatype" if !datatype
|
293
|
+
raise "Supposed to contain an array of size '#{arraysize}'" if arraysize and !obj.is_a?(Array)
|
294
|
+
raise "Supposed to contain a single value" if !arraysize and obj.is_a?(Array)
|
295
|
+
|
296
|
+
obj = [obj] if !obj.is_a?(Array)
|
297
|
+
|
298
|
+
values = []
|
299
|
+
obj.each do |val|
|
300
|
+
values << convert_to_s(val, datatype)
|
301
|
+
end
|
302
|
+
|
303
|
+
values.join(' ')
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
308
|
+
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
|