Pydantic Demo#

We will start with the necessary imports

from datetime import datetime, timedelta
from gmpacket.provenance import SoftwareAgent, PersonAgent, OrganizationAgent, Website, Provenance
from gmpacket.feature import (
    Feature,
    FeatureGeometry,
    FeatureProperties,
    Metric,
    MetricDimensions,
    MetricProperties,
    Stream,
    StreamHousing,
    StreamProperties,
    Trace,
    TraceProperties,
)
from gmpacket.packet import Event, GroundMotionPacket

Dealing with Provenance#

person = PersonAgent.from_params("Alex Processor", 
                                 "aprocessor@datagenerator.org", 
                                 "Data Processor")
print(person)

website = Website(url="https://code.usgs.gov/ghsc/esi/groundmotion-processing/#introduction")
software = SoftwareAgent.from_params("gmprocess", "1.2.0", website)
print(software)

org_website = Website(url="https://www.datagenerator.org")
organization = OrganizationAgent.from_params("Data Generator", "Data Provider", org_website)
print(organization)

# the names of the keys are not important, but the values must be valid Person,Software, or 
# OrganizationAgent objects.
agents = {"person": person, "software": software, "organization":organization}
provenance = Provenance(agent=agents)
print(provenance)
label='Alex Processor' name='Alex Processor' email='aprocessor@datagenerator.org' role='Data Processor' prov:type={'$': 'prov:Person', 'type': 'prov:QUALIFIED_NAME'}
label='gmprocess' name='gmprocess' version='1.2.0' website=Website(url='https://code.usgs.gov/ghsc/esi/groundmotion-processing/#introduction', site_type='xsd:anyURI') prov:type={'$': 'prov:SoftwareAgent', 'type': 'prov:QUALIFIED_NAME'}
label='Data Generator' name='Data Generator' role='Data Provider' website=Website(url='https://www.datagenerator.org', site_type='xsd:anyURI') prov:type={'$': 'prov:Organization', 'type': 'prov:QUALIFIED_NAME'}
agent={'person': PersonAgent(label='Alex Processor', name='Alex Processor', email='aprocessor@datagenerator.org', role='Data Processor', prov:type={'$': 'prov:Person', 'type': 'prov:QUALIFIED_NAME'}), 'software': SoftwareAgent(label='gmprocess', name='gmprocess', version='1.2.0', website=Website(url='https://code.usgs.gov/ghsc/esi/groundmotion-processing/#introduction', site_type='xsd:anyURI'), prov:type={'$': 'prov:SoftwareAgent', 'type': 'prov:QUALIFIED_NAME'}), 'organization': OrganizationAgent(label='Data Generator', name='Data Generator', role='Data Provider', website=Website(url='https://www.datagenerator.org', site_type='xsd:anyURI'), prov:type={'$': 'prov:Organization', 'type': 'prov:QUALIFIED_NAME'})} prefix={'seis_prov': 'http://seisprov.org/seis_prov/0.1/#'}

Creating Simple Metrics#

pga_props = MetricProperties(description="Peak Ground Accleration",
                           name="PGA",
                           units= "g",
                           provenance_ids= provenance.getAgents())
print(pga_props)

