Tutorials¶
Below are some frequent analysis questions that rocks
aims to solve
quickly. Do you have a good example to add? Post it in an issue on GitHub.
For more extended examples, check out the jupyter notebooks:
Basic Usage - Bibliography Management.
Identification¶
How do I identify an asteroid?
The basic usage is shown below. More information can be found here and here.
$ rocks id this
(23) This
>>> rocks.id(['this', 'that'])
[(this, 23), (that, 23)]
How do I ensure that the names and numbers of all asteroids in a file are up-to-date?
Let’s assume that the data file is in CSV format and that there is a single
column designation
which contains the identifiers of
the asteroids. These can be mixed: numbers, names, provisional designations
in different formats.
import pandas as pd
import rocks
data = pd.read_csv("/path/to/data.csv")
# Assuming that the asteroid names and designations are in a column called "designation"
data["name"] = [name for name, number in rocks.id(data["designation"])]
# To update the numbers, just change the list comprehension
data["number"] = [number for name, number in rocks.id(data["designation"])]
Note that this solution is easy to code but inefficient as the identification is executed twice. The more efficient but less readable solution is
data["name"], data["number"] = zip(*rocks.id(data["designation"]))
Not possible. If you think it should be, open a feature request on GitHub.
How can I get the aliases of an asteroid?
$ rocks ids aschera
(214) Aschera, aka
['1880 DB', '1903 SE', '1947 BP', '1948 JE', '1949 QG2', '1949 SX1', '1950 XH', '1953 OO',
'2000214', 'I80D00B', 'J03S00E', 'J47B00P', 'J48J00E', 'J49Q02G', 'J49S01X', 'J50X00H', 'J53O00O']
Not possible. If you think it should be, open a feature request on GitHub.
How can I identify an asteroid using its NAIF ID?
NAIF IDs are not stored in the local asteroid name-number index due to the ambiguity with ordinary asteroid numbers. You can still identify asteroids using their NAIF IDs by skipping the local look-up and forcing a quaero query.
>>> rocks.id(2000001)
ERROR [rocks] The provided number 2000001 is larger than the largest number of any asteroid.
>>> rocks.id(2000001, local=False)
(Ceres, 1)
Not possible.
What asteroids are in the SDSS MOC1?
The script below shows the typical workflow of downloading a database of asteroid observations and updating the outdated provisional designations used to identify the asteroids.
import numpy as np
import pandas as pd
import rocks
# ------
# Download SDSS MOC1 (28.6MB)
data = pd.read_fwf(
"https://faculty.washington.edu/ivezic/sdssmoc/ADR1.dat",
colspecs=[(244, 250), (250, 270)],
names=["numeration", "designation"],
)
print(f"Number of observations in SDSS MOC1: {len(data)}")
# Remove the unknown objects
data = data[data.designation.str.strip(" ") != "-"]
print(f"Observations of known objects: {len(set(data.designation))}")
# ------
# Get current designations and numbers for objects
# Unnumbered objects should be NaN
data.loc[data.numeration == 0, "numeration"] = np.nan
# Create list of identifiers by merging 'numeration' and 'designation' columns
ids = data.numeration.fillna(data.designation)
print("Identifying known objects in catalogue..")
names_numbers = rocks.identify(ids)
# Add numbers and names to data
data["name"] = [name_number[0] for name_number in names_numbers]
data["number"] = [name_number[1] for name_number in names_numbers]
data.number = data.number.astype("Int64") # Int64 supports integers and NaN
print(data.head())
Data Exploration¶
How do I get best-estimates of asteroid parameters?
The basic usage is shown below. More information can be found here.
The basic usage is $ rocks [parameter] [identifier]
. The list of
valid parameter names can be found here.
$ rocks albedo cybele
0.0344 +- 0.2499
$ rocks albedo.bibref ceres
[Bibref(doi='10.3847/2041-8205/817/2/L22', year=2016, title='Surface Albedo and Spectral Variability of Ceres', bibcode='2016ApJ...817L..22L', shortbib='Li+2016')]
How do I get all the taxonomic classes proposed for Ceres?
The taxonomic classes assigned to minor planets in public literature are available in the taxonomies
datacloud catalogues. They can be retrieved via the command line
and in a python
script as DataCloudDataFrame instance.
$ rocks taxonomies Ceres
>>> import rocks
>>> ceres = rocks.Rock(1, datacloud="taxonomies")
>>> for index, classification in ceres.taxonomies.iterrows():
print(f"{classification.shortbib} assigned class {classification.class_} to Ceres")
Tholen+1989 assigned class G to Ceres
Bus&Binzel+2002 assigned class C to Ceres
Lazzaro+2004 assigned class C to Ceres
Lazzaro+2004 assigned class C to Ceres
DeMeo+2009 assigned class C to Ceres
Fornasier+2014 assigned class G to Ceres
Fornasier+2014 assigned class C to Ceres
Mahlke+2022 assigned class C to Ceres
How do I get the taxonomy distribution of the first 1000 numbered minor planets?
#!/usr/bin/env python
"""Retrieve taxonomies of first 1000 numbered minor planets with rocks."""
import pandas as pd
import rocks
# Create list of identifiers for first 1000 asteroids
N = 1000
ids = list(range(1, N + 1))
# Create the rocks instances
asteroids = rocks.rocks(ids)
# Create a dataframe containing the asteroid names, numbers,
# their taxonomic class.
data = [{"number": ast.number, "name": ast.name, "class_": ast.taxonomy.class_} for ast in asteroids]
data = pd.DataFrame(data)
# Print the distribution of taxonomic classes
print(data.class_.value_counts())
What is the distribution of thermal inertias of known Barbarian asteroids?
#!/usr/bin/env python
"""Retrieve thermal inertias of known Barbarian asteroids."""
import rocks
# List of known Barbarians from Devogèle+ 2018
BARBARIANS = [172, 234, 236, 387, 402, 458, 599, 606,
611, 679, 729, 824, 980, 1284, 1372, 2085]
# Convert into list of Rock instances
barbarians = rocks.rocks(BARBARIANS)
thermal_ineratias = [barbarian.thermal_inertia.value for barbarian in barbarians]
print(thermal_ineratias )
What’s the weighted average albedo of (6) Hebe?
The average albedo can be retrieved using the diamalbedo
datacloud catalogue. The weighted_average()
method of the DataCloudDataFrame class is used to compute the average based on the best available observations of the parameter. The average is available in a python
script via
>>> import rocks
>>> hebe = rocks.Rock(6, datacloud="albedos")
>>> hebe.albedos.weighted_average("albedo")
(0.2397586986597045, 0.009518727398082856)
How do I access the entries in a catalogue one by one?
Data Analysis¶
How do I select all members of the Hermione family?
How do I efficiently get the data of a large number of asteroids?
The rocks.rocks()
function serves as a one-line replacement for a frequent
approach: get a list of asteroid identifiers from a catalogue and create
Rock
instances from them.
>>> from rocks import rocks
>>> themis_family = [24, 62, 90, 104, 171, 222, 223, 316, 379,
383, 468, 492, 515, 526, 767, 846]
>>> themis_family = rocks(themis_family)
>>> themis_family
[Rock(number=316, name='Goberta'), Rock(number=492, name='Gismonda'),
Rock(number=767, name='Bondia'), Rock(number=90, name='Antiope'), ... ]
Accessing the properties can now be done with a loop or list comprehension.
>>> from collections import Counter
>>> themis_taxonomies = [t.taxonomy.class_ for t in themis_family]
>>> Counter(themis_taxonomies)
Counter({'C': 8, 'B': 2, 'Ch': 2, 'BU': 1, 'Xc': 1, 'Xk': 1, 'Cb': 1})
Any property not present in the ssoCard of an asteroid is set to NaN
. This ensures that accessing attributes in a loop does not fail.
Can I use my own data to build a Rock
object?
You can provide a custom ssoCard to populate the Rock
attributes. The ssocard
argument
accepts a dict
ionary structure following the one of the original ssoCards. The easiest way
to achieve this is to edit a real ssoCard from SsODNet and load it via the json
module.
>>> import json
>>> import os
>>> import rocks
>>> with open("my_ssocard.json", "r") as file_:
>>> data = json.load(file_)
>>> mars_crosser_2016fj = rocks.Rock("2016_FJ", ssocard=data["2016_FJ"])
SsODNet and rocks
¶
What is the difference between data from the ssoCard and from the datacloud?
Is the cached asteroid data out-of-date? How do I update it?
Which parameters can be abbreviated?
Which parameters can I open in a plot?
I see too many WARNING
s I don’t care about. How do I change the verbosity of rocks
?
The rocks.set_log_level(LEVEL)
function can be used to set the verbosity of rocks
. The default level
is INFO
, meaning that all messages with a priority of INFO
or higher are printed. To see only the most relevant
information, you can use rocks.set_log_level("error")
.
See https://docs.python.org/3/library/logging.html#levels for more information on the different levels.
I got Error 404: missing ssoCard for IDENTIFIER
. What is happening?
rocks
tried to retrieve the ssoCard of a confirmed identifier and
got an invalid response from SsODNet. This can have different reasons:
The confirmed identifier is outdated. This may happen if an asteroid has recently been named or the designation has changed. In these cases, the ssoCard is associated to the new name of the asteroid, while
rocks
may still look for it under its previous designation. Updating the Asteroid name-number index via$ rocks status
fixes this.The ssoCard is unavailable due to a compilation error on the SsODNet side. You can confirm this by looking up the ssoCard directly on SsODNet (replace
IDENTIFIER
in the URL below by the confirmed SsODNet ID of the asteroid):http://ssp.imcce.fr/webservices/ssodnet/api/ssocard.php?q=IDENTIFIER
If the returned ssoCard is
null
, the card does not exist. This may be fixed at the next weekly recompilation of all ssoCards.