"""This module implements the position calculation functions""" import datetime import time from math import sin, cos, tan, atan2, degrees, isclose from IRAPy import logger from Acspy.Common.TimeHelper import getTimeStamp class PosGenerator(object): def __init__(self, updatingTime, trackingLeadTime): self.updatingTime = updatingTime self.trackingLeadTime = trackingLeadTime self.mapping = { 'parallactic': { 'getAngleFunction': PosGenerator.getParallacticAngle, 'coordinateFrame': 'horizontal' }, 'galacticParallactic': { 'getAngleFunction': PosGenerator.getGalacticParallacticAngle, 'coordinateFrame': 'equatorial' }, } def goto(self, iStaticPos): yield iStaticPos def parallactic(self, source, siteInfo, t): """Return the parallactic angle""" latitude = PosGenerator.getLatitude(siteInfo) try: coordinates = source.getApparentCoordinates(t) # Values in radians az, el = coordinates[:2] # The first two elements are (az, el) position = PosGenerator.getParallacticAngle(latitude, az, el) return position except Exception as ex: raeson = 'cannot get the %s (az, el) values' %source._get_name() logger.logNotice('%s: %s' %(raeson, ex)) raise PosGeneratorError(raeson) def galacticParallactic(self, source, siteInfo, t): """Return the galactic parallactic angle""" latitude = PosGenerator.getLatitude(siteInfo) try: coordinates = source.getApparentCoordinates(t) # Values in radians az, el, ra, dec = coordinates[:4] position = PosGenerator.getGalacticParallacticAngle(latitude, az, el, ra, dec) return position except Exception as ex: raeson = 'cannot get the %s (az, el) values' %source._get_name() logger.logNotice('%s: %s' %(raeson, ex)) raise PosGeneratorError(raeson) @staticmethod def getLatitude(siteInfo): """Return the site latitude""" try: return siteInfo['latitude'] except (KeyError, TypeError) as ex: raise PosGeneratorError('cannot get the latitude: %s' %ex) except Exception as ex: raeson = 'unexpected exception getting the site latitude' logger.logNotice(raeson) raise PosGeneratorError(raeson) @staticmethod def getParallacticAngle(latitude, az, el): """Arguments in radians""" denominator = tan(latitude) * cos(el) - sin(el) * cos(az) # Avoid division by zero and keep continuity if isclose(denominator, 0, abs_tol=1e-10): return -90.0 if sin(az) > 0 else 90.0 return degrees(atan2(-sin(az), denominator)) @staticmethod def getGalacticAngle(ra, dec): """Arguments in radians""" # North celestial pole coordinates in equatorial celestial frame (j2000) # ncp = ('12 51 26.28', '27 07 41.7') # ra0 = ephem.hours(ncp[0]) # dec0 = ephem.degrees(ncp[1]) ra0 = 3.3660332687500043 dec0 = 0.47347728280415174 denominator = cos(dec) * tan(dec0) - sin(dec) * cos(ra-ra0) # Avoid division by zero and keep continuity if isclose(denominator, 0, abs_tol=1e-10): return 90.0 if sin(ra-ra0) > 0 else -90.0 return degrees(atan2(sin(ra-ra0), denominator)) @staticmethod def getGalacticParallacticAngle(latitude, az, el, ra, dec): """Arguments in radians""" p = PosGenerator.getParallacticAngle(latitude, az, el) g = PosGenerator.getGalacticAngle(ra, dec) return p + g class PosGeneratorError(Exception): pass