# for scalar values like PGA, MetricDimensions are not necessary
pga_metric = Metric(properties=pga_props, values=1.5)
print(pga_metric)
description='Peak Ground Accleration' name='PGA' units='g' provenance_ids=['person', 'software', 'organization'] time_of_peak=None
properties=MetricProperties(description='Peak Ground Accleration', name='PGA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None) dimensions=None values=1.5

Creating Complex Metrics#

sa_props = MetricProperties(description="Spectral Accleration",
                             name="SA",
                             units= "g",
                             provenance_ids= provenance.getAgents())
print(sa_props)

sa_dims = MetricDimensions(number=2,
                           names=["critical damping", "period"],
                           units=["%","s"],
                           axis_values=[[5.0],[0.3, 1.0, 3.0]])
print(sa_dims)

sa_metric = Metric(properties=sa_props, dimensions=sa_dims, values=[[1.2, 1.4, 1.6]])
print(sa_metric)
description='Spectral Accleration' name='SA' units='g' provenance_ids=['person', 'software', 'organization'] time_of_peak=None
number=2 names=['critical damping', 'period'] units=['%', 's'] axis_values=[[5.0], [0.3, 1.0, 3.0]]
properties=MetricProperties(description='Spectral Accleration', name='SA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None) dimensions=MetricDimensions(number=2, names=['critical damping', 'period'], units=['%', 's'], axis_values=[[5.0], [0.3, 1.0, 3.0]]) values=[[1.2, 1.4, 1.6]]

Creating Traces#

end_time = datetime.utcnow()
start_time = end_time - timedelta(seconds=30)
sa_trace_props = TraceProperties(channel_code="HNE", 
                                 location_code="10", 
                                 as_recorded=True, 
                                 azimuth=90, 
                                 dip=0,
                                 start_time=start_time, 
                                 end_time=end_time)
print(sa_trace_props)

metrics = [pga_metric, sa_metric]
hne_trace = Trace(properties=sa_trace_props, metrics=metrics)
print(hne_trace)
channel_code='HNE' location_code='10' as_recorded=True azimuth=90.0 dip=0.0 start_time=datetime.datetime(2023, 2, 1, 17, 2, 19, 290235) end_time=datetime.datetime(2023, 2, 1, 17, 2, 49, 290235)
properties=TraceProperties(channel_code='HNE', location_code='10', as_recorded=True, azimuth=90.0, dip=0.0, start_time=datetime.datetime(2023, 2, 1, 17, 2, 19, 290235), end_time=datetime.datetime(2023, 2, 1, 17, 2, 49, 290235)) metrics=[Metric(properties=MetricProperties(description='Peak Ground Accleration', name='PGA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=None, values=1.5), Metric(properties=MetricProperties(description='Spectral Accleration', name='SA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=MetricDimensions(number=2, names=['critical damping', 'period'], units=['%', 's'], axis_values=[[5.0], [0.3, 1.0, 3.0]]), values=[[1.2, 1.4, 1.6]])]

Creating a Stream#

stream_housing = StreamHousing(cosmos_code=10, description="A building", stream_depth=0.0)
print(stream_housing)

stream_props = StreamProperties(band_code="H", 
                                instrument_code="N", 
                                samples_per_second=100.0, 
                                stream_housing=stream_housing)
print(stream_props)

stream = Stream(properties=stream_props, traces=[hne_trace])
print(stream)
cosmos_code=10 description='A building' stream_depth=0.0 stream_location=None
band_code='H' instrument_code='N' samples_per_second=100.0 stream_housing=StreamHousing(cosmos_code=10, description='A building', stream_depth=0.0, stream_location=None)
properties=StreamProperties(band_code='H', instrument_code='N', samples_per_second=100.0, stream_housing=StreamHousing(cosmos_code=10, description='A building', stream_depth=0.0, stream_location=None)) traces=[Trace(properties=TraceProperties(channel_code='HNE', location_code='10', as_recorded=True, azimuth=90.0, dip=0.0, start_time=datetime.datetime(2023, 2, 1, 17, 2, 19, 290235), end_time=datetime.datetime(2023, 2, 1, 17, 2, 49, 290235)), metrics=[Metric(properties=MetricProperties(description='Peak Ground Accleration', name='PGA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=None, values=1.5), Metric(properties=MetricProperties(description='Spectral Accleration', name='SA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=MetricDimensions(number=2, names=['critical damping', 'period'], units=['%', 's'], axis_values=[[5.0], [0.3, 1.0, 3.0]]), values=[[1.2, 1.4, 1.6]])])]

Creating a Feature (station)#

feature_geom = FeatureGeometry(coordinates=[-124.1, 32.0, 1.1])
print(feature_geom)

feature_props = FeatureProperties(network_code="NC", 
                                  station_code="ABCD", 
                                  name="A nice place for picnics", 
                                  streams=[stream])
print(feature_props)

feature = Feature(geometry=feature_geom, properties=feature_props)
print(feature)
coordinates=[-124.1, 32.0, 1.1] type='Point'
network_code='NC' station_code='ABCD' name='A nice place for picnics' streams=[Stream(properties=StreamProperties(band_code='H', instrument_code='N', samples_per_second=100.0, stream_housing=StreamHousing(cosmos_code=10, description='A building', stream_depth=0.0, stream_location=None)), traces=[Trace(properties=TraceProperties(channel_code='HNE', location_code='10', as_recorded=True, azimuth=90.0, dip=0.0, start_time=datetime.datetime(2023, 2, 1, 17, 2, 19, 290235), end_time=datetime.datetime(2023, 2, 1, 17, 2, 49, 290235)), metrics=[Metric(properties=MetricProperties(description='Peak Ground Accleration', name='PGA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=None, values=1.5), Metric(properties=MetricProperties(description='Spectral Accleration', name='SA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=MetricDimensions(number=2, names=['critical damping', 'period'], units=['%', 's'], axis_values=[[5.0], [0.3, 1.0, 3.0]]), values=[[1.2, 1.4, 1.6]])])])] structure_reference_orientation=None
geometry=FeatureGeometry(coordinates=[-124.1, 32.0, 1.1], type='Point') properties=FeatureProperties(network_code='NC', station_code='ABCD', name='A nice place for picnics', streams=[Stream(properties=StreamProperties(band_code='H', instrument_code='N', samples_per_second=100.0, stream_housing=StreamHousing(cosmos_code=10, description='A building', stream_depth=0.0, stream_location=None)), traces=[Trace(properties=TraceProperties(channel_code='HNE', location_code='10', as_recorded=True, azimuth=90.0, dip=0.0, start_time=datetime.datetime(2023, 2, 1, 17, 2, 19, 290235), end_time=datetime.datetime(2023, 2, 1, 17, 2, 49, 290235)), metrics=[Metric(properties=MetricProperties(description='Peak Ground Accleration', name='PGA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=None, values=1.5), Metric(properties=MetricProperties(description='Spectral Accleration', name='SA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=MetricDimensions(number=2, names=['critical damping', 'period'], units=['%', 's'], axis_values=[[5.0], [0.3, 1.0, 3.0]]), values=[[1.2, 1.4, 1.6]])])])], structure_reference_orientation=None) type='Feature'

Creating a Ground Motion Packet#

event = Event.from_params("us2023abcd", datetime.utcnow(), 7.3, 32.1, -120.0, 35.3)
print(event)

gm_packet = GroundMotionPacket(version="0.1dev", 
                               event=event, 
                               provenance=provenance, 
                               features=[feature]
                              )
print(gm_packet)
type='Feature' properties={'id': 'us2023abcd', 'time': datetime.datetime(2023, 2, 1, 17, 2, 49, 309312), 'magnitude': 7.3} geometry={'type': 'Point', 'coordinates': [-120.0, 32.1, 35300.0]}
version='0.1dev' creation_time=datetime.datetime(2023, 2, 1, 17, 2, 49, 258873) event=Event(type='Feature', properties={'id': 'us2023abcd', 'time': datetime.datetime(2023, 2, 1, 17, 2, 49, 309312), 'magnitude': 7.3}, geometry={'type': 'Point', 'coordinates': [-120.0, 32.1, 35300.0]}) provenance=Provenance(agent={'person': PersonAgent(label='Alex Processor', name='Alex Processor', email='aprocessor@datagenerator.org', role='Data Processor', prov:type={'$': 'prov:Person', 'type': 'prov:QUALIFIED_NAME'}), 'software': SoftwareAgent(label='gmprocess', name='gmprocess', version='1.2.0', website=Website(url='https://code.usgs.gov/ghsc/esi/groundmotion-processing/#introduction', site_type='xsd:anyURI'), prov:type={'$': 'prov:SoftwareAgent', 'type': 'prov:QUALIFIED_NAME'}), 'organization': OrganizationAgent(label='Data Generator', name='Data Generator', role='Data Provider', website=Website(url='https://www.datagenerator.org', site_type='xsd:anyURI'), prov:type={'$': 'prov:Organization', 'type': 'prov:QUALIFIED_NAME'})}, prefix={'seis_prov': 'http://seisprov.org/seis_prov/0.1/#'}) features=[Feature(geometry=FeatureGeometry(coordinates=[-124.1, 32.0, 1.1], type='Point'), properties=FeatureProperties(network_code='NC', station_code='ABCD', name='A nice place for picnics', streams=[Stream(properties=StreamProperties(band_code='H', instrument_code='N', samples_per_second=100.0, stream_housing=StreamHousing(cosmos_code=10, description='A building', stream_depth=0.0, stream_location=None)), traces=[Trace(properties=TraceProperties(channel_code='HNE', location_code='10', as_recorded=True, azimuth=90.0, dip=0.0, start_time=datetime.datetime(2023, 2, 1, 17, 2, 19, 290235), end_time=datetime.datetime(2023, 2, 1, 17, 2, 49, 290235)), metrics=[Metric(properties=MetricProperties(description='Peak Ground Accleration', name='PGA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=None, values=1.5), Metric(properties=MetricProperties(description='Spectral Accleration', name='SA', units='g', provenance_ids=['person', 'software', 'organization'], time_of_peak=None), dimensions=MetricDimensions(number=2, names=['critical damping', 'period'], units=['%', 's'], axis_values=[[5.0], [0.3, 1.0, 3.0]]), values=[[1.2, 1.4, 1.6]])])])], structure_reference_orientation=None), type='Feature')] type='FeatureCollection'

Exporting GroundMotion Packets#

print(gm_packet.as_json())

df = gm_packet.to_dataframe()
df
{"version":"0.1dev","creation_time":"2023-02-01T17:02:49Z","event":{"type":"Feature","properties":{"id":"us2023abcd","time":"2023-02-01T17:02:49Z","magnitude":7.3},"geometry":{"type":"Point","coordinates":[-120,32.1,35300]}},"provenance":{"agent":{"person":{"prov:label":"Alex Processor","seis_prov:name":"Alex Processor","seis_prov:email":"aprocessor@datagenerator.org","seis_prov:role":"Data Processor","prov:type":{"$":"prov:Person","type":"prov:QUALIFIED_NAME"}},"software":{"prov:label":"gmprocess","seis_prov:software_name":"gmprocess","seis_prov:software_version":"1.2.0","seis_prov:website":{"$":"https://code.usgs.gov/ghsc/esi/groundmotion-processing/#introduction","type":"xsd:anyURI"},"prov:type":{"$":"prov:SoftwareAgent","type":"prov:QUALIFIED_NAME"}},"organization":{"prov:label":"Data Generator","seis_prov:name":"Data Generator","seis_prov:role":"Data Provider","seis_prov:website":{"$":"https://www.datagenerator.org","type":"xsd:anyURI"},"prov:type":{"$":"prov:Organization","type":"prov:QUALIFIED_NAME"}}},"prefix":{"seis_prov":"http://seisprov.org/seis_prov/0.1/#"}},"features":[{"geometry":{"coordinates":[-124.1,32,1.1],"type":"Point"},"properties":{"network_code":"NC","station_code":"ABCD","name":"A nice place for picnics","streams":[{"properties":{"band_code":"H","instrument_code":"N","samples_per_second":100,"stream_housing":{"cosmos_code":10,"description":"A building","stream_depth":0,"stream_location":null}},"traces":[{"properties":{"channel_code":"HNE","location_code":"10","as_recorded":true,"azimuth":90,"dip":0,"start_time":"2023-02-01T17:02:19Z","end_time":"2023-02-01T17:02:49Z"},"metrics":[{"properties":{"description":"Peak Ground Accleration","name":"PGA","units":"g","provenance_ids":["person","software","organization"],"time_of_peak":null},"dimensions":null,"values":1.5},{"properties":{"description":"Spectral Accleration","name":"SA","units":"g","provenance_ids":["person","software","organization"],"time_of_peak":null},"dimensions":{"number":2,"names":["critical damping","period"],"units":["%","s"],"axis_values":[[5],[0.3,1,3]]},"values":[[1.2,1.4,1.6]]}]}]}],"structure_reference_orientation":null},"type":"Feature"}],"type":"FeatureCollection"}
id time magnitude event_longitude event_latitude event_depth network station station_name station_longitude station_latitude station_elevation channel location PGA(g) SA(g)_critical_damping_5.0%_period_0.3s SA(g)_critical_damping_5.0%_period_1.0s SA(g)_critical_damping_5.0%_period_3.0s
0 us2023abcd 2023-02-01 17:02:49.309312 7.3 -120.0 32.1 35300.0 NC ABCD A nice place for picnics -124.1 32.0 1.1 HNE 10 1.5 1.2 1.4 1.6
1 us2023abcd 2023-02-01 17:02:49.309312 7.3 -120.0 32.1 35300.0 NC ABCD A nice place for picnics -124.1 32.0 1.1 HNE 10 1.5 1.2 1.4 1.6