{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Observer and Spacecraft Classes\n",
"\n",
"The `Observer` and `Spacecraft` Classes within SORA were created to deal with the observer location. The online documentation here contains the details about every step. \n",
"\n",
"This Jupyter-Notebook was designed as a tutorial for how to work with the `Observer` and `Spacecraft` Classes. Any further question, please contact the core team: Altair Ramos Gomes Júnior, Bruno Eduardo Morgado, Gustavo Benedetti Rossi, and Rodrigo Carlos Boufleur.\n",
"\n",
"**The** `Observer` **and** `Spacecraft` **Docstring were designed to help the users. Also, each function has its Docstring containing its main purpose and the needed parameters (physical description and formats). Please, do not hesitate to use it.**\n",
"\n",
"## 0. Index\n",
"\n",
"1. [Instantiating an Observer or Spacecraft Object](#section_1)\n",
"2. [Setting and/or modifing parameters](#section_2)\n",
"3. [Apparent Sidereal Time](#section_3)\n",
"4. [Ksi and Eta projection](#section_5)\n",
"5. [MPC observatories](#section_6)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"SORA version: 0.3\n"
]
}
],
"source": [
"## import the Class\n",
"from sora.observer import Observer, Spacecraft\n",
"## This means the Observer Class is imported from the \"observer\" module of the sora package\n",
"\n",
"## To facilitate, sora allows to import Observer directly from the sora package.\n",
"from sora import Observer, Spacecraft"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## 1. Instantiating an Observer or Spacecraft Object\n",
"\n",
"### 1.1 Observer\n",
"\n",
"The `Observer` Object Class can be instantiated in different ways. First, all observers should have a _name_ that will distinguish it from other `Observer` Objects and also allows the `Occultation` Object to control all the steps and Objects. This is the name which the user will use to refer to this observer within the `Occultation` Object. The name is not needed when the site is downloaded from the MPC database in which case the name in the MPC will be used.\n",
"\n",
"The `Observer` main objective is to deal with the observer location, convert the coordinates from ITRS and GCRS and vice-versa and calculate the Orthographic projection the coordinates in the direction of a coordinate."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mInit signature:\u001b[0m \u001b[0mObserver\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDocstring:\u001b[0m \n",
"Defines the observer object.\n",
"\n",
"Attributes\n",
"----------\n",
"name : `str`\n",
" Name for the Observer. Observer is uniquely defined (name must be\n",
" different for each observer).\n",
"\n",
"code : `str`\n",
" The IAU code for SORA to search for its coordinates in MPC database.\n",
"\n",
"site : `astropy.coordinates.EarthLocation`\n",
" User provides an EarthLocation object.\n",
"\n",
"lon : `str`, `float`\n",
" The Longitude of the site in degrees.\n",
" Positive to East. Range (0 to 360) or (-180 to +180).\n",
" User can provide in degrees (`float`) or hexadecimal (`string`).\n",
"\n",
"lat : `str`, `float`\n",
" The Latitude of the site in degrees.\n",
" Positive North. Range (+90 to -90).\n",
" User can provide in degrees (float) or hexadecimal (string).\n",
"\n",
"height : `int`, `float`\n",
" The height of the site in meters above see level.\n",
"\n",
"ephem : `str`, `list`\n",
" The ephemeris used to locate the observer on space.\n",
" It can be \"horizons\" to use horizons or a list of kernels\n",
"\n",
"\n",
"Examples\n",
"--------\n",
"User can provide one of the following to define an observer:\n",
"\n",
"- If user will use the MPC name for the site:\n",
"\n",
">>> Observer(code)\n",
"\n",
"- If user wants to use a different name from the MPC database:\n",
"\n",
">>> Observer(name, code)\n",
"\n",
"- If user wants to use an EarthLocation value:\n",
"\n",
">>> from astropy.coordinates import EarthLocation\n",
">>> EarthLocation(lon, lat, height)\n",
">>> Observer(name, site)\n",
"\n",
"- If user wants to give site coordinates directly:\n",
"\n",
">>> Observer(name, lon, lat, height)\n",
"\u001b[0;31mFile:\u001b[0m ~/Documentos/códigos/SORA/sora/observer/core.py\n",
"\u001b[0;31mType:\u001b[0m type\n",
"\u001b[0;31mSubclasses:\u001b[0m \n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"Observer?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Example of an** `Observer` **intantiated with a MPC code**"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"opd = Observer(code='874')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Observatorio do Pico dos Dias, Itajuba'"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"## To see the name of the object \"opd\"\n",
"opd.name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this case, the name is a bit too long, the user can define a differente name upon instantiation."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"opd = Observer(name='OPD', code='874')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Example of** `Observer` **instantiated with coordinates**\n",
"\n",
"This coordinates must in degrees for longitude and latitude and in meters in height."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# using string representation\n",
"obs1 = Observer(name='Ex 1', lon='-45 34 57', lat='-22 32 04', height=1864)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# using numeric representation\n",
"obs2 = Observer(name='Ex 2', lon=-69.295805, lat=-31.79877, height=2495)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Example using an Astropy** `EarthLocation` **Object**\n",
"\n",
"Astropy has an `EarthLocation` Class with observer location information. SORA uses this class as a core functionality in the `Observer` Class. So the user can give an object created from `EarthLocation` as input."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"from astropy.coordinates import EarthLocation\n",
"site = EarthLocation(lon='-45 34 57', lat=' -22 32 04', height=1864)\n",
"obs3 = Observer(name='Ex 3', site=site)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**The user can access some information from the object as attribute**"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Ex 3'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"obs3.name"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$-45^\\circ34{}^\\prime57{}^{\\prime\\prime}$"
],
"text/plain": [
""
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"obs3.lon"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$-22^\\circ32{}^\\prime04{}^{\\prime\\prime}$"
],
"text/plain": [
""
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"obs3.lat"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$1864 \\; \\mathrm{m}$"
],
"text/plain": [
""
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"obs3.height"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the user wants to see the informations in the object, just prints the object directly."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Site: Ex 3\n",
"Geodetic coordinates: Lon: -45d34m57s, Lat: -22d32m04s, height: 1.864 km\n"
]
}
],
"source": [
"print(obs3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.2 Spacecraft\n",
"\n",
"In SORA, it is possible to inform an spacecraft observation. The `Spacecraft` Class provides functionality to identify the observer in space. This way, the `Occultation` object can calculate the geometry for the combination of different `Sacecraft` and `Observer` objects.\n",
"\n",
"For this, to instantiate a `Spacecraft` object, it is required an ephemeris. The options available are: the string \"horizons\" to use ephemeris from the Horizons web service; a list of spice kernels where Spice can identify the spacecraft relative to the barycenter of the Solar System. A \"spkid\" is also required. **Please do not use an Ephem object in this case.**"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"cassini = Spacecraft(name='Cassini', spkid='-82', ephem='horizons')"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"# Using kernels. For example, downloading the New Horizons kernel from\n",
"# https://naif.jpl.nasa.gov/pub/naif/pds/data/nh-j_p_ss-spice-6-v1.0/nhsp_1000/data/spk/\n",
"\n",
"# new_horizons = Spacecraft(name='New Horizons', spkid='-98', ephem=['nh_recon_pluto_od122_v01.bsp'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## 2. Setting and/or modifing parameters\n",
"\n",
"If any parameter given to `Observer` is not correct, the user does not need to delete or overwrite the previous object. It can be given the new values directly to the object attributes. Only the _name_ attribute cannot be replaced."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-45d34m57s\n"
]
}
],
"source": [
"print(obs3.lon)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-35d40m26s\n"
]
}
],
"source": [
"obs3.lon = '-35 40 26'\n",
"print(obs3.lon)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"67d21m05.04s\n"
]
}
],
"source": [
"obs3.lon = 67.3514\n",
"print(obs3.lon)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"ename": "AttributeError",
"evalue": "can't set attribute",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
"Input \u001b[0;32mIn [19]\u001b[0m, in \u001b[0;36m| \u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m obs3\u001b[38;5;241m.\u001b[39mname \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mTeste\u001b[39m\u001b[38;5;124m'\u001b[39m\n",
"\u001b[0;31mAttributeError\u001b[0m: can't set attribute"
]
}
],
"source": [
"obs3.name = 'Teste'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## 3. Apparent Sidereal Time\n",
"\n",
"If the user, for some reason, wants to know the apparent sidereal time at a certain location for a given time, there exists a function that calculates it. This function is only available for the `Observer` object."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mSignature:\u001b[0m \u001b[0mobs3\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msidereal_time\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmode\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'local'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDocstring:\u001b[0m\n",
"Calculates the Apparent Sidereal Time at a reference time.\n",
"\n",
"Parameters\n",
"----------\n",
"time : `str`, `astropy.time.Time`\n",
" Reference time to calculate sidereal time.It can be a string\n",
" in the ISO format (yyyy-mm-dd hh:mm:ss.s) or an astropy Time object.\n",
"\n",
"mode : `str`\n",
" Local or greenwich time.\n",
" If mode set ``'local'`` calculates the sidereal time for the\n",
" coordinates of this object.\n",
" If mode set ``'greenwich'`` calculates the Greenwich Apparent\n",
" Sidereal Time.\n",
"\n",
"\n",
"Returns\n",
"-------\n",
"sidereal_time\n",
" An Astropy Longitude object with the Sidereal Time.\n",
"\u001b[0;31mFile:\u001b[0m ~/Documentos/códigos/SORA/sora/observer/core.py\n",
"\u001b[0;31mType:\u001b[0m method\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"obs3.sidereal_time?"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$19^{\\mathrm{h}}42^{\\mathrm{m}}24.39237631^{\\mathrm{s}}$"
],
"text/plain": [
""
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"obs3.sidereal_time(time='2020-05-10 00:00:00')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The input time can also be an Astropy `Time` Object"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$19^{\\mathrm{h}}42^{\\mathrm{m}}24.39237631^{\\mathrm{s}}$"
],
"text/plain": [
""
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from astropy.time import Time\n",
"\n",
"t = Time('2020-05-10 00:00:00')\n",
"\n",
"obs3.sidereal_time(t)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the user wants to calculate the Greenwich Apparent Sidereal Time, it can be done as:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$15^{\\mathrm{h}}13^{\\mathrm{m}}00.05637697^{\\mathrm{s}}$"
],
"text/plain": [
""
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"obs3.sidereal_time('2020-05-10 00:00:00', mode='greenwich')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Also, with the Observer the user can calculate the altitude and azimuth of a given target."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mSignature:\u001b[0m \u001b[0mobs3\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maltaz\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcoord\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDocstring:\u001b[0m\n",
"Calculates the Altitude and Azimuth at a reference time for a coordinate.\n",
"\n",
"Parameters\n",
"----------\n",
"time : `str`, `astropy.time.Time`\n",
" Reference time to calculate the sidereal time. It can be a string\n",
" in the ISO format (yyyy-mm-dd hh:mm:ss.s) or an astropy Time object.\n",
"\n",
"coord : `str`, `astropy.coordinates.SkyCoord`\n",
" Coordinate of the target ICRS.\n",
"\n",
"\n",
"Returns\n",
"-------\n",
"altitude : `float`\n",
" Object altitude in degrees.\n",
"\n",
"azimuth : `float`\n",
" Object azimuth in degrees.\n",
"\u001b[0;31mFile:\u001b[0m ~/Documentos/códigos/SORA/sora/observer/core.py\n",
"\u001b[0;31mType:\u001b[0m method\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"obs3.altaz?"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Altitude 41.33 degrees\n",
"Azimuth 9.25 degrees\n"
]
}
],
"source": [
"altitude, azimuth = obs3.altaz(time='2020-05-10 00:00:00', coord='20 12 19.3 +25 30 00.5')\n",
"\n",
"print('Altitude {:.2f} degrees'.format(altitude))\n",
"print('Azimuth {:.2f} degrees'.format(azimuth))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## 4. Ksi and Eta projection\n",
"\n",
"`Observer` object calculates the orthographic projection (ksi and eta) of a site in the direction of a star given the following function. Ksi is in the East direction and Eta in the North direction.\n",
"\n",
"The coordinates of the star given must be in the Geocentric Celestial Reference System (GCRS).\n",
"\n",
"This is calculated automaticaly in `Occultation`."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mSignature:\u001b[0m \u001b[0mobs3\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_ksi_eta\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstar\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDocstring:\u001b[0m\n",
"Calculates relative position to star in the orthographic projection.\n",
"\n",
"Parameters\n",
"----------\n",
"time : `str`, `astropy.time.Time`\n",
" Reference time to calculate the position. It can be a string in the\n",
" format ``'yyyy-mm-dd hh:mm:ss.s'`` or an astropy `Time` object.\n",
"\n",
"star : `str`, `astropy.coordinates.SkyCoord`\n",
" The coordinate of the star in the same reference frame as the\n",
" ephemeris. It can be a string in the format ``'hh mm ss.s +dd mm ss.ss'``\n",
" or an astropy `SkyCoord` object.\n",
"\n",
"\n",
"Returns\n",
"-------\n",
"ksi, eta : `float`\n",
" On-sky orthographic projection of the observer relative to a star.\n",
" ``ksi`` is in the North-South direction (North positive).\n",
" ``eta`` is in the East-West direction (East positive).\n",
"\u001b[0;31mFile:\u001b[0m ~/Documentos/códigos/SORA/sora/observer/core.py\n",
"\u001b[0;31mType:\u001b[0m method\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"obs3.get_ksi_eta?"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"511.2578070060709 -86.8256098119528\n"
]
}
],
"source": [
"ksi, eta = obs3.get_ksi_eta(time='2020-05-10 00:00:00', star='19 21 18.63201 -21 44 25.3924')\n",
"print(ksi, eta)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A list of times can be given to the time param, as shown below."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 511.25780701 2017.74529995 3385.67428305 4521.3144453 ]\n",
"[ -86.82560981 -213.25930425 -479.77636105 -868.11505452]\n"
]
}
],
"source": [
"times = ['2020-05-10 00:00:00', '2020-05-10 01:00:00', '2020-05-10 02:00:00', '2020-05-10 03:00:00']\n",
"ksi, eta = obs3.get_ksi_eta(time=times, star='19 21 18.63201 -21 44 25.3924')\n",
"print(ksi)\n",
"print(eta)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"## 5. MPC observatories\n",
"\n",
"The user can download and look all the observatories from the MPC database. These are ground-based observatories. The spacecraft observatories are ignored. The function presented returns a Python dictionary that can be searched by the MPC code."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"from sora.observer import search_code_mpc\n",
"observatories = search_code_mpc()"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('Observatorio do Pico dos Dias, Itajuba',\n",
" )"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"observatories['874']"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"('Haute Provence',\n",
" )"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"observatories['511']"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'000': ('Greenwich', ),\n",
" '001': ('Crowborough',\n",
" ),\n",
" '002': ('Rayleigh',\n",
" ),\n",
" '003': ('Montpellier',\n",
" ),\n",
" '004': ('Toulouse',\n",
" ),\n",
" '005': ('Meudon',\n",
" ),\n",
" '006': ('Fabra Observatory, Barcelona',\n",
" ),\n",
" '007': ('Paris',\n",
" ),\n",
" '008': ('Algiers-Bouzareah',\n",
" ),\n",
" '009': ('Berne-Uecht',\n",
" ),\n",
" '010': ('Caussols',\n",
" ),\n",
" '011': ('Wetzikon',\n",
" ),\n",
" '012': ('Uccle',\n",
" ),\n",
" '013': ('Leiden',\n",
" ),\n",
" '014': ('Marseilles',\n",
" ),\n",
" '015': ('Utrecht',\n",
" ),\n",
" '016': ('Besancon',\n",
" ),\n",
" '017': ('Hoher List',\n",
" ),\n",
" '018': ('Dusseldorf-Bilk',\n",
" ),\n",
" '019': ('Neuchatel',\n",
" ),\n",
" '020': ('Nice',\n",
" ),\n",
" '021': ('Karlsruhe',\n",
" ),\n",
" '022': ('Pino Torinese',\n",
" ),\n",
" '023': ('Wiesbaden',\n",
" ),\n",
" '024': ('Heidelberg-Konigstuhl',\n",
" ),\n",
" '025': ('Stuttgart',\n",
" ),\n",
" '026': ('Berne-Zimmerwald',\n",
" ),\n",
" '027': ('Milan',\n",
" ),\n",
" '028': ('Wurzburg',\n",
" ),\n",
" '029': ('Hamburg-Bergedorf',\n",
" ),\n",
" '030': ('Arcetri Observatory, Florence',\n",
" ),\n",
" '031': ('Sonneberg',\n",
" ),\n",
" '032': ('Jena',\n",
" ),\n",
" '033': ('Karl Schwarzschild Observatory, Tautenburg',\n",
" ),\n",
" '034': ('Monte Mario Observatory, Rome',\n",
" ),\n",
" '035': ('Copenhagen',\n",
" ),\n",
" '036': ('Castel Gandolfo',\n",
" ),\n",
" '037': ('Collurania Observatory, Teramo',\n",
" ),\n",
" '038': ('Trieste',\n",
" ),\n",
" '039': ('Lund',\n",
" ),\n",
" '040': ('Lohrmann Institute, Dresden',\n",
" ),\n",
" '041': ('Innsbruck',\n",
" ),\n",
" '042': ('Potsdam',\n",
" ),\n",
" '043': ('Asiago Astrophysical Observatory, Padua',\n",
" ),\n",
" '044': ('Capodimonte Observatory, Naples',\n",
" ),\n",
" '045': ('Vienna (since 1879)',\n",
" ),\n",
" '046': ('Klet Observatory, Ceske Budejovice',\n",
" ),\n",
" '047': ('Poznan',\n",
" ),\n",
" '048': ('Hradec Kralove',\n",
" ),\n",
" '049': ('Uppsala-Kvistaberg',\n",
" ),\n",
" '050': ('Stockholm (before 1931)',\n",
" ),\n",
" '051': ('Royal Observatory, Cape of Good Hope',\n",
" ),\n",
" '052': ('Stockholm-Saltsjobaden',\n",
" ),\n",
" '053': ('Konkoly Observatory, Budapest (since 1934)',\n",
" ),\n",
" '054': ('Brorfelde',\n",
" ),\n",
" '055': ('Cracow',\n",
" ),\n",
" '056': ('Skalnate Pleso',\n",
" ),\n",
" '057': ('Belgrade',\n",
" ),\n",
" '058': ('Kaliningrad',\n",
" ),\n",
" '059': ('Lomnicky Stit',\n",
" ),\n",
" '060': ('Warsaw-Ostrowik',\n",
" ),\n",
" '061': ('Uzhgorod',\n",
" ),\n",
" '062': ('Turku',\n",
" ),\n",
" '063': ('Turku-Tuorla',\n",
" ),\n",
" '064': ('Turku-Kevola',\n",
" ),\n",
" '065': ('Traunstein',\n",
" ),\n",
" '066': ('Athens',\n",
" ),\n",
" '067': ('Lvov University Observatory',\n",
" ),\n",
" '068': ('Lvov Polytechnic Institute',\n",
" ),\n",
" '069': ('Baldone',\n",
" ),\n",
" '070': ('Vilnius (before 1939)',\n",
" ),\n",
" '071': ('NAO Rozhen, Smolyan',\n",
" ),\n",
" '072': ('Scheuren Observatory',\n",
" ),\n",
" '073': ('Bucharest',\n",
" ),\n",
" '074': ('Boyden Observatory, Bloemfontein',\n",
" ),\n",
" '075': ('Tartu',\n",
" ),\n",
" '076': ('Johannesburg-Hartbeespoort',\n",
" ),\n",
" '077': ('Yale-Columbia Station, Johannesburg',\n",
" ),\n",
" '078': ('Johannesburg',\n",
" ),\n",
" '079': ('Radcliffe Observatory, Pretoria',\n",
" ),\n",
" '080': ('Istanbul',\n",
" ),\n",
" '081': ('Leiden Station, Johannesburg',\n",
" ),\n",
" '082': ('St. Polten',\n",
" ),\n",
" '083': ('Golosseevo-Kiev',\n",
" ),\n",
" '084': ('Pulkovo',\n",
" ),\n",
" '085': ('Kiev',\n",
" ),\n",
" '086': ('Odessa',\n",
" ),\n",
" '087': ('Helwan',\n",
" ),\n",
" '088': ('Kottomia',\n",
" ),\n",
" '089': ('Nikolaev',\n",
" ),\n",
" '090': ('Mainz', ),\n",
" '091': ('Observatoire de Nurol, Aurec sur Loire',\n",
" ),\n",
" '092': ('Torun-Piwnice',\n",
" ),\n",
" '093': ('Skibotn',\n",
" ),\n",
" '094': ('Crimea-Simeis',\n",
" ),\n",
" '095': ('Crimea-Nauchnij',\n",
" ),\n",
" '096': ('Merate',\n",
" ),\n",
" '097': ('Wise Observatory, Mitzpeh Ramon',\n",
" ),\n",
" '098': ('Asiago Observatory, Cima Ekar',\n",
" ),\n",
" '099': ('Lahti',\n",
" ),\n",
" '100': ('Ahtari',\n",
" ),\n",
" '101': ('Kharkov',\n",
" ),\n",
" '102': ('Zvenigorod',\n",
" ),\n",
" '103': ('Ljubljana',\n",
" ),\n",
" '104': ('San Marcello Pistoiese',\n",
" ),\n",
" '105': ('Moscow',\n",
" ),\n",
" '106': ('Crni Vrh',\n",
" ),\n",
" '107': ('Cavezzo',\n",
" ),\n",
" '108': ('Montelupo',\n",
" ),\n",
" '109': ('Algiers-Kouba',\n",
" ),\n",
" '110': ('Rostov',\n",
" ),\n",
" '111': ('Piazzano Observatory, Florence',\n",
" ),\n",
" '112': ('Pleiade Observatory, Verona',\n",
" ),\n",
" '113': ('Volkssternwarte Drebach, Schoenbrunn',\n",
" ),\n",
" '114': ('Engelhardt Observatory, Zelenchukskaya Station',\n",
" ),\n",
" '115': ('Zelenchukskaya',\n",
" ),\n",
" '116': ('Giesing',\n",
" ),\n",
" '117': ('Sendling',\n",
" ),\n",
" '118': ('Astronomical and Geophysical Observatory, Modra',\n",
" ),\n",
" '119': ('Abastuman',\n",
" ),\n",
" '120': ('Visnjan',\n",
" ),\n",
" '121': ('Kharkov University, Chuguevskaya Station',\n",
" ),\n",
" '122': ('Pises Observatory',\n",
" ),\n",
" '123': ('Byurakan',\n",
" ),\n",
" '124': ('Castres',\n",
" ),\n",
" '125': ('Tbilisi',\n",
" ),\n",
" '126': ('Monte Viseggi',\n",
" ),\n",
" '127': ('Bornheim',\n",
" ),\n",
" '128': ('Saratov',\n",
" ),\n",
" '129': ('Ordubad',\n",
" ),\n",
" '130': ('Lumezzane',\n",
" ),\n",
" '131': (\"Observatoire de l'Ardeche\",\n",
" ),\n",
" '132': ('Bedoin',\n",
" ),\n",
" '133': ('Les Tardieux',\n",
" ),\n",
" '134': ('Groszschwabhausen',\n",
" ),\n",
" '135': ('Kasan',\n",
" ),\n",
" '136': ('Engelhardt Observatory, Kasan',\n",
" ),\n",
" '137': ('Givatayim Observatory',\n",
" ),\n",
" '138': ('Village-Neuf',\n",
" ),\n",
" '139': ('Antibes',\n",
" ),\n",
" '140': ('Augerolles',\n",
" ),\n",
" '141': ('Hottviller',\n",
" ),\n",
" '142': ('Sinsen',\n",
" ),\n",
" '143': ('Gnosca',\n",
" ),\n",
" '144': ('Bray et Lu',\n",
" ),\n",
" '145': (\"'s-Gravenwezel\",\n",
" ),\n",
" '146': ('Frignano',\n",
" ),\n",
" '147': ('Osservatorio Astronomico di Suno',\n",
" ),\n",
" '148': ('Guitalens',\n",
" ),\n",
" '149': ('Beine-Nauroy',\n",
" ),\n",
" '150': ('Maisons Laffitte',\n",
" ),\n",
" '151': ('Eschenberg Observatory, Winterthur',\n",
" ),\n",
" '152': ('Moletai Astronomical Observatory',\n",
" ),\n",
" '153': ('Stuttgart-Hoffeld',\n",
" ),\n",
" '154': ('Cortina',\n",
" ),\n",
" '155': ('Ole Romer Observatory, Aarhus',\n",
" ),\n",
" '156': ('Catania Astrophysical Observatory',\n",
" ),\n",
" '157': ('Frasso Sabino',\n",
" ),\n",
" '158': ('Promiod',\n",
" ),\n",
" '159': ('Monte Agliale',\n",
" ),\n",
" '160': ('Castelmartini',\n",
" ),\n",
" '161': ('Cerrina Tololo Observatory',\n",
" ),\n",
" '162': ('Potenza',\n",
" ),\n",
" '163': ('Roeser Observatory, Luxembourg',\n",
" ),\n",
" '164': ('St. Michel sur Meurthe',\n",
" ),\n",
" '165': ('Piera Observatory, Barcelona',\n",
" ),\n",
" '166': ('Upice',\n",
" ),\n",
" '167': ('Bulach Observatory',\n",
" ),\n",
" '168': ('Kourovskaya',\n",
" ),\n",
" '169': ('Airali Observatory',\n",
" ),\n",
" '170': ('Observatorio de Begues',\n",
" ),\n",
" '171': ('Flarestar Observatory, San Gwann',\n",
" ),\n",
" '172': ('Onnens',\n",
" ),\n",
" '173': ('St. Clotilde, Reunion',\n",
" ),\n",
" '174': ('Nyrola Observatory, Jyvaskyla',\n",
" ),\n",
" '175': ('F.-X. Bagnoud Observatory, St-Luc',\n",
" ),\n",
" '176': ('Observatorio Astronomico de Consell',\n",
" ),\n",
" '177': ('Le Cres',\n",
" ),\n",
" '178': ('Collonges',\n",
" ),\n",
" '179': ('Monte Generoso',\n",
" ),\n",
" '180': ('Mauguio',\n",
" ),\n",
" '181': ('Observatoire des Makes, Saint-Louis',\n",
" ),\n",
" '182': ('St. Paul, Reunion',\n",
" ),\n",
" '183': ('Starlab Observatory, Karachay-Cherkessia',\n",
" ),\n",
" '184': ('Valmeca Observatory, Puimichel',\n",
" ),\n",
" '185': ('Observatoire Astronomique Jurassien-Vicques',\n",
" ),\n",
" '186': ('Kitab',\n",
" ),\n",
" '187': ('Astronomical Observatory, Borowiec',\n",
" ),\n",
" '188': ('Majdanak',\n",
" ),\n",
" '189': ('Geneva (before 1967)',\n",
" ),\n",
" '190': ('Gissar',\n",
" ),\n",
" '191': ('Dushanbe',\n",
" ),\n",
" '192': ('Tashkent',\n",
" ),\n",
" '193': ('Sanglok',\n",
" ),\n",
" '194': ('Tivoli',\n",
" ),\n",
" '195': ('Untermenzing Observatory, Munich',\n",
" ),\n",
" '196': ('Homburg-Erbach',\n",
" ),\n",
" '197': ('Bastia',\n",
" ),\n",
" '198': ('Wildberg',\n",
" ),\n",
" '199': ('Buthiers',\n",
" ),\n",
" '200': ('Beersel Hills Observatory',\n",
" ),\n",
" '201': ('Jonathan B. Postel Observatory',\n",
" ),\n",
" '202': ('Tamaris Observatoire, La Seyne sur Mer',\n",
" ),\n",
" '203': ('GiaGa Observatory',\n",
" ),\n",
" '204': ('Schiaparelli Observatory',\n",
" ),\n",
" '205': ('Obs. Casalecchio di Reno, Bologna',\n",
" ),\n",
" '206': ('Haagaar Observatory, Eina',\n",
" ),\n",
" '207': ('Osservatorio Antonio Grosso',\n",
" ),\n",
" '208': ('Rivalta',\n",
" ),\n",
" '209': ('Asiago Observatory, Cima Ekar-ADAS',\n",
" ),\n",
" '210': ('Alma-Ata',\n",
" ),\n",
" '211': ('Scandicci',\n",
" ),\n",
" '212': ('Observatorio La Dehesilla',\n",
" ),\n",
" '213': ('Observatorio Montcabre',\n",
" ),\n",
" '214': ('Garching Observatory',\n",
" ),\n",
" '215': ('Buchloe',\n",
" ),\n",
" '216': ('Observatoire des Cote de Meuse',\n",
" ),\n",
" '217': ('Assah',\n",
" ),\n",
" '218': ('Hyderabad',\n",
" ),\n",
" '219': ('Japal-Rangapur',\n",
" ),\n",
" '220': ('Vainu Bappu Observatory, Kavalur',\n",
" ),\n",
" '221': ('IAS Observatory, Hakos',\n",
" ),\n",
" '222': ('Yerres-Canotiers',\n",
" ),\n",
" '223': ('Madras',\n",
" ),\n",
" '224': ('Ottmarsheim',\n",
" ),\n",
" '225': ('Northwood Ridge Observatory',\n",
" ),\n",
" '226': ('Guido Ruggieri Observatory, Padua',\n",
" ),\n",
" '227': ('OrbitJet Observatory, Colden',\n",
" ),\n",
" '228': ('Bruno Zugna Observatory, Trieste',\n",
" ),\n",
" '229': ('G. C. Gloriosi Astronomical Observatory, Salerno',\n",
" ),\n",
" '230': ('Mt. Wendelstein Observatory',\n",
" ),\n",
" '231': ('Vesqueville',\n",
" ),\n",
" '232': ('Masquefa Observatory',\n",
" ),\n",
" '233': ('Sauro Donati Astronomical Observatory, San Vito',\n",
" ),\n",
" '234': ('Coddenham Observatory',\n",
" ),\n",
" '235': ('CAST Observatory, Talmassons',\n",
" ),\n",
" '236': ('Tomsk',\n",
" ),\n",
" '237': ('Baugy',\n",
" ),\n",
" '238': ('Grorudalen Optical Observatory',\n",
" ),\n",
" '239': ('Trebur',\n",
" ),\n",
" '240': ('Herrenberg Sternwarte',\n",
" ),\n",
" '241': ('Schaerding',\n",
" ),\n",
" '242': ('Varennes',\n",
" ),\n",
" '243': ('Umbrella Observatory, Fredenbeck',\n",
" ),\n",
" '244': ('Geocentric Occultation Observation',\n",
" ),\n",
" '245': ('Spitzer Space Telescope', |