# Understanding the information contained in the Deep Space Network XML data?

NASA's Deep Space Network activity can be viewed conveniently at https://eyes.nasa.gov/dsn/dsn.html but if you would like data in a more raw XML form, it can be accessed as described in this answer

Below is a small Python script that reads the XML into a list of dictionaries, and saves it to disk as a JSON.

The dictionaries are organized at the higher level by dish, then by spacecraft per dish.

Question: What are the most-likely meanings of all the data field contained in the Deep Space Network XML data?

This is the example url from the other answer, used in the script below: https://eyes.nasa.gov/dsn/data/1365107113.xml

def dictify(r,root=True): # https://stackoverflow.com/questions/2148119/how-to-convert-an-xml-string-to-a-dictionary-in-python/30923963#30923963
if root:
return {r.tag : dictify(r, False)}
d=copy(r.attrib)
if r.text:
d["_text"]=r.text
for x in r.findall("./*"):
if x.tag not in d:
d[x.tag]=[]
d[x.tag].append(dictify(x,False))
return d

import xml.etree.ElementTree as ET
from copy import copy
import requests, json, pprint

# https://deepspace.jpl.nasa.gov/dsnnow/
# https://eyes.nasa.gov/dsn/dsn.html
# https://space.stackexchange.com/questions/17046/is-there-any-publicly-available-logging-or-wayback-machine-for-dsn-now-activi

N     = 1365107113

url   = "https://eyes.nasa.gov/dsn/data/" + str(N) + ".xml"

r     = requests.get(url)

text  = r.text

a     = ET.fromstring(text)

things = [dictify(x) for x in a]

with open (str(N) + '_XML', 'w') as outfile:
json.dump(things, outfile)

pp = pprint.PrettyPrinter(indent=1)

for i, thing in enumerate(things):
print "i = ", i
pp.pprint(thing)


Here are the last two "things" this prints:

i =  14
{'dish': {'_text': '\n\t\t',
'azimuthAngle': '16.999969',
'created': '2013-04-04T07:00:42.036Z',
'downSignal': [{'dataRate': '2291.963470',
'frequency': '8445767679.000001',
'power': '-482.579407',
'signalType': 'none',
'signalTypeDebug': 'IDLE OFF 0 MCD2',
'spacecraft': 'RSTS',
'spacecraftId': '99'}],
'elevationAngle': '88.000488',
'isArray': 'false',
'isDDOR': 'false',
'isMSPA': 'false',
'name': 'DSS43',
'target': [{'downlegRange': '-1.0',
'id': '99',
'name': 'RSTS',
'rtlt': '-1.0',
'uplegRange': '-1.0'}],
'upSignal': [{'dataRate': '',
'frequency': '',
'power': '',
'signalType': 'none',
'signalTypeDebug': '  ',
'spacecraft': 'RSTS',
'spacecraftId': '99'}],
'updated': '2013-04-04T07:00:42.036Z',
'windSpeed': '0.000000'}}
i =  15
{'timestamp': {'_text': '1365107113334'}}


It took me several days observing data from DSN. Here is my analysis of the fields from the XML data files.

station

• name: Call sign for the station.
• friendlyName: Common name for the station (Goldstone, Madrid, Canberra).
• timeUTC: Time that this report happened, using Coordinated Universal Time, in milliseconds (1/1000 of second) since the Unix epoch (1 January 1970).
• timeZoneOffset: Add this number to timeUTC to get the local time of this station, again in milliseconds since the Unix epoch.

dish

• name: Identifier of the dish. Usually "DSS" followed by two decimal digits.
• azimuthAngle, elevationAngle: The astronomical azimuth and elevation where this dish is currently pointing, in degrees with a decimal fraction.
• windSpeed: The wind speed around the dish, in km/hr.
• isMSPA: If "true", the dish is listening to more than one target (Multiple Spacecraft Per Aperture).
• isArray: If "true", the dish is part of a dish array.
• isDDOR: If "true", the dish is being used for Delta Differential One-way Ranging.
• created, updated: File creation and modification times (of what?), in ISO 8601 format.

target

