File Coverage

blib/lib/Astro/SIMBAD/Query.pm
Criterion Covered Total %
statement 444 622 71.3
branch 11 60 18.3
condition 4 24 16.6
subroutine 22 41 53.6
pod 8 18 44.4
total 489 765 63.9


line stmt bran cond sub pod time code
1             package Astro::SIMBAD::Query;
2              
3             # ---------------------------------------------------------------------------
4              
5             #+
6             # Name:
7             # Astro::SIMBAD::Query
8              
9             # Purposes:
10             # Perl wrapper for the SIMBAD database
11              
12             # Language:
13             # Perl module
14              
15             # Description:
16             # This module wraps the SIMBAD online database.
17              
18             # Authors:
19             # Alasdair Allan (aa@astro.ex.ac.uk)
20              
21             # Revision:
22             # $Id: Query.pm,v 1.14 2005/06/08 01:38:17 aa Exp $
23              
24             # Copyright:
25             # Copyright (C) 2001 University of Exeter. All Rights Reserved.
26              
27             #-
28              
29             # ---------------------------------------------------------------------------
30              
31             =head1 NAME
32              
33             Astro::SIMBAD::Query - Object definining an prospective SIMBAD query.
34              
35             =head1 SYNOPSIS
36              
37             $query = new Astro::SIMBAD::Query( Target => $object,
38             RA => $ra,
39             Dec => $dec,
40             Error => $radius,
41             Units => $radius_units,
42             Frame => $coord_frame,
43             Epoch => $coord_epoch,
44             Equinox => $coord_equinox,
45             Proxy => $proxy,
46             Timeout => $timeout,
47             URL => $alternative_url );
48              
49             my $results = $query->querydb();
50              
51             $other = new Astro::SIMBAD::Query( Target => $object );
52              
53             =head1 DESCRIPTION
54              
55             Stores information about an prospective SIMBAD query and allows the query to
56             be made, returning an Astro::SIMBAD::Result object. Minimum information needed
57             for a sucessful query is an R.A. and Dec. or an object Target speccification,
58             other variables will be defaulted.
59              
60             The Query object supports two types of queries: "list" (summary)
61             and "object" (detailed). The list query usually returns multiple results;
62             the object query is expected to obtain only one result, but returns extra
63             data about that target. An object query is performed if the target name
64             is specified and the Error radius is 0; otherwise, a list query is done.
65              
66             The object will by default pick up the proxy information from the HTTP_PROXY
67             and NO_PROXY environment variables, see the LWP::UserAgent documentation for
68             details.
69              
70             =cut
71              
72             # L O A D M O D U L E S --------------------------------------------------
73              
74 1     1   8119 use strict;
  1         2  
  1         43  
75 1     1   5 use vars qw/ $VERSION /;
  1         2  
  1         43  
76              
77 1     1   1198 use LWP::UserAgent;
  1         146138  
  1         56  
78 1     1   1349 use Net::Domain qw(hostname hostdomain);
  1         39815  
  1         1290  
79 1     1   15 use Carp;
  1         3  
  1         73  
80 1     1   2694 use HTML::TreeBuilder;
  1         93375  
  1         13  
81 1     1   49 use HTML::Entities;
  1         2  
  1         101  
82              
83 1     1   771 use Astro::SIMBAD::Result;
  1         3  
  1         24  
84 1     1   6 use Astro::SIMBAD::Result::Object;
  1         1  
  1         5040  
