Using the Windows client

About

The pywwt.windows sub-package includes a Python interface for the Microsoft WorldWide Telescope (WWT) Windows client, using the Layer Control API (LCAPI). The LCAPI provides an interface to WWT’s Layer Manager by sending data and information in the form of strings over HTTP. pywwt simply provides a Python interface to make these calls, enabling the control of WWT from scripts or an IPython notebook. Most importantly, it enables the passing of data created within a Python environment to WWT.

Note

The pywwt package was originally developed as a client for the Windows WorldWideTelescope application. For now, the API for the Windows is identical to that in previous versions, with the exception that imports of the WWTClient class should be changed from:

from pywwt import WWTClient

to:

from pywwt.windows import WWTWindowsClient

For now, the API remains identical to previous versions, and is different from the API for the Jupyter and Qt widgets. In future, we will align the API of the Windows client on the Jupyter and Qt widgets.

Using the Windows client

The Windows client is imported using:

from pywwt.windows import WWTWindowsClient

Connecting to the WWT application

Connecting to a running WWT application on the current host is as simple as creating a WWTWindowsClient instance:

wwt = WWTWindowsClient()

If WWT is running on a separate host, and you have enabled access from remote hosts, you can connect to it by specifying the hostname or IP address:

wwt = WWTWindowsClient(host="192.168.1.3")

If the WWT client has not been started on the host you are attempting to connect to, or if you have not enabled remote access, or if the firewall is blocking port 5050 on the host, you may get one of the following error messages:

WWTException: WorldWide Telescope has not been started on this host or is
otherwise unreachable.

WWTException: Error - IP Not Authorized by Client

If the version of WWT is not the required version, you will get this error message:

WWTException: WorldWide Telescope is not the required version (>= 2.8)

Note

Some tasks require loading files from disk. These will currently only work if the current WWTWindowsClient instance and the WWT client itself are running on the same host.

Creating New Layers

The heart of WWTWindowsClient (and the LCAPI) is the interaction with WWT’s Layer Manager. Layers contain data in WWT. There are three ways to create new layers from a WWTWindowsClient instance.

load

You can use the load() method to generate a new layer with data uploaded from a file:

layer = wwt.load("particles.csv", "Sun", "Vulcan")

where the file in this case is a CSV file with values separated by commas or tabs. The second two arguments are the frame to load the data into, and the name for the new layer. In addition to CSV files, the load() command shape files (.shp), 3D model files (.3ds), and WTML files containing ImageSet references.

load() takes a number of keyword arguments, which may be used to customize the data in the layer. These include options to control the color, the start and end date of the events, and options to control the fading in and out of data:

layer = wwt.load("particles.csv", "Sun", "Vulcan", color="FFFFFFFF",
                       start_date="1/11/2009 12:00 AM", end_date="12/31/2010 5:00 PM",
                       fade_type="In", fade_range=2)

load() returns a WWTLayer instance.

LCAPI Reference: Load

new_layer

To create a new layer without loading data from a file, use the new_layer() method:

new_layer = wwt.new_layer("Sky", "My Star", ["RA","DEC","ALT","color"])

where the first two arguments are the frame to create the layer and the name of the new layer. The last argument is a list of fields that are the names of the data arrays that will be loaded into the WWTLayer instance using an update() call. new_layer() also takes the same keyword arguments as load().

LCAPI Reference: New

new_layer_group

new_layer_group() creates a new layer group, which is an organizational aid when using the layer manager. The user will be able to collapse and expand groups in the Layer Manager, and have groups that are sub-sets of other groups:

wwt.new_layer_group("Sun", "my asteroids")

The first argument is the reference frame for the group and the second is the name of the group.

LCAPI Reference: Group

get_existing_layer

Finally, to retrieve an already existing layer as a WWTLayer object, call get_existing_layer():

minihalo_layer = wwt.get_existing_layer("minihalo")

Working With Layers

Once a WWTLayer object has been created, there are a number of options for setting the parameters of the layer and working with its data.

update

update() adds data to layers, removes data, and changes other aspects of the layer. The data to be added is a dict of NumPy arrays or lists:

data = {}
data["RA"] = ra_coord
data["DEC"] = dec_coord
data["ALT"] = alt_coord
data["color"] = colors
layer.update(data=data, purge_all=True, no_purge=False, show=True)