• name: The call sign for the target spacecraft.
• id: A decimal ID number for each spacecraft. Appears to be sequentially assigned (starting at 1) when the spacecraft was added to the database.
• uplegRange, downlegRange: Estimated distance to and from the target, in km. Should be the same, unless using an array or DDOR. Seems to be off by a factor of 2.
• rtlt: Round-trip light time, in seconds. Seems to be off by a factor of 2.

upSignal

• signalType: none if setup/teardown/tracking, carrier if carrier frequency only, data if something actually being sent.
• signalTypeDebug: Unknown; intended for the programmers.
• power: Power of transmitted signal, in kW.
• frequency: Frequency of transmitted signal, in MHz.
• dataRate: Bits per second of transmitted data.
• spacecraft: Call sign of targeted spacecraft.
• spacecraftId: ID number of targeted spacecraft.

downSignal

• signalType: none if setup/teardown/tracking, carrier if carrier frequency only, data if something actually being received.
• signalTypeDebug: Unknown; intended for the programmers.
• spacecraft: Call sign of targeted spacecraft.
• spacecraftId: ID number of targeted spacecraft.
• dataRate: Bits per second of received data.
• frequency: Frequency of received signal, in Hz. Note the different units and higher precision than the upSignal; this would be useful for analyzing the Doppler effect of the spacecraft's motion.
• power: Power of received signal, in dBm. There have been several times where two targets of the same dish have nearly identical power, except offset by a value of 300: typically -1xx.xx and -4xx.xx dBm. Therefore, I think 300 is deducted from the power as a flag for a certain condition (which I have yet to identify). Code to handle this value should look like this:
if (power < -300.00)
power = power + 300.00


Please give this a try, plot the results, and let us know if it works!

You'll notice that units are not consistent. Time can be in Unix time or in ISO 8601. Frequency can be in Hz or MHz. Power can be in kW or dBm.

I would be concerned that units might change in the future, or have changed in the past. Therefore, I would recommend performing a "sanity check" on values, and adjust the correspondingly. Frequency for example:

if (frequency < 40.0)
# Gigahertz
frequency = frequency * 1E9
else if (frequency < 40000)
# Megahertz
frequency = frequency * 1E6
# else Hertz


IEEE radio band frequencies (from Wikipedia):

S   2 to 4 GHz  Short wave
C   4 to 8 GHz  Compromise between S and X
X   8 to 12 GHz     Used in WW II for fire control, X for cross (as in crosshair). Exotic.
Ku  12 to 18 GHz    Kurz-under
K   18 to 27 GHz    Kurz (German for "short")
Ka  27 to 40 GHz    Kurz-above

• This is beautiful, thanks for your hard work! – uhoh Dec 1 '18 at 2:24

## Follow-up

DSN stores the data internally in a format called "TRK-2-34". It's described in DSN technical note 820-013. I've found 15 papers that refer to using this data format. Two of those papers specifically state that it is an "internal document." Also consider this blog post:

This is a technical article about how to use the Deep Space Network (DSN). I’m going to start high briefly and dive in deeply. You can google/wiki the top level stuff. I want to get right into how to translate from DSN formatted data types into range and range rate in kilometers/ kilometers per second.

I want to do this because it was unnecessarily hard for me. Not because of the theory but because of the lack of documentation or guidance. I’ve ranted before that the DSN’s idea of a car for sale is a bag of parts, some duplicates, some bad, no instructions.

and

The documentation on the TRK-2-34 format is actually comprehensive, but doesn’t explain how to put the pieces together to get a usable measurement

and

In general, my #1 complaint with almost everything spacecraft operations related is how needlessly complicated everything is, and how difficult it is to agree on data format, interfacing and access, even units and modeling.

and

DSN does a beautiful thing, but they are not a public-facing for-profit company. If you want to use the DSN to track your precious spacecraft, you’ll have to play with the toys they give you. You’ll need a half-decent a priori state vector for your spacecraft, a simulator to propagate it and extract geometry, a binary parser, the TRK-2-34 handbook, and all the steps listed above.

https://clarkpatricknewman.wordpress.com/category/nasa/dsn/

The TRK-2-34 format description (820-013) is not public information. It appears the only way you are going to get a copy is to send up your own spacecraft and pay DSN to track it.

• This bodes ill for the chances of this getting its "authoritative source". If you like, please feel free to leave a comment or an answer there pointing this out, as you've nicely documented that likelihood here! – uhoh Dec 1 '18 at 6:47