{ "cells": [ { "cell_type": "markdown", "id": "7ff57756-4e96-4cd1-a39a-79b434123b5a", "metadata": {}, "source": [ "# Usage Examples\n", "\n", "Here basic usage of the `mt_metadata` module are demonstrated." ] }, { "cell_type": "markdown", "id": "7ff33a5d-5103-4196-8bf2-09f385d71d9e", "metadata": {}, "source": [ "## MetadataBase Class\n", "\n", "`mt_metadata.base.MetadataBase` is the base class for which all metadata objects are built upon. `MetadataBase` is built on Pydantic v2 and provides convenient methods to input and output metadata in different formats: XML, JSON, Python dictionary, and Pandas Series. It also provides functions to help the user understand what's inside and ensures data validation." ] }, { "cell_type": "markdown", "id": "d8e9bcc6-ef6a-4afd-a4b0-a51fdb4ec567", "metadata": {}, "source": [ "## Working with MetadataBase Objects\n", "\n", "Let's start with a practical example using the `Location` metadata class, which inherits from `MetadataBase`." ] }, { "cell_type": "code", "execution_count": 4, "id": "969bfca0-ea65-4dd1-bfbe-3d9d219d5452", "metadata": {}, "outputs": [], "source": [ "from mt_metadata.common import Location\n", "\n", "location = Location()" ] }, { "cell_type": "markdown", "id": "7e6b331b-9cea-48b5-8c1c-c702b406e00b", "metadata": {}, "source": [ "### Methods of MetadataBase\n", "\n", "MetadataBase (built on Pydantic v2) includes methods for converting to/from various formats:\n", "\n", "- **`to_dict()` / `from_dict()`** - Python dictionary\n", "- **`to_json()` / `from_json()`** - JSON string or file\n", "- **`to_xml()` / `from_xml()`** - XML elements\n", "- **`to_series()` / `from_series()`** - Pandas Series\n", "\n", "It also provides:\n", "- **`get_all_fields()`** - Get all field definitions with metadata\n", "- **`get_attribute_list()`** - List of all available attributes\n", "- **`model_dump()`** - Pydantic method to export as dictionary\n", "- **`model_dump_json()`** - Pydantic method to export as JSON" ] }, { "cell_type": "code", "execution_count": 6, "id": "aa0b10c3-1ba9-42de-af6f-7862bf3f67b2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Key Methods:\n", "\tto_dict\n", "\tfrom_dict\n", "\tto_json\n", "\tfrom_json\n", "\tto_xml\n", "\tfrom_xml\n", "\tto_series\n", "\tfrom_series\n", "\tget_all_fields\n", "\tget_attribute_list\n", "\tmodel_dump\n", "\tmodel_dump_json\n" ] } ], "source": [ "# Display key methods available on MetadataBase objects\n", "key_methods = [\n", " \"to_dict\",\n", " \"from_dict\",\n", " \"to_json\",\n", " \"from_json\",\n", " \"to_xml\",\n", " \"from_xml\",\n", " \"to_series\",\n", " \"from_series\",\n", " \"get_all_fields\",\n", " \"get_attribute_list\",\n", " \"model_dump\",\n", " \"model_dump_json\",\n", "]\n", "\n", "available_methods = []\n", "for method_name in key_methods:\n", " if hasattr(location, method_name):\n", " try:\n", " attr = getattr(location, method_name)\n", " if callable(attr):\n", " available_methods.append(method_name)\n", " except AttributeError:\n", " pass\n", "\n", "print(\"Key Methods:\")\n", "for method in available_methods:\n", " print(f\"\\t{method}\")" ] }, { "cell_type": "code", "execution_count": 7, "id": "f8bae79f-d0ae-407a-ae34-0a7a41dd7488", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['datum',\n", " 'elevation',\n", " 'elevation_uncertainty',\n", " 'latitude',\n", " 'latitude_uncertainty',\n", " 'longitude',\n", " 'longitude_uncertainty',\n", " 'x',\n", " 'x2',\n", " 'x_uncertainty',\n", " 'y',\n", " 'y2',\n", " 'y_uncertainty',\n", " 'z',\n", " 'z2',\n", " 'z_uncertainty']" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# View available attributes\n", "location.get_attribute_list()" ] }, { "cell_type": "markdown", "id": "49b1a36a-344c-46e6-a33c-343d81bdc719", "metadata": {}, "source": [ "### Setting Values\n", "\n", "You can set values directly using attribute access. Pydantic automatically validates the data types and values." ] }, { "cell_type": "code", "execution_count": 8, "id": "5edef78a-82ec-4dd9-bc70-c0322ef2fd07", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{\n", " \"location\": {\n", " \"datum\": \"WGS 84\",\n", " \"elevation\": 1500.0,\n", " \"elevation_uncertainty\": 0.0,\n", " \"latitude\": 40.0,\n", " \"latitude_uncertainty\": 0.0,\n", " \"longitude\": -120.0,\n", " \"longitude_uncertainty\": 0.0,\n", " \"x\": 0.0,\n", " \"x2\": 0.0,\n", " \"x_uncertainty\": 0.0,\n", " \"y\": 0.0,\n", " \"y2\": 0.0,\n", " \"y_uncertainty\": 0.0,\n", " \"z\": 0.0,\n", " \"z2\": 0.0,\n", " \"z_uncertainty\": 0.0\n", " }\n", "}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "location.latitude = 40.0\n", "location.longitude = -120.0\n", "location.elevation = 1500.0\n", "location" ] }, { "cell_type": "markdown", "id": "7d8fd8b2-deff-4c85-b416-627de42022ce", "metadata": {}, "source": [ "### The `__str__` Representation\n", "\n", "The string representation provides a readable summary." ] }, { "cell_type": "code", "execution_count": 9, "id": "806e04b6-8989-4722-a17f-88c8e8fcb712", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'latitude': 40.0, 'longitude': -120.0, 'elevation': 1500.0, 'datum': 'WGS 84', 'x': 0.0, 'y': 0.0, 'z': 0.0, 'latitude_uncertainty': 0.0, 'longitude_uncertainty': 0.0, 'elevation_uncertainty': 0.0, 'x2': 0.0, 'y2': 0.0, 'z2': 0.0, 'x_uncertainty': 0.0, 'y_uncertainty': 0.0, 'z_uncertainty': 0.0, '_class_name': 'location'}\n" ] } ], "source": [ "print(location)" ] }, { "cell_type": "markdown", "id": "7e316ebb-5f04-4629-a447-ed96b4bab26e", "metadata": {}, "source": [ "### Field Information\n", "\n", "You can get detailed information about all fields including their types, descriptions, and constraints." ] }, { "cell_type": "code", "execution_count": 10, "id": "5aaaef26-1c70-4217-8e06-87150ef70406", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total fields: 16\n", "First few fields: ['latitude', 'longitude', 'elevation', 'datum', 'x']\n" ] } ], "source": [ "# Get all fields with their metadata\n", "fields = location.get_all_fields()\n", "print(f\"Total fields: {len(fields)}\")\n", "print(f\"First few fields: {list(fields.keys())[:5]}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "8d105f02-282d-41a8-9009-24b8fca5611f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "temperature:\n", "\talias: ['temp']\n", "\tdefault: None\n", "\tdescription: local temperature\n", "\texample: ambient\n", "\toptions: ['ambient', 'air']\n", "\trequired: False\n", "\tstyle: controlled vocabulary\n", "\ttype: \n", "\tunits: celsius\n", "==================================================\n" ] } ], "source": [ "# Examine a specific field's metadata\n", "latitude_field = fields[\"latitude\"]\n", "print(f\"Type: {latitude_field['type']}\")\n", "print(f\"Description: {latitude_field['description']}\")\n", "print(f\"Required: {latitude_field['required']}\")" ] }, { "cell_type": "markdown", "id": "f5ba78d3-c253-4cd5-8259-686e77da3444", "metadata": {}, "source": [ "## Validation with Pydantic\n", "\n", "Validation is automatically handled by Pydantic v2. The validation process:\n", "\n", "1. **Type checking**: Ensures values match the prescribed type (int, float, str, etc.)\n", "2. **Type coercion**: Automatically converts compatible types when possible (e.g., \"10.5\" → 10.5)\n", "3. **Constraints**: Validates against constraints like min/max values, patterns, etc.\n", "4. **Required fields**: Ensures required fields are provided\n", "5. **Nested validation**: Validates nested MetadataBase objects recursively" ] }, { "cell_type": "code", "execution_count": 11, "id": "41bff4f1-fefb-412e-9b75-122863422200", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Latitude type: , value: 45.5\n" ] } ], "source": [ "# Type coercion example - string to float\n", "location.latitude = \"45.5\"\n", "print(f\"Latitude type: {type(location.latitude)}, value: {location.latitude}\")" ] }, { "cell_type": "code", "execution_count": 12, "id": "405063cf-6c0d-4a88-bf26-a41abec70c32", "metadata": {}, "outputs": [ { "ename": "ValidationError", "evalue": "1 validation error for Location\nlatitude\n Value error, latitude must be between -90 and 90 degrees [type=value_error, input_value=90.5, input_type=float]\n For further information visit https://errors.pydantic.dev/2.10/v/value_error", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mValidationError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[12], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# Validation with constraints\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[43mlocation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlatitude\u001b[49m \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m 3\u001b[0m \u001b[38;5;241m90.5\u001b[39m \u001b[38;5;66;03m# Will raise validation error (latitude must be between -90 and 90)\u001b[39;00m\n\u001b[0;32m 4\u001b[0m )\n", "File \u001b[1;32mc:\\Users\\peaco\\miniconda3\\envs\\py311\\Lib\\site-packages\\pydantic\\main.py:922\u001b[0m, in \u001b[0;36mBaseModel.__setattr__\u001b[1;34m(self, name, value)\u001b[0m\n\u001b[0;32m 920\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__dict__\u001b[39m[name] \u001b[38;5;241m=\u001b[39m value\n\u001b[0;32m 921\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel_config\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mvalidate_assignment\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m--> 922\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__pydantic_validator__\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalidate_assignment\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 923\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel_config\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mextra\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mallow\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m name \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__pydantic_fields__:\n\u001b[0;32m 924\u001b[0m \u001b[38;5;66;03m# TODO - matching error\u001b[39;00m\n\u001b[0;32m 925\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m object has no field \u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", "\u001b[1;31mValidationError\u001b[0m: 1 validation error for Location\nlatitude\n Value error, latitude must be between -90 and 90 degrees [type=value_error, input_value=90.5, input_type=float]\n For further information visit https://errors.pydantic.dev/2.10/v/value_error" ] } ], "source": [ "# Validation with constraints\n", "location.latitude = (\n", " 90.5 # Will raise validation error (latitude must be between -90 and 90)\n", ")" ] }, { "cell_type": "markdown", "id": "7d5f254f-495d-4476-ac15-29e2f8e02662", "metadata": {}, "source": [ "## Working with Location Metadata\n", "\n", "Let's create a more complete example with nested metadata objects." ] }, { "cell_type": "code", "execution_count": 15, "id": "fc7b9c93-fb69-4032-b264-51fb05eabb15", "metadata": {}, "outputs": [], "source": [ "from mt_metadata.common import StationLocation\n", "here = StationLocation()\n", "here.latitude = 40.7128\n", "here.longitude = -74.0060\n", "here.elevation = 10.0\n", "here.declination.value = -12.5\n", "here.declination.model = \"WMM\"" ] }, { "cell_type": "code", "execution_count": 16, "id": "88a606d6-ee7c-4707-a414-7ce59df8a73e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'latitude': 40.7128, 'longitude': -74.006, 'elevation': 10.0, 'datum': 'WGS 84', 'x': 0.0, 'y': 0.0, 'z': 0.0, 'latitude_uncertainty': 0.0, 'longitude_uncertainty': 0.0, 'elevation_uncertainty': 0.0, 'x2': 0.0, 'y2': 0.0, 'z2': 0.0, 'x_uncertainty': 0.0, 'y_uncertainty': 0.0, 'z_uncertainty': 0.0, 'declination': {'comments': {'author': None, 'time_stamp': {'time_stamp': '1980-01-01T00:00:00+00:00', 'gps_time': False}, 'value': None, '_class_name': 'comment'}, 'model': 'WMM', 'epoch': None, 'value': -12.5, '_class_name': 'declination'}, 'geographic_location': {'country': None, 'state': None, 'county': None, 'township': None, 'section': None, 'quarter': None, 'parcel': None, '_class_name': 'geographic_location'}, '_class_name': 'station_location'}\n" ] } ], "source": [ "print(here)" ] }, { "cell_type": "markdown", "id": "3deb70d9-903e-4db6-acdd-68653f4159c4", "metadata": {}, "source": [ "### Accessing Nested Attributes\n", "\n", "You can access nested attributes directly using dot notation." ] }, { "cell_type": "code", "execution_count": null, "id": "150a6484-a0f5-4874-a717-c1026e338dce", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "location:\n", "\tdeclination.model = WMM\n", "\tdeclination.value = 10.0\n", "\televation = 0.0\n", "\tlatitude = 0.0\n", "\tlongitude = 0.0\n" ] } ], "source": [ "# Access nested declination object\n", "print(f\"Declination value: {here.declination.value}\")\n", "print(f\"Declination model: {here.declination.model}\")" ] }, { "cell_type": "markdown", "id": "04abe954-399e-41ac-9b32-293cde995db6", "metadata": {}, "source": [ "## Dictionary\n", "\n", "The basic element that the metadata can be in is a Python dictionary with key, value pairs. " ] }, { "cell_type": "code", "execution_count": 17, "id": "acb8c570-22cb-441c-b434-4d3e4c373c11", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'station_location': OrderedDict([('datum', 'WGS 84'),\n", " ('declination.comments.author', None),\n", " ('declination.comments.time_stamp', '1980-01-01T00:00:00+00:00'),\n", " ('declination.comments.value', None),\n", " ('declination.epoch', None),\n", " ('declination.model', 'WMM'),\n", " ('declination.value', -12.5),\n", " ('elevation', 10.0),\n", " ('elevation_uncertainty', 0.0),\n", " ('geographic_location.country', None),\n", " ('geographic_location.county', None),\n", " ('geographic_location.parcel', None),\n", " ('geographic_location.quarter', None),\n", " ('geographic_location.section', None),\n", " ('geographic_location.state', None),\n", " ('geographic_location.township', None),\n", " ('latitude', 40.7128),\n", " ('latitude_uncertainty', 0.0),\n", " ('longitude', -74.006),\n", " ('longitude_uncertainty', 0.0),\n", " ('x', 0.0),\n", " ('x2', 0.0),\n", " ('x_uncertainty', 0.0),\n", " ('y', 0.0),\n", " ('y2', 0.0),\n", " ('y_uncertainty', 0.0),\n", " ('z', 0.0),\n", " ('z2', 0.0),\n", " ('z_uncertainty', 0.0)])}" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Export to dictionary (compact dotted notation)\n", "here.to_dict()" ] }, { "cell_type": "code", "execution_count": 18, "id": "a96a6f7c-783a-4f40-a227-1eeae87499b7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'latitude': -34.0, 'longitude': -104.0, 'elevation': 759.0, 'datum': 'WGS 84', 'x': 0.0, 'y': 0.0, 'z': 0.0, 'latitude_uncertainty': 0.0, 'longitude_uncertainty': 0.0, 'elevation_uncertainty': 0.0, 'x2': 0.0, 'y2': 0.0, 'z2': 0.0, 'x_uncertainty': 0.0, 'y_uncertainty': 0.0, 'z_uncertainty': 0.0, 'declination': {'comments': {'author': None, 'time_stamp': {'time_stamp': '1980-01-01T00:00:00+00:00', 'gps_time': False}, 'value': None, '_class_name': 'comment'}, 'model': 'WMM', 'epoch': None, 'value': -11.0, '_class_name': 'declination'}, 'geographic_location': {'country': None, 'state': None, 'county': None, 'township': None, 'section': None, 'quarter': None, 'parcel': None, '_class_name': 'geographic_location'}, '_class_name': 'station_location'}\n" ] } ], "source": [ "# Import from dictionary with dotted notation\n", "here.from_dict(\n", " {\n", " \"location\": {\n", " \"declination.value\": -11.0,\n", " \"elevation\": 759.0,\n", " \"latitude\": -34.0,\n", " \"longitude\": -104.0,\n", " }\n", " }\n", ")\n", "print(here)" ] }, { "cell_type": "markdown", "id": "6c3b8908-560f-4716-a968-683215e72ff4", "metadata": {}, "source": [ "## JSON\n", "\n", "JSON is a standard format human/machine readable and well supported in Python. There are methods to to read/write JSON files. " ] }, { "cell_type": "code", "execution_count": 19, "id": "d69166f6-58e1-4ae7-82e9-bda538eb579a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"station_location\": {\n", " \"datum\": \"WGS 84\",\n", " \"declination.comments.author\": null,\n", " \"declination.comments.time_stamp\": \"1980-01-01T00:00:00+00:00\",\n", " \"declination.comments.value\": null,\n", " \"declination.epoch\": null,\n", " \"declination.model\": \"WMM\",\n", " \"declination.value\": -11.0,\n", " \"elevation\": 759.0,\n", " \"elevation_uncertainty\": 0.0,\n", " \"geographic_location.country\": null,\n", " \"geographic_location.county\": null,\n", " \"geographic_location.parcel\": null,\n", " \"geographic_location.quarter\": null,\n", " \"geographic_location.section\": null,\n", " \"geographic_location.state\": null,\n", " \"geographic_location.township\": null,\n", " \"latitude\": -34.0,\n", " \"latitude_uncertainty\": 0.0,\n", " \"longitude\": -104.0,\n", " \"longitude_uncertainty\": 0.0,\n", " \"x\": 0.0,\n", " \"x2\": 0.0,\n", " \"x_uncertainty\": 0.0,\n", " \"y\": 0.0,\n", " \"y2\": 0.0,\n", " \"y_uncertainty\": 0.0,\n", " \"z\": 0.0,\n", " \"z2\": 0.0,\n", " \"z_uncertainty\": 0.0\n", " }\n", "}\n" ] } ], "source": [ "# Compact JSON form\n", "print(here.to_json())" ] }, { "cell_type": "code", "execution_count": 20, "id": "9a09e82a-05a1-4810-9c53-92421c9fff4b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'latitude': 40.0, 'longitude': -120.0, 'elevation': 99.0, 'datum': 'WGS 84', 'x': 0.0, 'y': 0.0, 'z': 0.0, 'latitude_uncertainty': 0.0, 'longitude_uncertainty': 0.0, 'elevation_uncertainty': 0.0, 'x2': 0.0, 'y2': 0.0, 'z2': 0.0, 'x_uncertainty': 0.0, 'y_uncertainty': 0.0, 'z_uncertainty': 0.0, 'declination': {'comments': {'author': None, 'time_stamp': {'time_stamp': '1980-01-01T00:00:00+00:00', 'gps_time': False}, 'value': None, '_class_name': 'comment'}, 'model': 'WMM', 'epoch': None, 'value': 10.0, '_class_name': 'declination'}, 'geographic_location': {'country': None, 'state': None, 'county': None, 'township': None, 'section': None, 'quarter': None, 'parcel': None, '_class_name': 'geographic_location'}, '_class_name': 'station_location'}\n" ] } ], "source": [ "here.from_json(\n", " '{\"location\": {\"declination.model\": \"WMM\", \"declination.value\": 10.0, \"elevation\": 99.0, \"latitude\": 40.0, \"longitude\": -120.0}}'\n", ")\n", "print(here)" ] }, { "cell_type": "code", "execution_count": 21, "id": "e3b88d26-b753-4fe5-974e-51fbb23e0501", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"station_location\": {\n", " \"datum\": \"WGS 84\",\n", " \"declination\": {\n", " \"comments\": {\n", " \"author\": null,\n", " \"time_stamp\": \"1980-01-01T00:00:00+00:00\",\n", " \"value\": null\n", " },\n", " \"epoch\": null,\n", " \"model\": \"WMM\",\n", " \"value\": 10.0\n", " },\n", " \"elevation\": 99.0,\n", " \"elevation_uncertainty\": 0.0,\n", " \"geographic_location\": {\n", " \"country\": null,\n", " \"county\": null,\n", " \"parcel\": null,\n", " \"quarter\": null,\n", " \"section\": null,\n", " \"state\": null,\n", " \"township\": null\n", " },\n", " \"latitude\": 40.0,\n", " \"latitude_uncertainty\": 0.0,\n", " \"longitude\": -120.0,\n", " \"longitude_uncertainty\": 0.0,\n", " \"x\": 0.0,\n", " \"x2\": 0.0,\n", " \"x_uncertainty\": 0.0,\n", " \"y\": 0.0,\n", " \"y2\": 0.0,\n", " \"y_uncertainty\": 0.0,\n", " \"z\": 0.0,\n", " \"z2\": 0.0,\n", " \"z_uncertainty\": 0.0\n", " }\n", "}\n" ] } ], "source": [ "# Nested JSON form\n", "print(here.to_json(nested=True, indent=2))" ] }, { "cell_type": "code", "execution_count": 22, "id": "1e262543-25f5-4759-a34f-be2780678886", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'latitude': 20.0, 'longitude': -110.0, 'elevation': 199.0, 'datum': 'WGS 84', 'x': 0.0, 'y': 0.0, 'z': 0.0, 'latitude_uncertainty': 0.0, 'longitude_uncertainty': 0.0, 'elevation_uncertainty': 0.0, 'x2': 0.0, 'y2': 0.0, 'z2': 0.0, 'x_uncertainty': 0.0, 'y_uncertainty': 0.0, 'z_uncertainty': 0.0, 'declination': {'comments': {'author': None, 'time_stamp': {'time_stamp': '1980-01-01T00:00:00+00:00', 'gps_time': False}, 'value': None, '_class_name': 'comment'}, 'model': 'WMM', 'epoch': None, 'value': -12.0, '_class_name': 'declination'}, 'geographic_location': {'country': None, 'state': None, 'county': None, 'township': None, 'section': None, 'quarter': None, 'parcel': None, '_class_name': 'geographic_location'}, '_class_name': 'station_location'}\n" ] } ], "source": [ "here.from_json(\n", " '{\"location\": {\"declination\": {\"model\": \"WMM\", \"value\": -12.0}, \"elevation\": 199.0, \"latitude\": 20.0, \"longitude\": -110.0}}'\n", ")\n", "print(here)" ] }, { "cell_type": "markdown", "id": "1f31aeb5-cc05-4440-ae6f-144c15c1fee5", "metadata": {}, "source": [ "## XML\n", "\n", "XML is also a common format for metadata, though not as human readable. " ] }, { "cell_type": "code", "execution_count": 23, "id": "2f3c6d12-7c16-4ca5-839b-838c0c01a203", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", " WGS 84\n", " \n", " \n", " \n", " 1980-01-01T00:00:00+00:00\n", " \n", " \n", " \n", " WMM\n", " -12.0\n", " \n", " 199.0\n", " 0.0\n", " \n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", " \n", " 20.0\n", " 0.0\n", " -110.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 0.0\n", " 0.0\n", "\n", "\n" ] } ], "source": [ "print(here.to_xml(string=True))" ] }, { "cell_type": "code", "execution_count": 24, "id": "62120ee5-d5fa-4626-aa96-fa6b074a9ffd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'latitude': -10.0, 'longitude': -110.0, 'elevation': 199.0, 'datum': 'WGS 84', 'x': 0.0, 'y': 0.0, 'z': 0.0, 'latitude_uncertainty': 0.0, 'longitude_uncertainty': 0.0, 'elevation_uncertainty': 0.0, 'x2': 0.0, 'y2': 0.0, 'z2': 0.0, 'x_uncertainty': 0.0, 'y_uncertainty': 0.0, 'z_uncertainty': 0.0, 'declination': {'comments': {'author': None, 'time_stamp': {'time_stamp': '1980-01-01T00:00:00+00:00', 'gps_time': False}, 'value': None, '_class_name': 'comment'}, 'model': 'WMM', 'epoch': None, 'value': -12.0, '_class_name': 'declination'}, 'geographic_location': {'country': None, 'state': None, 'county': None, 'township': None, 'section': None, 'quarter': None, 'parcel': None, '_class_name': 'geographic_location'}, '_class_name': 'station_location'}\n" ] } ], "source": [ "from xml.etree import cElementTree as et\n", "\n", "location = et.Element(\"location\")\n", "lat = et.SubElement(location, \"latitude\")\n", "lat.text = \"-10\"\n", "here.from_xml(location)\n", "print(here)" ] }, { "cell_type": "markdown", "id": "42a76e00-3cc5-4c31-a8f5-61f97edd23b3", "metadata": {}, "source": [ "## Pandas Series\n", "\n", "Pandas is a common data base object that is commonly used for columnar data. A series is basically like a single row in a data base. " ] }, { "cell_type": "code", "execution_count": 25, "id": "461cc4c5-ba35-43f5-b92c-818b17edaebd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "datum WGS 84\n", "declination.comments.author None\n", "declination.comments.time_stamp 1980-01-01T00:00:00+00:00\n", "declination.comments.value None\n", "declination.epoch None\n", "declination.model WMM\n", "declination.value -12.0\n", "elevation 199.0\n", "elevation_uncertainty 0.0\n", "geographic_location.country None\n", "geographic_location.county None\n", "geographic_location.parcel None\n", "geographic_location.quarter None\n", "geographic_location.section None\n", "geographic_location.state None\n", "geographic_location.township None\n", "latitude -10.0\n", "latitude_uncertainty 0.0\n", "longitude -110.0\n", "longitude_uncertainty 0.0\n", "x 0.0\n", "x2 0.0\n", "x_uncertainty 0.0\n", "y 0.0\n", "y2 0.0\n", "y_uncertainty 0.0\n", "z 0.0\n", "z2 0.0\n", "z_uncertainty 0.0\n", "dtype: object\n" ] } ], "source": [ "pd_series = here.to_series()\n", "print(pd_series)" ] }, { "cell_type": "code", "execution_count": 26, "id": "87be9165-986e-41c5-9480-46a90d496e90", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'latitude': -14.0, 'longitude': -112.0, 'elevation': 399.0, 'datum': 'WGS 84', 'x': 0.0, 'y': 0.0, 'z': 0.0, 'latitude_uncertainty': 0.0, 'longitude_uncertainty': 0.0, 'elevation_uncertainty': 0.0, 'x2': 0.0, 'y2': 0.0, 'z2': 0.0, 'x_uncertainty': 0.0, 'y_uncertainty': 0.0, 'z_uncertainty': 0.0, 'declination': {'comments': {'author': None, 'time_stamp': {'time_stamp': '1980-01-01T00:00:00+00:00', 'gps_time': False}, 'value': None, '_class_name': 'comment'}, 'model': 'WMM', 'epoch': None, 'value': -14.0, '_class_name': 'declination'}, 'geographic_location': {'country': None, 'state': None, 'county': None, 'township': None, 'section': None, 'quarter': None, 'parcel': None, '_class_name': 'geographic_location'}, '_class_name': 'station_location'}\n" ] } ], "source": [ "from pandas import Series\n", "\n", "location_series = Series(\n", " {\n", " \"declination.model\": \"WMM\",\n", " \"declination.value\": -14.0,\n", " \"elevation\": 399.0,\n", " \"latitude\": -14.0,\n", " \"longitude\": -112.0,\n", " }\n", ")\n", "\n", "here.from_series(location_series)\n", "print(here)" ] }, { "cell_type": "code", "execution_count": null, "id": "aa2332fb", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "py311", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.11" } }, "nbformat": 4, "nbformat_minor": 5 }