Source code for pywwt.windows.utils

import csv
import sys
import codecs
import struct
from datetime import datetime, timedelta

import numpy as np
import matplotlib.cm as mcm
from matplotlib.colors import LogNorm, Normalize
from astropy.utils.console import ProgressBar
from dateutil import tz, parser

__all__ = ['map_array_to_colors', 'generate_utc_times',
           'convert_xyz_to_spherical', 'write_data_to_csv']


[docs] def map_array_to_colors(arr, cmap, scale="linear", vmin=None, vmax=None): """ Map a NumPy array to a colormap using Matplotlib. Parameters ---------- array : `numpy.ndarray` The array to be mapped onto a colormap. cmap : `str` The name of a Matplotlib colormap. scale : {'linear' | 'log'}, optional The scaling of the data as mapped to the colormap. vmin : `float`, optional The value associated with the low end of the colormap. By default this is the minimum value of ``arr``. vmax : `float`, optional The value associated with the high end of the colormap. By default this is the maximum value of ``arr``. Returns ------- colors : `list` A list of colors, encoded in ARGB hex values. """ if vmin is None: vmin = arr.min() if vmax is None: vmax = arr.max() if scale == "linear": norm = Normalize(vmin=vmin, vmax=vmax) elif scale == "log": norm = LogNorm(vmin=vmin, vmax=vmax) my_cmap = mcm.ScalarMappable(norm=norm, cmap=cmap) colors = my_cmap.to_rgba(arr, bytes=True) hex_colors = [] for color in colors: hex_color = codecs.getencoder('hex')(struct.pack('BBB', *color[:3]))[0] hex_colors.append("FF" + hex_color.decode().upper()) return hex_colors
[docs] def generate_utc_times(num_steps, step_size, start_time=None): """ Generate a series of equally linearly spaced times in UTC. Parameters ---------- num_steps : `int` The number of times to generate. step_size : `dict` A dictionary corresponding to the step size between the times, with keys referring to the unit (seconds, minutes, days, etc.) and the values of the step in that unit. start_date : `str`, optional A string corresponding to a time in the local time zone at which to start the timesteps. Default: the current system time. Acceptable formats (month/day/year): ``"1/1/2010 11:00:00 PM"``, ``"1/1/2010 11:30 AM"``, ``"1/1/2010 11 am"``, ``"1/1/2000"``, ``"1/2000"``, Returns ------- times : `list` A list of formatted date/time strings in UTC readable by WorldWide Telescope. """ if start_time is None: start_time = datetime.utcnow() else: start_time = parser.parse(start_time) utc_zone = tz.tzutc() local_zone = tz.tzlocal() # Tell the datetime object that it's in local time zone since # datetime objects are 'naive' by default local_time = start_time.replace(tzinfo=local_zone) # Convert time to UTC start_time = local_time.astimezone(utc_zone) time_arr = [] new_time = start_time for i in range(num_steps): time_arr.append(new_time.strftime("%m/%d/%Y %I:%M:%S %p")) new_time += timedelta(**step_size) return time_arr
[docs] def convert_xyz_to_spherical(x, y, z, is_astro=True, ra_units="degrees"): """ Convert rectangular coordinates (x,y,z) to spherical coordinates (Lat, Lon, Alt) or (RA, Dec, Alt). Parameters ---------- x : `numpy.ndarray` The x-coordinates of the data. y : `numpy.ndarray` The y-coordinates of the data. z : `numpy.ndarray` The z-coordinates of the data. is_astro : `bool`, optional Whether the coordinate system is astronomical (RA, Dec) or geographical (Lat, Lon)? ra_units : {'degrees', 'hours'}, optional The unit of the RA/Lon coordinate. Returns ------- spherical : `dict` A dict of NumPy arrays corresponding to the positions in spherical coordinates. """ if ra_units == "degrees" or not is_astro: ra_scale = 1. elif ra_units == "hours": ra_scale = 24. / 360. if is_astro: ra_name = "RA" dec_name = "DEC" else: ra_name = "LON" dec_name = "LAT" coords = {} coords["ALT"] = np.sqrt(x * x + y * y + z * z) coords[ra_name] = (np.rad2deg(np.arctan2(y, x)) + 180.) * ra_scale coords[dec_name] = np.rad2deg(np.arccos(z / coords["ALT"])) - 90. return coords
[docs] def write_data_to_csv(data, filename, mode="new"): """ Write a dataset to a CSV-formatted file with a data header. Parameters ---------- data : `dict` The data to be written as a dictionary of NumPy arrays filename : `str` The filename to write the data to. mode : {'new', 'append'}, optional Write a "new" file or "append" to an existing file? """ if mode == "new": fmode = "w" elif mode == "append": fmode = "a+" if sys.version_info >= (3, 0, 0): f = open(filename, fmode, newline='') else: f = open(filename, fmode + 'b') w = csv.DictWriter(f, list(data.keys())) if mode == "new": w.writeheader() num_points = len(list(data.values())[0]) for i in ProgressBar(list(range(num_points))): row = dict([(k, v[i]) for k, v in list(data.items())]) w.writerow(row) f.close()