85              
86             '$Revision: 1.14 $ ' =~ /.*:\s(.*)\s\$/ && ($VERSION = $1);
87              
88             sub trim {
89 0     0 0 0 my $s = shift;
90 0         0 $s =~ s/(^\s+)|(\s+$)//g;
91 0         0 return $s;
92             }
93              
94             # C O N S T R U C T O R ----------------------------------------------------
95              
96             =head1 REVISION
97              
98             $Id: Query.pm,v 1.14 2005/06/08 01:38:17 aa Exp $
99              
100             =head1 METHODS
101              
102             =head2 Constructor
103              
104             =over 4
105              
106             =item B
107              
108             Create a new instance from a hash of options
109              
110             $query = new Astro::SIMBAD::Query( Target => $object,
111             RA => $ra,
112             Dec => $dec,
113             Error => $radius,
114             Units => $radius_units,
115             Frame => $coord_frame,
116             Epoch => $coord_epoch,
117             Equinox => $coord_equinox,
118             Proxy => $proxy,
119             Timeout => $timeout,
120             URL => $alternative_url );
121              
122             returns a reference to an SIMBAD query object.
123              
124             =cut
125              
126             sub new {
127 1     1 1 532 my $proto = shift;
128 1   33     8 my $class = ref($proto) || $proto;
129              
130             # bless the query hash into the class
131 1         13 my $block = bless { OPTIONS => {},
132             RA => undef,
133             DEC => undef,
134             URL => undef,
135             QUERY => undef,
136             USERAGENT => undef,
137             BUFFER => undef,
138             LOOKUP => {} }, $class;
139              
140             # Configure the object
141 1         7 $block->configure( @_ );
142              
143 1         5 return $block;
144              
145             }
146              
147             # Q U E R Y M E T H O D S ------------------------------------------------
148              
149             =back
150              
151             =head2 Accessor Methods
152              
153             =over 4
154              
155             =item B
156              
157             Returns an Astro::SIMBAD::Result object for an inital SIMBAD query
158              
159             $results = $query->querydb();
160              
161             =cut
162              
163             sub querydb {
164 1     1 1 291 my $self = shift;
165              
166             # call the private method to make the actual SIMBAD query
167 1         4 $self->_make_query();
168              
169             # check for failed connect
170 1 50       68 return undef unless defined $self->{BUFFER};
171              
172             # return an Astro::SIMBAD::Result object
173 1         6 return $self->_parse_query();
174              
175             }
176              
177             =item B
178              
179             Return (or set) the current proxy for the SIMBAD request.
180              
181             $query->proxy( 'http://wwwcache.ex.ac.uk:8080/' );
182             $proxy_url = $query->proxy();
183              
184             =cut
185              
186             sub proxy {
187 0     0 1 0 my $self = shift;
188              
189             # grab local reference to user agent
190 0         0 my $ua = $self->{USERAGENT};
191              
192 0 0       0 if (@_) {
193 0         0 my $proxy_url = shift;
194 0         0 $ua->proxy('http', $proxy_url );
195             }
196              
197             # return the current proxy
198 0         0 return $ua->proxy('http');
199              
200             }
201              
202             =item B
203              
204             Return (or set) the current timeout in seconds for the SIMBAD request.
205              
206             $query->timeout( 30 );
207             $proxy_timeout = $query->timeout();
208              
209             =cut
210              
211             sub timeout {
212 0     0 1 0 my $self = shift;
213              
214             # grab local reference to user agent
215 0         0 my $ua = $self->{USERAGENT};
216              
217 0 0       0 if (@_) {
218 0         0 my $time = shift;
219 0         0 $ua->timeout( $time );
220             }
221              
222             # return the current timeout
223 0         0 return $ua->timeout();
224              
225             }
226              
227             =item B
228              
229             Return (or set) the current base URL for the ADS query.
230              
231             $url = $query->url();
232             $query->url( "simbad.u-strasbg.fr" );
233              
234             if not defined the default URL is simbad.u-strasbg.fr
235              
236             =cut
237              
238             sub url {
239 0     0 1 0 my $self = shift;
240              
241             # SETTING URL
242 0 0       0 if (@_) {
243              
244             # set the url option
245 0         0 my $base_url = shift;
246 0 0       0 if( defined $base_url ) {
247 0         0 $self->{URL} = $base_url;
248 0         0 $self->{QUERY} = "http://$base_url/sim-id.pl?";
249             }
250             }
251              
252             # RETURNING URL
253 0         0 return $self->{URL};
254             }
255              
256             =item B
257              
258             Returns the user agent tag sent by the module to the ADS server.
259              
260             $agent_tag = $query->agent();
261              
262             =cut
263              
264             sub agent {
265 0     0 1 0 my $self = shift;
266 0         0 return $self->{USERAGENT}->agent();
267             }
268              
269             # O T H E R M E T H O D S ------------------------------------------------
270              
271              
272             =item B
273              
274             Return (or set) the current target R.A. defined for the SIMBAD query
275              
276             $ra = $query->ra();
277             $query->ra( $ra );
278              
279             where $ra should be a string of the form "HH MM SS.SS", e.g. 21 42 42.66
280              
281             =cut
282              
283             sub ra {
284 1     1 0 3 my $self = shift;
285              
286             # SETTING R.A.
287 1 50       4 if (@_) {
288            
289             # grab the new R.A.
290 1         2 my $ra = shift;
291            
292             # mutilate it and stuff it and the current $self->{RA}
293             # into the ${$self->{OPTIONS}}{"Ident"} hash item.
294 1         6 $ra =~ s/\s/\+/g;
295 1         3 $self->{RA} = $ra;
296            
297             # grab the currently set DEC
298 1         3 my $dec = $self->{DEC};
299            
300             # set the identifier
301 1         3 ${$self->{OPTIONS}}{"Ident"} = "$ra+$dec";
  1         3  
302             }
303            
304             # un-mutilate and return a nicely formated string to the user
305 1         2 my $ra = $self->{RA};
306 1         5 $ra =~ s/\+/ /g;
307 1         2 return $ra;
308             }
309              
310             =item B
311              
312             Return (or set) the current target Declination defined for the SIMBAD query
313              
314             $dec = $query->dec();
315             $query->dec( $dec );
316              
317             where $dec should be a string of the form "+-HH MM SS.SS", e.g. +43 35 09.5
318             or -40 25 67.89
319              
320             =cut
321              
322             sub dec {
323 1     1 0 3 my $self = shift;
324              
325             # SETTING DEC
326 1 50       4 if (@_) {
327              
328             # grab the new Dec
329 1         2 my $dec = shift;
330            
331             # mutilate it and stuff it and the current $self->{DEC}
332             # into the ${$self->{OPTIONS}}{"Ident"} hash item.
333 1         4 $dec =~ s/\+/%2B/g;
334 1         6 $dec =~ s/\s/\+/g;
335 1         2 $self->{DEC} = $dec;
336            
337             # grab the currently set RA
338 1         2 my $ra = $self->{RA};
339            
340             # set the identifier
341 1         3 ${$self->{OPTIONS}}{"Ident"} = "$ra+$dec";
  1         3  
342             }
343            
344             # un-mutilate and return a nicely formated string to the user
345 1         3 my $dec = $self->{DEC};
346 1         3 $dec =~ s/\+/ /g;
347 1         4 $dec =~ s/%2B/\+/g;
348 1         3 return $dec;
349              
350             }
351              
352             =item B
353              
354             Instead of querying SIMBAD by R.A. and Dec., you may also query it by object
355             name. Return (or set) the current target object defined for the SIMBAD query
356              
357             $ident = $query->target();
358             $query->target( "HT Cas" );
359              
360             using an object name will override the current R.A. and Dec settings for the
361             Query object (if currently set) and the next querydb() method call will query
362             SIMBAD using this identifier rather than any currently set co-ordinates.
363              
364             =cut
365              
366             sub target {
367 0     0 0 0 my $self = shift;
368              
369             # SETTING IDENTIFIER
370 0 0       0 if (@_) {
371              
372             # grab the new object name
373 0         0 my $ident = shift;
374            
375             # mutilate it and stuff it into ${$self->{OPTIONS}}{"Ident"}
376 0         0 $ident =~ s/\s/\+/g;
377 0         0 ${$self->{OPTIONS}}{"Ident"} = $ident;
  0         0  
378              
379             # refigure object/list search type
380 0         0 $self->_update_nbident();
381             }
382            
383 0         0 return ${$self->{OPTIONS}}{"Ident"};
  0         0  
384              
385             }
386              
387             =item B
388              
389             The error radius to be searched for SIMBAD objects around the target R.A.
390             and Dec, the radius defaults to 10 arc seconds, with the radius unit being
391             set using the units() method.
392              
393             $error = $query->error();
394             $query->error( 20 );
395              
396             =cut
397              
398             sub error {
399 1     1 0 2 my $self = shift;
400              
401 1 50       4 if (@_) {
402             # If searching with a nonzero radius, do a list query.
403             # If radius is zero, get a detailed object query.
404 1         2 ${$self->{OPTIONS}}{"Radius"} = shift;
  1         3  
405              
406             # refigure object/list search type
407 1         5 $self->_update_nbident();
408             }
409            
410 1         2 return ${$self->{OPTIONS}}{"Radius"};
  1         3  
411              
412             }
413              
414             =item B
415              
416             The unit for the error radius to be searched for SIMBAD objects around the
417             target R.A. and Dec, the radius defaults to 10 arc seconds, with the radius itself being set using the error() method
418              
419             $error = $query->units();
420             $query->units( "arcmin" );
421              
422             valid unit types are "arcsec", "arcmin" and "deg".
423              
424             =cut
425              
426             sub units {
427 1     1 0 2 my $self = shift;
428              
429 1 50       5 if (@_) {
430            
431 1         8 my $unit = shift;
432 1 0 33     5 if( $unit eq "arcsec" || $unit eq "arcmin" || $unit eq "deg" ) {
      33        
433 1         2 ${$self->{OPTIONS}}{"Radius.unit"} = $unit;
  1         3  
434             }
435             }
436            
437 1         3 return ${$self->{OPTIONS}}{"Radius.unit"};
  1         3  
438              
439             }
440              
441             =item B
442              
443             When searching by coordinates, or if the radius is nonzero, we perform a
444             "list query" that is expected to return multiple results. However, if
445             searching for a target by name, and the error radius is zero, it is pretty
446             clear that we want a specific target. In that case, we use a more detailed
447             "object query."
448              
449             This method returns true if the criteria are such that we will use a list
450             query and false if it is an object query.
451              
452             =cut
453             sub use_list_query {
454 2     2 1 11 my $self = shift;
455 2   33     3 return ((${$self->{OPTIONS}}{"Ident"} =~ m/^(\d{1,3}\+){2}/) || (${$self->{OPTIONS}}{"Radius"} > 0));
456             }
457              
458             =item B
459              
460             The frame in which the R.A. and Dec co-ordinates are given
461              
462             $frame = $query->frame();
463             $query->frames( "FK5" );
464              
465             valid frames are "FK5" and "FK4", if not specified it will default to FK5.
466              
467             =cut
468              
469             sub frame {
470 0     0 0 0 my $self = shift;
471              
472 0 0       0 if (@_) {
473            
474 0         0 my $frame = shift;
475 0 0 0     0 if( $frame eq "FK5" || $frame eq "FK4" ) {
476 0         0 ${$self->{OPTIONS}}{"CooFrame"} = $frame;
  0         0  
477             }
478             }
479            
480 0         0 return ${$self->{OPTIONS}}{"CooFrame"};
  0         0  
481              
482             }
483              
484             =item B
485              
486             The epoch for the R.A. and Dec co-ordinates
487              
488             $epoch = $query->epoch();
489             $query->epoch( "1950" );
490              
491             defaults to 2000
492              
493             =cut
494              
495             sub epoch {
496 0     0 0 0 my $self = shift;
497              
498 0 0       0 if (@_) {
499 0         0 ${$self->{OPTIONS}}{"CooEpoch"} = shift;
  0         0  
500             }
501            
502 0         0 return ${$self->{OPTIONS}}{"CooEpoch"};
  0         0  
503              
504             }
505              
506             =item B
507              
508             The equinox for the R.A. and Dec co-ordinates
509              
510             $equinox = $query->equinox();
511             $query->equinox( "2000" );
512              
513             defaults to 2000
514              
515             =cut
516              
517             sub equinox {
518 0     0 0 0 my $self = shift;
519              
520 0 0       0 if (@_) {
521 0         0 ${$self->{OPTIONS}}{"CooEqui"} = shift;
  0         0  
522             }
523            
524 0         0 return ${$self->{OPTIONS}}{"CooEqui"};
  0         0  
525              
526             }
527              
528             =item B
529              
530             Returns the URL used to query the Simbad database
531              
532             =cut
533              
534             sub queryurl {
535 1     1 0 2 my $self = shift;
536              
537             # grab the base URL
538 1         3 my $URL = $self->{QUERY};
539 1         2 my $options = "";
540              
541             # loop round all the options keys and build the query
542 1         107 foreach my $key ( keys %{$self->{OPTIONS}} ) {
  1         7  
543 22         27 $options = $options . "&$key=${$self->{OPTIONS}}{$key}";
  22         49  
544             }
545              
546             # build final query URL
547 1         5 $URL = $URL . $options;
548            
549 1         2 return $URL;
550             }
551              
552             # C O N F I G U R E -------------------------------------------------------
553              
554             =back
555              
556             =head2 General Methods
557              
558             =over 4
559              
560             =item B
561              
562             Configures the object, takes an options hash as an argument
563              
564             $query->configure( %options );
565              
566             Does nothing if the array is not supplied.
567              
568             =cut
569              
570             sub configure {
571 1     1 1 3 my $self = shift;
572              
573             # CONFIGURE DEFAULTS
574             # ------------------
575              
576             # default the R.A. and DEC to blank strings to avoid uninitialized
577             # value problems when creating the object
578 1         6 $self->{RA} = "";
579 1         2 $self->{DEC} = "";
580              
581             # define the default base URLs
582 1         3 $self->{URL} = "simbad.u-strasbg.fr";
583            
584             # define the query URLs
585 1         2 my $default_url = $self->{URL};
586 1         5 $self->{QUERY} = "http://$default_url/sim-id.pl?";
587              
588             # Setup the LWP::UserAgent
589 1         28 my $HOST = hostname();
590 1         9524 my $DOMAIN = hostdomain();
591 1         15 $self->{USERAGENT} = new LWP::UserAgent( timeout => 30 );
592 1         6181 $self->{USERAGENT}->agent("Astro::SIMBAD/$VERSION ($HOST.$DOMAIN)");
593              
594             # Grab Proxy details from local environment
595 1         85 $self->{USERAGENT}->env_proxy();
596              
597             # configure the default options
598 1         21732 ${$self->{OPTIONS}}{"protocol"} = "html";
  1         8  
599 1         3 ${$self->{OPTIONS}}{"Ident"} = undef;
  1         4  
600 1         2 ${$self->{OPTIONS}}{"NbIdent"} = "around";
  1         4  
601 1         3 ${$self->{OPTIONS}}{"Radius"} = "10";
  1         4  
602 1         3 ${$self->{OPTIONS}}{"Radius.unit"} = "arcsec";
  1         3  
603 1         3 ${$self->{OPTIONS}}{"CooFrame"} = "FK5";
  1         79  
604 1         5 ${$self->{OPTIONS}}{"CooEpoch"} = "2000";
  1         4  
605 1         3 ${$self->{OPTIONS}}{"CooEqui"} = "2000";
  1         6  
606 1         2 ${$self->{OPTIONS}}{"output.max"} = "all";
  1         4  
607 1         2 ${$self->{OPTIONS}}{"o.catall"} = "on";
  1         3  
608 1         14 ${$self->{OPTIONS}}{"output.mesdisp"} = "A";
  1         4  
609 1         3 ${$self->{OPTIONS}}{"Bibyear1"} = "1983";
  1         2  
610 1         2 ${$self->{OPTIONS}}{"Bibyear2"} = "2001";
  1         4  
611              
612             # Frame 1, FK5 2000/2000
613 1         2 ${$self->{OPTIONS}}{"Frame1"} = "FK5";
  1         3  
614 1         2 ${$self->{OPTIONS}}{"Equi1"} = "2000.0";
  1         4  
615 1         1 ${$self->{OPTIONS}}{"Epoch1"} = "2000.0";
  1         6  
616            
617             # Frame 2, FK4 1950/1950
618 1         3 ${$self->{OPTIONS}}{"Frame2"} = "FK4";
  1         4  
619 1         2 ${$self->{OPTIONS}}{"Equi2"} = "1950.0";
  1         4  
620 1         3 ${$self->{OPTIONS}}{"Epoch2"} = "1950.0";
  1         4  
621            
622             # Frame 3, Galactic
623 1         2 ${$self->{OPTIONS}}{"Frame3"} = "G";
  1         3  
624 1         2 ${$self->{OPTIONS}}{"Equi3"} = "2000.0";
  1         3  
625 1         3 ${$self->{OPTIONS}}{"Epoch3"} = "2000.0";
  1         3  
626              
627             # TYPE LOOKUP HASH TABLE
628             # ----------------------
629            
630             # build the data table
631 1         3 ${$self->{LOOKUP}}{"?"} = "Object of unknown nature";
  1         4  
632 1         2 ${$self->{LOOKUP}}{"Rad"} = "Radio-source";
  1         3  
633 1         2 ${$self->{LOOKUP}}{"mR"} = "metric Radio-source";
  1         4  
634 1         3 ${$self->{LOOKUP}}{"cm"} = "centimetric Radio-source";
  1         4  
635 1         2 ${$self->{LOOKUP}}{"mm"} = "millimetric Radio-source";
  1         4  
636 1         3 ${$self->{LOOKUP}}{"Mas"} = "Maser";
  1         3  
637 1         2 ${$self->{LOOKUP}}{"IR"} = "Infra-Red source";
  1         3  
638 1         2 ${$self->{LOOKUP}}{"IR1"} = "IR source at lambda > 10 microns";
  1         4  
639 1         3 ${$self->{LOOKUP}}{"IR0"} = "IR source at lambda < 10 microns";
  1         4  
640 1         2 ${$self->{LOOKUP}}{"red"} = "Very red source";
  1         3  
641 1         2 ${$self->{LOOKUP}}{"blu"} = "Blue object";
  1         3  
642 1         3 ${$self->{LOOKUP}}{"UV"} = "UV-emission source";
  1         3  
643 1         2 ${$self->{LOOKUP}}{"X"} = "X-ray source";
  1         3  
644 1         2 ${$self->{LOOKUP}}{"gam"} = "gamma-ray source";
  1         3  
645 1         2 ${$self->{LOOKUP}}{"gB"} = "gamma-ray Burster";
  1         4  
646 1         2 ${$self->{LOOKUP}}{"grv"} = "Gravitational Source";
  1         5  
647 1         3 ${$self->{LOOKUP}}{"Lev"} = "(Micro)Lensing Event";
  1         3  
648 1         2 ${$self->{LOOKUP}}{"mul"} = "Composite object";
  1         3  
649 1         2 ${$self->{LOOKUP}}{"reg"} = "Region defined in the sky";
  1         2  
650 1         2 ${$self->{LOOKUP}}{"vid"} = "Underdense region of the Universe";
  1         3  
651 1         2 ${$self->{LOOKUP}}{"SCG"} = "Supercluster of Galaxies";
  1         4  
652 1         2 ${$self->{LOOKUP}}{"ClG"} = "Cluster of Galaxies";
  1         3  
653 1         9 ${$self->{LOOKUP}}{"GrG"} = "Group of Galaxies";
  1         3  
654 1         2 ${$self->{LOOKUP}}{"CGG"} = "Compact Group of Galaxies";
  1         3  
655 1         3 ${$self->{LOOKUP}}{"PaG"} = "Pair of Galaxies";
  1         3  
656 1         2 ${$self->{LOOKUP}}{"Gl?"} = "Possible Globular Cluster";
  1         3  
657 1         3 ${$self->{LOOKUP}}{"Cl*"} = "Cluster of Stars";
  1         3  
658 1         2 ${$self->{LOOKUP}}{"GlC"} = "Globular Cluster";
  1         3  
659 1         3 ${$self->{LOOKUP}}{"OpC"} = "Open (galactic) Cluster";
  1         5  
660 1         2 ${$self->{LOOKUP}}{"As*"} = "Association of Stars";
  1         3  
661 1         2 ${$self->{LOOKUP}}{"**"} = "Double or multiple star";
  1         3  
662 1         2 ${$self->{LOOKUP}}{"EB*"} = "Eclipsing binary";
  1         5  
663 1         3 ${$self->{LOOKUP}}{"Al*"} = "Eclipsing binary of Algol type";
  1         3  
664 1         3 ${$self->{LOOKUP}}{"bL*"} = "Eclipsing binary of beta Lyr type";
  1         4  
665 1         1 ${$self->{LOOKUP}}{"WU*"} = "Eclipsing binary of W UMa type";
  1         3  
666 1         3 ${$self->{LOOKUP}}{"SB*"} = "Spectrocopic binary";
  1         3  
667 1         2 ${$self->{LOOKUP}}{"CV*"} = "Cataclysmic Variable Star";
  1         8  
668 1         3 ${$self->{LOOKUP}}{"DQ*"} = "Cataclysmic Var. DQ Her type";
  1         2  
669 1         2 ${$self->{LOOKUP}}{"AM*"} = "Cataclysmic Var. AM Her type";
  1         3  
670 1         2 ${$self->{LOOKUP}}{"NL*"} = "Nova-like Star";
  1         52  
671 1         2 ${$self->{LOOKUP}}{"No*"} = "Nova";
  1         4  
672 1         2 ${$self->{LOOKUP}}{"DN*"} = "Dwarf Nova";
  1         3  
673 1         2 ${$self->{LOOKUP}}{"XB*"} = "X-ray Binary";
  1         3  
674 1         2 ${$self->{LOOKUP}}{"LXB"} = "Low Mass X-ray Binary";
  1         3  
675 1         2 ${$self->{LOOKUP}}{"HXB"} = "High Mass X-ray Binary";
  1         3  
676 1         2 ${$self->{LOOKUP}}{"Neb"} = "Nebula of unknown nature";
  1         4  
677 1         2 ${$self->{LOOKUP}}{"PoC"} = "Part of Cloud";
  1         3  
678 1         2 ${$self->{LOOKUP}}{"PN?"} = "Possible Planetary Nebula";
  1         3  
679 1         2 ${$self->{LOOKUP}}{"CGb"} = "Cometary Globule";
  1         4  
680 1         3 ${$self->{LOOKUP}}{"EmO"} = "Emission Object";
  1         3  
681 1         1 ${$self->{LOOKUP}}{"HH"} = "Herbig-Haro Object";
  1         4  
682 1         2 ${$self->{LOOKUP}}{"Cld"} = "Cloud of unknown nature";
  1         3  
683 1         2 ${$self->{LOOKUP}}{"GNe"} = "Galactic Nebula";
  1         4  
684 1         2 ${$self->{LOOKUP}}{"BNe"} = "Bright Nebula";
  1         3  
685 1         1 ${$self->{LOOKUP}}{"DNe"} = "Dark Nebula";
  1         3  
686 1         2 ${$self->{LOOKUP}}{"RNe"} = "Reflection Nebula";
  1         3  
687 1         8 ${$self->{LOOKUP}}{"HI"} = "HI (neutral) region";
  1         4  
688 1         2 ${$self->{LOOKUP}}{"MoC"} = "Molecular Cloud";
  1         3  
689 1         2 ${$self->{LOOKUP}}{"HVC"} = "High-velocity Cloud";
  1         2  
690 1         3 ${$self->{LOOKUP}}{"HII"} = "HII (ionized) region";
  1         3  
691 1         2 ${$self->{LOOKUP}}{"PN"} = "Planetary Nebula";
  1         4  
692 1         2 ${$self->{LOOKUP}}{"sh"} = "HI shell";
  1         9  
693 1         2 ${$self->{LOOKUP}}{"SR?"} = "SuperNova Remnant Candidate";
  1         3  
694 1         2 ${$self->{LOOKUP}}{"SNR"} = "SuperNova Remnant";
  1         7  
695 1         2 ${$self->{LOOKUP}}{"*"} = "Star";
  1         4  
696 1         2 ${$self->{LOOKUP}}{"*iC"} = "Star in Cluster";
  1         3  
697 1         2 ${$self->{LOOKUP}}{"*iN"} = "Star in Nebula";
  1         3  
698 1         2 ${$self->{LOOKUP}}{"*iA"} = "Star in Association";
  1         8  
699 1         2 ${$self->{LOOKUP}}{"*i*"} = "Star in double system";
  1         2  
700 1         2 ${$self->{LOOKUP}}{"V*?"} = "Star suspected of Variability";
  1         2  
701 1         3 ${$self->{LOOKUP}}{"Pe*"} = "Peculiar Star";
  1         9  
702 1         2 ${$self->{LOOKUP}}{"HB*"} = "Horizontal Branch Star";
  1         4  
703 1         2 ${$self->{LOOKUP}}{"Em*"} = "Emission-line Star";
  1         3  
704 1         2 ${$self->{LOOKUP}}{"Be*"} = "Be Star";
  1         3  
705 1         2 ${$self->{LOOKUP}}{"WD*"} = "White Dwarf";
  1         3  
706 1         2 ${$self->{LOOKUP}}{"ZZ*"} = "Variable White Dwarf of ZZ Cet type";
  1         3  
707 1         2 ${$self->{LOOKUP}}{"C*"} = "Carbon Star";
  1         3  
708 1         2 ${$self->{LOOKUP}}{"S*"} = "S Star";
  1         3  
709 1         2 ${$self->{LOOKUP}}{"OH*"} = "Star with envelope of OH/IR type";
  1         3  
710 1         2 ${$self->{LOOKUP}}{"CH*"} = "Star with envelope of CH type";
  1         3  
711 1         8 ${$self->{LOOKUP}}{"pr*"} = "Pre-main sequence Star";
  1         3  
712 1         2 ${$self->{LOOKUP}}{"TT*"} = "T Tau-type Star";
  1         2  
713 1         2 ${$self->{LOOKUP}}{"WR*"} = "Wolf-Rayet Star";
  1         3  
714 1         2 ${$self->{LOOKUP}}{"PM*"} = "High proper-motion Star";
  1         3  
715 1         2 ${$self->{LOOKUP}}{"HV*"} = "High-velocity Star";
  1         3  
716 1         2 ${$self->{LOOKUP}}{"V*"} = "Variable Star";
  1         3  
717 1         2 ${$self->{LOOKUP}}{"Ir*"} = "Variable Star of irregular type";
  1         2  
718 1         2 ${$self->{LOOKUP}}{"Or*"} = "Variable Star in Orion Nebula";
  1         3  
719 1         2 ${$self->{LOOKUP}}{"V* RI*"} = "Variable Star with rapid variations";
  1         3  
720 1         1 ${$self->{LOOKUP}}{"Er*"} = "Eruptive variable Star";
  1         3  
721 1         15 ${$self->{LOOKUP}}{"Fl*"} = "Flare Star";
  1         4  
722 1         2 ${$self->{LOOKUP}}{"FU*"} = "Variable Star of FU Ori type";
  1         3  
723 1         2 ${$self->{LOOKUP}}{"RC*"} = "Variable Star of R CrB type";
  1         3  
724 1         2 ${$self->{LOOKUP}}{"Ro*"} = "Rotationally variable Star";
  1         4  
725 1         3 ${$self->{LOOKUP}}{"a2*"} = "Variable Star of alpha2 CVn type";
  1         2  
726 1         2 ${$self->{LOOKUP}}{"El*"} = "Elliptical variable Star";
  1         3  
727 1         2 ${$self->{LOOKUP}}{"Psr"} = "Pulsars";
  1         2  
728 1         3 ${$self->{LOOKUP}}{"BY*"} = "Variable of BY Dra type";
  1         2  
729 1         2 ${$self->{LOOKUP}}{"RS*"} = "Variable of RS CVn type";
  1         3  
730 1         3 ${$self->{LOOKUP}}{"Pu*"} = "Pulsating variable Star";
  1         3  
731 1         1 ${$self->{LOOKUP}}{"Mi*"} = "Variable Star of Mira Cet type";
  1         3  
732 1         8 ${$self->{LOOKUP}}{"RR*"} = "Variable Star of RR Lyr type";
  1         3  
733 1         3 ${$self->{LOOKUP}}{"Ce*"} = "Classical Cepheid variable Star";
  1         3  
734 1         1 ${$self->{LOOKUP}}{"eg sr*"} = "Semi-regular pulsating Star";
  1         3  
735 1         2 ${$self->{LOOKUP}}{"dS*"} = "Variable Star of delta Sct type";
  1         10  
736 1         2 ${$self->{LOOKUP}}{"RV*"} = "Variable Star of RV Tau type";
  1         3  
737 1         2 ${$self->{LOOKUP}}{"WV*"} = "Variable Star of W Vir type";
  1         4  
738 1         2 ${$self->{LOOKUP}}{"SN*"} = "SuperNova";
  1         4  
739 1         2 ${$self->{LOOKUP}}{"Sy*"} = "Symbiotic Star";
  1         3  
740 1         2 ${$self->{LOOKUP}}{"G"} = "Galaxy";
  1         4  
741 1         2 ${$self->{LOOKUP}}{"PoG"} = "Part of a Galaxy";
  1         10  
742 1         3 ${$self->{LOOKUP}}{"GiC"} = "Galaxy in Cluster of Galaxies";
  1         2  
743 1         2 ${$self->{LOOKUP}}{"GiG"} = "Galaxy in Group of Galaxies";
  1         3  
744 1         2 ${$self->{LOOKUP}}{"GiP"} = "Galaxy in Pair of Galaxies";
  1         3  
745 1         1 ${$self->{LOOKUP}}{"HzG"} = "Galaxy with high redshift";
  1         3  
746 1         1 ${$self->{LOOKUP}}{"ALS"} = "Absorption Line system";
  1         2  
747 1         2 ${$self->{LOOKUP}}{"LyA"} = "Ly alpha Absorption Line system";
  1         3  
748 1         2 ${$self->{LOOKUP}}{"DLy"} = "Dumped Ly alpha Absorption Line system";
  1         2  
749 1         2 ${$self->{LOOKUP}}{"mAL"} = "metallic Absorption Line system";
  1         2  
750 1         2 ${$self->{LOOKUP}}{"rG"} = "Radio Galaxy";
  1         3  
751 1         2 ${$self->{LOOKUP}}{"H2G"} = "HII Galaxy";
  1         2  
752 1         3 ${$self->{LOOKUP}}{"Q?"} = "Possible Quasar";
  1         2  
753 1         2 ${$self->{LOOKUP}}{"EmG"} = "Emission-line galaxy";
  1         12  
754 1         3 ${$self->{LOOKUP}}{"SBG"} = "Starburst Galaxy";
  1         2  
755 1         8 ${$self->{LOOKUP}}{"BCG"} = "Blue compact Galaxy";
  1         2  
756 1         2 ${$self->{LOOKUP}}{"LeI"} = "Gravitationnaly Lensed Image";
  1         3  
757 1         2 ${$self->{LOOKUP}}{"LeG"} = "Gravitationnaly Lensed Image of a Galaxy";
  1         8  
758 1         3 ${$self->{LOOKUP}}{"LeQ"} = "Gravitationnaly Lensed Image of a Quasar";
  1         7  
759 1         2 ${$self->{LOOKUP}}{"AGN"} = "Active Galaxy Nucleus";
  1         3  
760 1         2 ${$self->{LOOKUP}}{"LIN"} = "LINER-type Active Galaxy Nucleus";
  1         3  
761 1         1 ${$self->{LOOKUP}}{"SyG"} = "Seyfert Galaxy";
  1         3  
762 1         3 ${$self->{LOOKUP}}{"Sy1"} = "Seyfert 1 Galaxy";
  1         69  
763 1         2 ${$self->{LOOKUP}}{"Sy2"} = "Seyfert 2 Galaxy";
  1         3  
764 1         2 ${$self->{LOOKUP}}{"Bla"} = "Blazar";
  1         2  
765 1         2 ${$self->{LOOKUP}}{"BLL"} = "BL Lac - type object";
  1         3  
766 1         1 ${$self->{LOOKUP}}{"OVV"} = "Optically Violently Variable object";
  1         3  
767 1         2 ${$self->{LOOKUP}}{"QSO"} = "Quasar";
  1         3  
768              
769             # CONFIGURE FROM ARGUMENTS
770             # -------------------------
771              
772             # return unless we have arguments
773 1 50       11 return undef unless @_;
774              
775             # grab the argument list
776 1         13 my %args = @_;
777              
778             # Loop over the allowed keys and modify the default query options, note
779             # that due to the order these are called in supplying both and RA and Dec
780             # and an object Identifier (e.g. HT Cas) will cause the query to default
781             # to using the identifier rather than the supplied co-ordinates.
782 1         3 for my $key (qw / RA Dec Target Error Units Frame Epoch Equinox
783             Proxy Timeout URL / ) {
784 11         14 my $method = lc($key);
785 11 100       44 $self->$method( $args{$key} ) if exists $args{$key};
786             }
787              
788             }
789              
790             # T I M E A T T H E B A R --------------------------------------------
791              
792             =back
793              
794             =begin __PRIVATE_METHODS__
795              
796             =head2 Private methods
797              
798             These methods are for internal use only.
799              
800             =over 4
801              
802             =item B<_make_query>
803              
804             Private function used to make an SIMBAD query. Should not be called directly,
805             since it does not parse the results. Instead use the querydb() assessor method.
806              
807             =cut
808              
809             sub _make_query {
810 1     1   2 my $self = shift;
811              
812             # grab the user agent
813 1         2 my $ua = $self->{USERAGENT};
814              
815             # clean out the buffer
816 1         3 $self->{BUFFER} = "";
817              
818             # grab the base URL
819 1         12 my $URL = $self->queryurl();
820            
821             # build request
822 1         11 my $request = new HTTP::Request('GET', $URL);
823              
824             # grab page from web
825 1         11647 my $reply = $ua->request($request);
826              
827 1 50       519178 if ( ${$reply}{"_rc"} eq 200 ) {
  1         8  
828             # stuff the page contents into the buffer
829 1         3 $self->{BUFFER} = ${$reply}{"_content"};
  1         76  
830             } else {
831 0         0 $self->{BUFFER} = undef;
832 0         0 croak("Error ${$reply}{_rc}: Failed to establish network connection");
  0         0  
833             }
834             }
835              
836             =item B<_parse_query>
837              
838             Private function used to parse the results returned in an SIMBAD query. Should
839             not be called directly. Instead use the querydb() assessor method to make and
840             parse the results.
841              
842             =cut
843              
844             sub _parse_query {
845 1     1   2 my $self = shift;
846 1         17 my $tree = HTML::TreeBuilder->new_from_content($self->{BUFFER});
847 1         317771 $tree->elementify();
848 1         143 my $result;
849 1 50       8 if ($self->use_list_query()) {
850 1         7 $result = $self->_parse_list_query($tree);
851             } else {
852 0         0 $result = $self->_parse_object_query($tree);
853             }
854 0         0 $tree->delete(); # yes, this is necessary
855 0         0 return $result;
856             }
857              
858             =item B<_parse_list_query>
859              
860             Private method to parse the results of a list query. Should not be called
861             directly. Instead use the querydb() assessor method to make and parse the
862             results.
863              
864             =cut
865              
866             sub _parse_list_query {
867 1     1   2 my $self = shift;
868 1         2 my $tree = shift;
869              
870 1         8 my $pretag = $tree->find_by_tag_name('pre'); # find the
 element 
871 1         4571 my $idtext = decode_entities($pretag->as_HTML());
872 0         0 chomp($idtext);
873              
874 0         0 my @buffer = split( /\n/, $idtext);
875              
876             # create an Astro::SIMBAD::Result object to hold the search results
877 0         0 my $result = new Astro::SIMBAD::Result();
878              
879             # loop round the returned buffer
880 0         0 foreach my $linepos (2 .. $#buffer-1) {
881 0         0 my $starline = $buffer[$linepos];
882              
883             # create a temporary place holder object
884 0         0 my $object = new Astro::SIMBAD::Result::Object();
885            
886             # split each line using the "pipe" symbol separating the table columns
887 0         0 my @separated = split( /\|/, $starline );
888            
889              
890 0         0 $self->_insert_query_params($object);
891            
892             # URL
893             # ---
894            
895             # grab the url based on quotes around the string
896 0         0 my $start_index = index( $separated[0], q/"/ );
897 0         0 my $last_index = rindex( $separated[0], q/"/ );
898 0         0 my $url = substr( $separated[0], $start_index+1,
899             $last_index-$start_index-1);
900              
901             # push it into the object
902 0         0 $object->url( $url );
903            
904             # NAME
905             # ----
906            
907             # get the object name from the same section
908 0         0 my $final_index = rindex( $separated[0], "<" ) - 1;
909 0         0 my $name = substr($separated[0],$last_index+2,$final_index-$last_index-1);
910            
911             # push it into the object
912 0         0 $object->name( $name );
913            
914             # TYPE
915             # ----
916 0         0 my $type = trim($separated[1]);
917            
918             # push it into the object
919 0         0 $object->type( $type );
920            
921             # LONG TYPE
922             # ---------
923            
924             # do the lookup
925 0         0 for my $key (keys %{$self->{LOOKUP}}) {
  0         0  
926            
927 0 0       0 if( $object->type() eq $key ) {
928            
929             # push it into the object
930 0         0 my $long = ${$self->{LOOKUP}}{$key};
  0         0  
931 0         0 $object->long( $long );
932 0         0 last;
933             }
934             }
935            
936             # RA and DEC
937 0         0 my ($ra, $dec) = $self->_coordinates($separated[2]);
938 0         0 $object->ra($ra);
939 0         0 $object->dec($dec);
940            
941             # B, V magnitudes; field may contain none, one or both
942 0         0 my ($bmag, $vmag) = split /\s+/, trim($separated[3]);
943 0 0 0     0 if ($bmag && $bmag ne ":") {
944 0         0 $object->bmag($bmag);
945             }
946 0         0 $object->vmag($vmag);
947            
948             # SPECTRAL TYPE
949             # -------------
950 0         0 my $spectral = trim($separated[4]);
951            
952             # push it into the object
953 0         0 $object->spec($spectral);
954            
955             # Add the target object to the Astro::SIMBAD::Result object
956             # ---------------------------------------------------------
957 0         0 $result->addobject( $object );
958             }
959            
960             # return an Astro::SIMBAD::Result object, or undef if no abstracts returned
961 0         0 return $result;
962             }
963              
964             =item B<_parse_object_query>
965              
966             Private method to parse the results of an object query. Should not be called
967             directly. Instead use the querydb() assessor method to make and parse the
968             results.
969              
970             =cut
971              
972             sub _parse_object_query {
973 0     0   0 my $self = shift;
974 0         0 my $tree = shift;
975              
976 0         0 my $result = new Astro::SIMBAD::Result();
977 0         0 my $object = new Astro::SIMBAD::Result::Object();
978              
979             # The object's detail URL is the query URL
980 0         0 $object->url($self->queryurl());
981              
982             # Find the tag named lab_basic1
983 0     0   0 my $basic_anchor = $tree->look_down("_tag", "a", sub { $_[0]->attr("name") eq "lab_basic1"} );
  0         0  
984              
985             # Under lab_basic1, find the table cell containing name and long description
986 0     0   0 my $objtitle = $basic_anchor->look_down("_tag", "td", sub { $_[0]->as_text() =~ /^Basic data :/ })->as_text();
  0         0  
987 0         0 my ($label, $name, $long) = split /:|--/, $objtitle;
988 0         0 $object->name($name);
989 0         0 $object->long($long);
990              
991             # "Basic data" table
992 0     0   0 my $bdtable = $basic_anchor->look_down("_tag", "table", sub { $_[0]->attr("cols") eq "3" });
  0         0  
993              
994             # Grab the left-hand column of table cells
995 0     0   0 my @bdlabels = $bdtable->look_down("_tag", "td", sub { $_[0]->right() });
  0         0  
996              
997 0         0 my %basic_data = {};
998 0         0 foreach my $bdlabel (@bdlabels) {
999 0         0 my $key = trim($bdlabel->as_text());
1000 0         0 my $value = trim($bdlabel->right()->as_text());
1001 0         0 $basic_data{$key} = $value;
1002             }
1003              
1004 0         0 $self->_insert_query_params($object);
1005              
1006             # Set RA and DEC
1007 0         0 my @coord_types = ( ["ICRS", 2000, 2000, "ICRS 2000.0 coordinates"],
1008             ["FK5", 2000, 2000, "FK5 2000.0/2000.0 coordinates"],
1009             ["FK4", 1950, 1950, "FK4 1950.0/1950.0 coordinates"],
1010             );
1011 0         0 foreach my $row (@coord_types) {
1012 0 0       0 if (join('*', @{$row}[0..2]) eq join('*', $object->frame())) {
  0         0  
1013 0         0 $label = @{$row}[3];
  0         0  
1014 0         0 my $coord_string = $basic_data{$label};
1015 0         0 my ($ra, $dec) = $self->_coordinates($coord_string);
1016 0         0 $object->ra($ra);
1017 0         0 $object->dec($dec);
1018 0         0 last;
1019             }
1020             }
1021              
1022             # Spectral type
1023 0         0 $object->spec($basic_data{"Spectral type"});
1024              
1025             # B, V magnitudes
1026 0         0 my ($bmag, $vmag) = split ',', $basic_data{"B magn, V magn, Peculiarities"};
1027 0         0 $object->bmag($bmag);
1028 0         0 $object->vmag($vmag);
1029              
1030             # Proper motion
1031 0 0       0 if ((my $pm = $basic_data{"Proper motion (mas/yr) [error ellipse]"})) {
1032 0         0 $object->pm(split /\s+/, $pm);
1033             }
1034              
1035             # Parallax
1036 0 0       0 if ((my $plx = $basic_data{"Parallaxes (mas)"})) {
1037 0         0 $object->plx(split /\s+/, $plx);
1038             }
1039              
1040             # Radial velocity/redshift
1041 0 0       0 if ((my $rvterm = $basic_data{"Radial velocity (v:Km/s) or Redshift (z)"})) {
1042 0         0 my ($type, $mag) = split /\s+/, $rvterm;
1043 0 0       0 if ($type eq "v") {
    0          
1044 0         0 $object->radial($mag);
1045             } elsif ($type eq "z") {
1046 0         0 $object->redshift($mag);
1047             }
1048             }
1049              
1050             # Build an array of designations for this object
1051 0         0 my @idents;
1052             # Find the
 block under the 'lab_ident1' anchor 
1053 0     0   0 my $iptag = $tree->look_down("_tag", "a", sub { $_[0]->attr("name") eq "lab_ident1"} )->find('pre');
  0         0  
1054 0         0 foreach my $idref ($iptag->find("a")) {
1055 0         0 push @idents, trim($idref->as_text());
1056 0         0 $idref = $idref->right();
1057             }
1058 0         0 $object->ident(\@idents);
1059              
1060 0         0 $result->addobject( $object );
1061 0         0 return $result;
1062             }
1063              
1064             =item B<_insert_query_params>
1065              
1066             Copies frame, epoch and equinox and target from the query params into
1067             the result object.
1068              
1069             =cut
1070             sub _insert_query_params {
1071 0     0   0 my $self = shift;
1072 0         0 my $object = shift;
1073              
1074             # FRAME
1075             # -----
1076            
1077             # grab the current co-ordinate frame from the query object itself
1078 0         0 my @coord_frame = ( ${$self->{OPTIONS}}{"CooFrame"},
  0         0  
1079 0         0 ${$self->{OPTIONS}}{"CooEpoch"},
1080 0         0 ${$self->{OPTIONS}}{"CooEqui"} );
1081             # push it into the object
1082 0         0 $object->frame( \@coord_frame );
1083              
1084             # TARGET
1085 0         0 $object->target($self->target());
1086             }
1087              
1088             =item B<_update_nbident>
1089              
1090             If the search is for a specific object and the radius is 0, do a detailed
1091             (i.e., object) query, rather than a more general list (summary) query
1092             that is expected to return multiple results.
1093              
1094             =cut
1095             sub _update_nbident {
1096 1     1   2 my $self = shift;
1097 1 50       4 if ($self->use_list_query()) {
1098 1         2 ${$self->{OPTIONS}}{"NbIdent"} = "around";
  1         4  
1099             } else {
1100 0           ${$self->{OPTIONS}}{"NbIdent"} = "1";
  0            
1101             }
1102             }
1103              
1104             =item B<_coordinates>
1105              
1106             Private function used to split a coordinate line into RA and DEC values
1107              
1108             =cut
1109             sub _coordinates {
1110 0     0     my $self = shift;
1111              
1112             # RA
1113             # --
1114            
1115 0           my $coords = trim(shift);
1116            
1117             # split the RA and Dec line into an array elements
1118 0           my @radec = split( /\s+/, $coords );
1119            
1120             # ...and then rebuild it
1121 0           my $ra;
1122 0 0 0       unless( $radec[2] =~ '\+' || $radec[2] =~ '-' ) {
1123 0           $ra = "$radec[0] $radec[1] $radec[2]";
1124             } else {
1125 0           $ra = "$radec[0] $radec[1] 00.0";
1126             }
1127            
1128            
1129             # DEC
1130             # ---
1131            
1132             # ...and rebuild the Dec
1133 0           my $dec;
1134 0 0 0       unless ( $radec[2] =~ '\+' || $radec[2] =~ '-' ) {
1135 0           $dec = "$radec[3] $radec[4] $radec[5]";
1136             } else {
1137 0           $dec = "$radec[2] $radec[3] 00.0";
1138             }
1139              
1140 0           return ($ra, $dec);
1141             }
1142              
1143             =item B<_dump_raw>
1144              
1145             Private function for debugging and other testing purposes. It will return
1146             the raw output of the last SIMBAD query made using querydb().
1147              
1148             =cut
1149              
1150             sub _dump_raw {
1151 0     0     my $self = shift;
1152            
1153             # split the BUFFER into an array
1154 0           my @portable = split( /\n/,$self->{BUFFER});
1155 0           chomp @portable;
1156              
1157 0           return @portable;
1158             }
1159              
1160             =item B<_dump_options>
1161              
1162             Private function for debugging and other testing purposes. It will return
1163             the current query options as a hash.
1164              
1165             =cut
1166              
1167             sub _dump_options {
1168 0     0     my $self = shift;
1169              
1170 0           return %{$self->{OPTIONS}};
  0            
1171             }
1172              
1173             =back
1174              
1175             =end __PRIVATE_METHODS__
1176              
1177             =head1 COPYRIGHT
1178              
1179             Copyright (C) 2001 University of Exeter. All Rights Reserved.
1180              
1181             This program was written as part of the eSTAR project and is free software;
1182             you can redistribute it and/or modify it under the terms of the GNU Public
1183             License.
1184              
1185             =head1 AUTHORS
1186              
1187             Alasdair Allan Eaa@astro.ex.ac.ukE,
1188              
1189             =cut
1190              
1191             # L A S T O R D E R S ------------------------------------------------------
1192              
1193             1;