Source code for momxml.targetsource

r'''
Specification of target sources to use in Observation Beams.
'''

from lofarobsxml.angles import Angle
import sys
import urllib
if sys.version_info[0] > 2:
    import urllib.request as request

[docs]class NoSimbadCoordinatesError(RuntimeError): r''' Raised if the Simbad response does not contain J2000 coordinates. '''
[docs]class SourceSpecificationError (ValueError): r''' Raised in case of badly specified TargetSource. '''
[docs]class TargetSource(object): r''' A target source to be used when specifying a Beam within an Observation. **Parameters** name : non-unicode string Contains the name of the source. ra_angle : None or an Angle J2000 right ascension. dec_angle : None or an Angle J2000 declination. reference_frame : string Reference frame for the longitudinal (ra/az/lon) and latitudinal (dec/el/lat) coordinates. Examples: 'J2000', 'B1950', 'AZELGEO', 'AZEL', 'GALACTIC', 'JMEAN', JTRUE', etc... Basically anything supported by Casacore. Default: 'J2000' **Raises** SourceSpecificationError In case of badly specified TargetSource. **Examples** >>> TargetSource('Cyg A', ... ra_angle = Angle(shms = ('+', 19, 59, 28.3565)), ... dec_angle = Angle(sdms = ('+', 40, 44, 2.099)) ) TargetSource(name = 'Cyg A', ra_angle = Angle(shms = ('+', 19, 59, 28.3565)), dec_angle = Angle(sdms = ('+', 40, 44, 2.099))) ''' def __init__(self, name = '', ra_angle = None, dec_angle = None, reference_frame='J2000'): self.name = name self.ra_angle = ra_angle self.dec_angle = dec_angle self.reference_frame = reference_frame self.validate_and_normalize()
[docs] def validate_and_normalize(self): r''' Validates type and contents of data members. This method is called by the constructor. **Returns** A reference to ``self``. **Raises** SourceSpecificationError In case of a badly specified target source. **Examples** >>> TargetSource('Cyg A', ... ra_angle = Angle(shms = ('+', 19, 59, 28.3565)), ... dec_angle = Angle(sdms = ('+', 40, 44, 2.099)) ) TargetSource(name = 'Cyg A', ra_angle = Angle(shms = ('+', 19, 59, 28.3565)), dec_angle = Angle(sdms = ('+', 40, 44, 2.099))) # >>> TargetSource(u'Cyg A', # ... ra_angle = Angle(shms = ('+', 19, 59, 28.3565)), # ... dec_angle = Angle(sdms = ('+', 40, 44, 2.099)) ) # Traceback (most recent call last): # ... # lofarobsxml.targetsource.SourceSpecificationError: Source name may not be a unicode string. >>> TargetSource('Cyg A', ... ra_angle = 3.0, ... dec_angle = Angle(sdms = ('+', 40, 44, 2.099)) ) Traceback (most recent call last): ... lofarobsxml.targetsource.SourceSpecificationError: ra_angle must be a lofarobsxml.Angle, not 3.0 >>> TargetSource('Cyg A', ... ra_angle = Angle(shms = ('+', 19, 59, 28.3565)), ... dec_angle = -2) Traceback (most recent call last): ... lofarobsxml.targetsource.SourceSpecificationError: dec_angle must be a lofarobsxml.Angle, not -2 ''' # Named tuple was introduced in Python 2.7 # In python 2.7 use sys.version_info.major if sys.version_info[0] == 2: if type(self.name) == type(u''): raise SourceSpecificationError( 'Source name may not be a unicode string.') if type(self.name) != type(''): raise SourceSpecificationError( 'Source name must be a string. You specified %s' % (str(self.name),)) if self.ra_angle.__class__.__name__ != 'Angle': raise SourceSpecificationError( 'ra_angle must be a lofarobsxml.Angle, not %r' % self.ra_angle) if self.dec_angle.__class__.__name__ != 'Angle': raise SourceSpecificationError( 'dec_angle must be a lofarobsxml.Angle, not %r' % self.dec_angle) return self
[docs] def ra_deg(self): r''' Return right ascension in degrees **Returns** A float. **Examples** >>> TargetSource('Cyg A', ... ra_angle = Angle(deg = 299.868152), ... dec_angle = Angle(deg = 40.733916) ).ra_deg() 299.868152 ''' return self.ra_angle.as_deg()
[docs] def dec_deg(self): r''' Return declination in degrees **Returns** A float. **Examples** >>> TargetSource('Cyg A', ... ra_angle = Angle(deg = 299.868152), ... dec_angle = Angle(deg = 40.733916) ).dec_deg() 40.733916 ''' return self.dec_angle.as_deg()
[docs] def ra_dec_rad(self): r''' Returns coordinates as an (ra_rad, dec_rad) pair of floats. **Examples** >>> '(%.6f, %.6f)' % TargetSource('Cyg A', ... ra_angle = Angle(deg = 299.868152), ... dec_angle = Angle(deg = 40.733916) ).ra_dec_rad() '(5.233687, 0.710941)' ''' return (self.ra_angle.as_rad(), self.dec_angle.as_rad())
def __repr__(self): return ('''TargetSource(name = %r, ra_angle = Angle(shms = %r), dec_angle = Angle(sdms = %r))''' % (self.name, self.ra_angle.as_shms()[0:3] + (float('%7.4f' % self.ra_angle.as_shms()[-1]),), self.dec_angle.as_sdms()[0:3] + (float('%7.4f' % self.dec_angle.as_sdms()[-1]),)))
[docs]def target_source_from_simbad_response(source_name, simbad_response): r''' **Examples** >>> simbad_response = open('examples/simbad-ngc891.txt').read() >>> target_source_from_simbad_response('NGC 891', simbad_response) TargetSource(name = 'NGC 891', ra_angle = Angle(shms = ('+', 2, 22, 32.907)), dec_angle = Angle(sdms = ('+', 42, 20, 53.95))) >>> simbad_trifid = open('examples/simbad-trifid.txt').read() >>> target_source_from_simbad_response('Trifid Nebula', simbad_trifid) TargetSource(name = 'Trifid Nebula', ra_angle = Angle(shms = ('+', 18, 2, 42.0)), dec_angle = Angle(sdms = ('-', 22, 58, 18.0))) >>> simbad_ncp = open('examples/simbad-ncp.txt').read() >>> target_source_from_simbad_response('NCP', simbad_ncp) TargetSource(name = 'NCP', ra_angle = Angle(shms = ('+', 0, 0, 0.0)), dec_angle = Angle(sdms = ('+', 90, 0, 0.0))) ''' coordinate_lines = [line for line in simbad_response.split('\n') if 'Coordinates(ICRS,ep=J2000,eq=2000)' in line] if len(coordinate_lines) > 0: words = coordinate_lines[0].split() ra_hms = [float(number) for number in words[1:4]] ra_angle = Angle(hms = ra_hms) if words[6][0] in '0123456789': dec_sdms = (words[4][0], float(words[4][1:]), float(words[5]), float(words[6])) else: dec_sdms = (words[4][0], float(words[4][1:]), float(words[5]), 0.0) dec_angle = Angle(sdms = dec_sdms) return TargetSource(name = source_name, ra_angle = ra_angle, dec_angle = dec_angle) else: raise NoSimbadCoordinatesError('No J2000 coordinates in %s' % simbad_response)
[docs]def simbad(source_name, debug = False): r''' Lookup ``source_name`` on simbad and return a TargetSource instance. **Examples** >>> simbad('3C 196') TargetSource(name = '3C 196', ra_angle = Angle(shms = ('+', 8, 13, 36.0561)), dec_angle = Angle(sdms = ('+', 48, 13, 2.636))) ''' query = '&'.join([ 'http://simbad.u-strasbg.fr/simbad/sim-id?output.format=ASCII', 'obj.coo1=on', 'obj.coo2=off', 'obj.coo3=off', 'obj.coo4=off', 'frame1=ICRS', 'epoch1=J2000', 'equi1=2000', 'obj.pmsel=off', 'obj.plxsel=off', 'obj.rvsel=off', 'obj.spsel=off', 'obj.mtsel=off', 'obj.sizesel=off', 'obj.fluxsel=off', 'obj.bibsel=off', 'obj.messel=off', 'obj.notesel=off', 'Ident=%s']) if sys.version_info[0] == 2: result = urllib.urlopen(query % urllib.quote(source_name), proxies = {}).read() else: result = request.urlopen(query % urllib.parse.quote(source_name)).read().decode('utf8') if debug: print(result) sys.stdout.flush() else: return target_source_from_simbad_response(source_name, result)