Where the keys of the dict must correspond to the names of the fields specified in the new_layer() call that created this layer. purge_all controls whether or not all existing data will be cleared from the layer. Setting no_purge to True will prevent data that has already occurred from being deleted from the layer, which would happen by default. show controls whether the layer is shown or hidden.

LCAPI Reference: Update

activate

The activate() method highlights the selected layer in the layer manager:

layer.activate()

LCAPI Reference: Activate

There are a number of properties associated with each layer, and there are methods for getting and setting these properties. There is a list of properties for layers at the WWT website.

get_property

get_property() returns the value of a property given its property_name:

prop = layer.get_property("CoordinatesType")

LCAPI Reference: Getprop

get_properties

get_properties() returns all of the properties for a layer in a Python dict:

prop_dict = layer.get_properties()

LCAPI Reference: Getprops

set_property

set_property() sets a property with property_name to property_value:

layer.set_property("AltUnit", "MegaParsecs")

The property_name and property_value must both be strings.

LCAPI Reference: Setprop

set_properties

set_properties() sets a number of properties which have been organized into a dict of {property_name,``property_value``} pairs:

props_dict = {"CoordinatesType":"Spherical",
              "MarkerScale":"Screen",
              "PointScaleType":"Constant",
              "ScaleFactor":"16",
              "ShowFarSide":"True",
              "TimeSeries":"False",
              "AltUnit":"MegaParsecs",
              "RaUnits":"Degrees"}
layer.set_properties(props_dict)

Each name and value must be a string.

LCAPI Reference: Setprops

delete

delete() deletes the layer from the Layer Manager:

layer.delete()

If you try to call a method on the associated layer, you will get an error message:

WWTException: This layer has been deleted!

LCAPI Reference: Delete

Other Commands

There are several remaining methods for WWTWindowsClient that may be used to control the appearance of the WWT client and the layers.

change_mode

change_mode() changes the view to one of: Earth, Planet, Sky, Panorama, SolarSystem:

wwt.change_mode("SolarSystem")

LCAPI Reference: Mode

get_frame_list

get_frame_list() returns a dictionary of the WWT client’s reference frames:

frame_list = wwt.get_frame_list()

returns something like:

{'Adrastea': {'Enabled': 'True'},
 'Aegir': {'Enabled': 'True'},
 'Aitne': {'Enabled': 'True'},
 'Albiorix': {'Enabled': 'True'},
 ...
 'Umbriel': {'Enabled': 'True'},
 'Uranus': {'Enabled': 'True'},
 'Venus': {'Enabled': 'True'},
 'Ymir': {'Enabled': 'True'}}

LCAPI Reference: LayerList

get_layer_list

get_layer_list() returns a dictionary of the WWT client’s layers:

layer_list = wwt.get_layer_list()

returns something like:

{'2D Sky': {'Enabled': 'True',
  'ID': 'fffe96fc-b485-44bb-8f78-538e0f2348d4',
  'Type': 'SkyOverlays',
  'Version': '3'},
 '3d Solar System': {'Enabled': 'True',
  'ID': 'cb87eaec-534d-4490-b3d9-4d9013574895',
  'Type': 'SkyOverlays',
  'Version': '3'},
 'ISS Model  (Toshiyuki Takahei)': {'Enabled': 'False',
  'ID': '00000001-0002-0003-0405-060708090a0b',
  'Type': 'ISSLayer',
  'Version': '2'},
 'Overlays': {'Enabled': 'True',
  'ID': '531f48c6-f8f5-44db-bce5-b81301a25b60',
  'Type': 'SkyOverlays',
  'Version': '2'}}

LCAPI Reference: LayerList

get_state

get_state() returns a dict of some of the details of the current view:

wwt.get_state()

returns something along the lines of:

{'ReferenceFrame': 'Sun',
 'ViewToken': 'GK484GJ28CH2E59766142GGGGIC8427AA1468BBD2D453FB0A22FA365486C3F21FB521FD2E8683FGGG',
 'ZoomText': '1.2 Mpc',
 'angle': '0',
 'lat': '48',
 'lng': '-12',
 'lookat': 'SolarSystem',
 'rotation': '0',
 'time': '4/1/2015 2:38:13 PM',
 'timerate': '1',
 'zoom': '600000000000'}

LCAPI Reference: State

move_view

move_view() changes the view depending on the supplied parameter:

wwt.move_view("ZoomIn")

