Source code for irfpy.cena.intersection

''' Calculate the CENA FoV cross-section on the Moon's map
'''

import datetime
import logging

import numpy as np

from irfpy.util.intersection import los_sphere
from irfpy.util import intersection as _intersection

from irfpy.cy1orb import lseme
import irfpy.cy1orb.pvat2 as pvat

from irfpy.cena import frame
from irfpy.cena import fov

_logger = logging.getLogger(__name__)

[docs]def get_center_me(t, dir, as_vector=False): ''' Get the intersection between the given pixel and the surface. Returns the intersection between the given pixel ``dir`` and the lunar surface. ME frame is used. :param t: Time in ``datetime.datetime`` instance. :type t: ``datetime.datetime`` :param dir: Direction number. 0 to 6. :type dir: ``int`` :keyword as_vector: If ``True``, return as a vector in ME frame. :type as_vector: ``boolean`` :returns: If ``as_vector`` is ``True``, the ``numpy.array`` instance with (``x``, ``y``, ``z``) is returned. Otherwise (default), A list of [``longitude (deg)``, ``latitude (deg)``] will be returned. Note that the Moon is assumed to be a sphere with 1738 km radius here. This is just a geometric vector calculation, and no SPICE is used. >>> t = datetime.datetime(2009, 1, 31, 3, 25, 17) >>> lon, lat = get_center_me(t, 4) >>> print('%.1f' % lon) 69.9 >>> print('%.1f' % lat) 62.5 >>> lon, lat = get_center_me(t, 0) >>> print('%.1f' % lon) 85.1 >>> print('%.1f' % lat) 62.3 >>> lon, lat = get_center_me(t, 6) >>> print('%.1f' % lon) 59.8 >>> print('%.1f' % lat) 62.2 ''' scpos_me = pvat.getmepos(t, as_vector=True) _logger.debug('sc = %s' % str(scpos_me)) _logger.debug('ELEV = %f, AZIM = %f' % (fov.elev_pix_center(dir), fov.azim_pix_center(dir))) cenaarms = frame.angles2cena(fov.elev_pix_center(dir), fov.azim_pix_center(dir), degrees=True) _logger.debug('Arm = %s' % str(cenaarms)) arms_sc = frame.cena2sc(cenaarms) arms_lse = pvat.getlsevec(t, arms_sc) arms_me = lseme.lse2me(t, arms_lse) arms_me = np.array(arms_me) _logger.debug('Arm [ME] = %s' % str(arms_me)) los = los_sphere(scpos_me, arms_me, np.array([0, 0, 0]), 1738.) if los is None: if as_vector: return np.array([3]) + np.nan else: return [np.nan, np.nan] los = np.array([los[0], los[1], los[2]]) if as_vector: return los len = np.sqrt((los ** 2).sum()) los = los / len lat = np.arcsin(los[2]) * 180. / np.pi lon = np.arctan2(los[1], los[0]) * 180. / np.pi return [lon, lat]
[docs]def in_cena_fov(t, me_lon, me_lat): """ Return if the given position is in CENA's FOV or not :param t: Time :param me_lon: Longitude of surface position, deg :param me_lat: Latitude of surface position, deg :returns: *True* if (me_lon, me_lat) is in CENA'f FOV >>> print(in_cena_fov(datetime.datetime(2009, 4, 15, 2, 22, 59), 177.5, -45.5)) # False False >>> print(in_cena_fov(datetime.datetime(2009, 4, 15, 2, 26, 19), 177.5, -45.5)) # True True """ t2 = t # Alias lon0 = np.deg2rad(me_lon) lat0 = np.deg2rad(me_lat) pos_surf_me = np.array([np.cos(lon0) * np.cos(lat0), np.sin(lon0) * np.cos(lat0), np.sin(lat0)]) * 1738 pos_surf_lse2 = lseme.me2lse(t2, pos_surf_me) pos_sc_lse2 = pvat.getlsepos(t2, asarray=True) if not _intersection.isvisible(pos_sc_lse2, pos_surf_lse2, [0, 0, 0], 1738): _logger.debug('Backside of Moon') return False dir_sc2surf_lse2 = pos_surf_lse2 - pos_sc_lse2 dir_sc2surf_sc2 = pvat.lse2sc(t2, dir_sc2surf_lse2) dir_sc2surf_cena2 = frame.sc2cena(dir_sc2surf_sc2) cena_theta2, cena_phi2 = frame.cena2angles(dir_sc2surf_cena2, degrees=True) _logger.debug('Theta_CENA={}'.format(cena_theta2)) _logger.debug('Phi_CENA={}'.format(cena_phi2)) return fov.infov(cena_theta2, cena_phi2)