Creating Catalogues
The two main elements required to start preparing a TFCat feature
collection is the choice of the CRS and the list of feature geometries
(with its set of time and spectral coordinates). In the following code
snippet, a CRS object is created with a time axis using the unix
timestamp representation, a spectral axis (frequency in kHz) and a
reference position set to the Juno spacecraft.
from tfcat import CRS
crs = CRS({
"type": "local",
"properties": {
"name": "Time-Frequency",
"time_coords_id": "unix",
"spectral_coords": {
"type": "frequency",
"unit": "kHz"
},
"ref_position_id": "juno",
}
})
In the following example, we create a TFCat feature with a TFCat Polygon
geometry and two custom feature properties called feature_type
and integrated_flux_density. The set of coordinates are available as
two variables called tt and ff, containing respectively the time
coordinates (as a unix timestamp), and the frequency coordinates
(in kHz). Note, that a Polygon geometry requires that the last coordinate
point of the input sequence should be the same as the first one (closed
polygon condition). It also requires that the segments forming the polygon
are not crossing over (no cross-over condition). The polygon must also be
curled counter-clockwise. We use the shapely package to check those
conditions.
from tfcat import Polygon, Feature
from shapely.geometry import LinearRing
# packing coordinates into a list
coords = list(zip(tt, ff))
# checking if polygon is valid
if not LinearRing(coords).isvalid:
raise ValueError("Polygon is invalid")
# checking if list of coordinates is curled in the direct trigonometric sense (counter-clockwise)
if not LinearRing(coords).is_ccw:
coords = coords[::-1]
# creating the TFCat Feature
feature = Feature(
geometry=Polygon([coords]),
properties={
"feature_type": "Io-A",
"integrated_flux_density": 1.22e-19,
},
)
Each properties must be defined at the main level of the feature collection object, using a set of TFCat Field objects, as shown below.
fields = {
"feature_type": {
"info": "Feature Type",
"datatype": "str",
"ucd": "meta.id",
},
"integrated_flux_density": {
"info": "Integrated Flux Density",
"datatype": "float",
"ucd": "phot.flux.density;stat.mean",
"unit": "W m-2 Hz-1",
}
}
The feature collection can also include main level properties, listing global metadata for the collection, such as the author, the instrument, etc. The next code snippet shows a set of collection level properties. We recommend to use keywords compliant with the EPNcore metadata dictionary. For authors, we recommend to use a list of dictionaries containing GivenName, FamilyName, ORCID and Affiliation (using Research Organisation Registry identifier when possible).
properties = {
"instrument_host_name": "Juno",
"instrument_name": "Waves",
"title": "Catalogue of Juno Radio emissions",
"authors": [
{
"GivenName": "Corentin K.",
"FamilyName": "Louis",
"ORCID": "https://orcid.org/0000-0002-9552-8822",
"Affiliation": "https://ror.org/051sx6d27"
},
],
"target_name": "Jupiter",
"target_class": "planet",
"target_region": "magnetosphere",
"feature_name": "radio emissions",
"bib_reference": "TBD",
"publisher": "PADC/MASER",
"version": "1.0"
}
Finally, the collection can be built, assuming a list of features is available
in an iterable called features. The JSON schema URI should also be referenced.
from tfcat import FeatureCollection
SCHEMA_URI = "https://voparis-ns.obspm.fr/maser/tfcat/v1.0/schema#"
# creating the collection
collection = FeatureCollection(
schema=SCHEMA_URI,
features=features,
properties=properties,
fields=fields,
crs=crs
)
Writing the collection into a file is straightforward, since tje TFCat module implements the
same interfaces as the json python module for file system interactions (i.e., dump(),
dumps(), load(), loads() methods):
# write out the collection on disk
from tfcat import dump
filename = "tfcat.json"
with open(filename, "w") as f:
dump(collection, f)