where the parameter may be one of:

  • "ZoomIn": Zoom in on the current view.
  • "ZoomOut": Zoom out of the current view.
  • "Up": Move the current view up.
  • "Down": Move the current view down.
  • "Left": Move the current view left.
  • "Right": Move the current view right.
  • "Clockwise": Rotate the view clockwise 0.2 of one radian.
  • "CounterClockwise": Rotate the view counterclockwise 0.2 of one radian.
  • "TiltUp": Angle the view up 0.2 of one radian.
  • "TiltDown": Angle the view down 0.2 of one radian.
  • "Finder": Currently unimplemented.

LCAPI Reference: Move

ui_settings

Note

At the moment this does not work properly due to issues on the WWT side

ui_settings() changes user interface settings without altering the layer data:

wwt.ui_settings("ShowConstellationBoundries", "True")

To see the list of possible settings see the LCAPI section on uisettings.

Standard Keyword Arguments

Many of the pywwt methods take a standard set of keyword arguments that may be applied along with that method’s particular arguments.

  • date_time (string): Sets the viewing clock to the given date and time, in UTC format, for example: “1/1/2000 12:02:46 AM”
  • time_rate (float): The accelerated time to render the visualization, as a multiple of 10.
  • fly_to (list of floats): Sets the position of the view camera. Requires five floating point numbers, in this order:
  1. Latitude is in decimal degrees, positive to the North.
  2. Longitude is in decimal degrees, positive to the East.
  3. Zoom level varies from 360 (the most distant view) to 0.00023 (the closest view).
  4. Rotation is in radians, positive moves the camera to the left.
  5. Angle is in radians, positive moves the camera forward.
  6. (optional) The name of the frame to change the view to.
  • instant (boolean): Used with the fly_to parameter, set this to True to specify that the camera should jump to the location, or False that the camera should smoothly pan and zoom to the location. Default
  • autoloop (boolean): True sets the layer manager to auto loop.

The API documentation for WWTWindowsClient and WWTLayer lists for each method all the possible keyword arguments.

An example call:

wwt.move_view("Clockwise", date_time="1/1/2000", time_rate=100.)

which would rotate the view clockwise, set the current date and time to 1/1/2000 at 12:00:00 AM UTC, and increase the rate of the passage of time by a factor of 100.

LCAPI Reference: General Parameters

Data Utilities

pywwt provides general utilities for generating and transforming data into formats suitable for WWT.

convert_xyz_to_spherical

convert_xyz_to_spherical() takes a set of Cartesian coordinates and returns a dictionary of NumPy arrays containing the coordinates converted to spherical coordinates:

sp_crd = convert_xyz_to_spherical(x, y, z, is_astro=True, ra_units="degrees")

where x, y, and z are NumPy arrays corresponding to the Cartesian coordinates, assumed to have an origin at (0,0,0). From this call, sp_crd will have "RA", "DEC", and "ALT" as fields. If is_astro is set to False, the fields will be "LAT", "LON", and "ALT". ra_units controls whether the "RA" coordinate will be in degrees or hours.

generate_utc_times

For data that does not have a time component, generate_utc_times() will generate a list of times that may be used by WWT:

num_steps = 100
step_size = {"days":5, "hours":12, "minutes":5}
start_time = "1/1/2013 12:00 AM"
my_times = generate_utc_times(num_steps, step_size, start_time=start_time)

The first two arguments, num_steps and step_size, set the number of times and the step between the times. start_time is a keyword argument that defaults to the current system time if it is not specified. my_times will be a list of time strings.

map_array_to_colors

map_array_to_colors() takes a NumPy array of floats, and a Matplotlib colormap, and converts the floating-point values to colors, which may be used as colors for event data in WWT:

colors = map_array_to_colors(temperature, "spectral", scale="log", vmin=1., vmax=7.)

where the first two arguments are the NumPy array arr to be converted, and a string cmap representing the Matplotlib colormap. The scale of the color map may be set to "linear" or "log", and the maximum and minimum values of the data may be set by vmin and vmax. If they are not set, they are set to the minimum and maximum values of the array arr by default.

write_data_to_csv

write_data_to_csv() takes a dict of NumPy arrays or lists of data and writes them to a file in CSV format, which may be read in by load():

particles = {}
particles["x"] = x
particles["y"] = y
particles["z"] = z
particles["color"] = colors
write_data_to_csv(particles, "my_particles.csv", mode="new")

The keyword argument mode may be set to "new" or "append".