#!/usr/bin/env python # coding: utf-8 # # VirES - access to Østred, CHAMP, Cryosat-2, and Swarm virtual observatories data # # This notebook demonstrates access to Østred, CHAMP, Cryosat-2 and Swarm VOBS_1M and VOBS_4M virtual observatory data via the VirES for Swarm API. # # Avalable observed and core field data collections # # | Collection Name | Description | # |---|---| # | `SW_OPER_VOBS_1M_2_` | Swarm 1 month data from all virtual observatories | # | `SW_OPER_VOBS_1M_2_:` | Swarm 1 month data from one selected virtual observatory | # | `SW_OPER_VOBS_4M_2_` | Swarm 4 month data from all virtual observatories | # | `SW_OPER_VOBS_4M_2_:` | Swarm 4 months data from one selected virtual observatory | # | `CH_OPER_VOBS_4M_2_` | CHAMP 4 month data from all virtual observatories | # | `CH_OPER_VOBS_4M_2_:` | CHAMP 4 months data from one selected virtual observatory | # | `CR_OPER_VOBS_4M_2_` | Cryosat-2 4 month data from all virtual observatories | # | `CR_OPER_VOBS_4M_2_:` | Cryosat-2 4 months data from one selected virtual observatory | # | `OR_OPER_VOBS_4M_2_` | Østred 4 month data from all virtual observatories | # | `OR_OPER_VOBS_4M_2_:` | Østred 4 months data from one selected virtual observatory | # | `CO_OPER_VOBS_4M_2_` | Ørsted, CHAMP, CryoSat-2 and Swarm composite 4 month data from all virtual observatories | # | `CO_OPER_VOBS_4M_2_:` | Ørsted, CHAMP, CryoSat-2 and Swarm composite 4 months data from one selected virtual observatory | # # Avalable field secular variation data collections # # | Collection Name | Description | # |---|---| # | `SW_OPER_VOBS_1M_2_:SecularVariation` | Swarm 1 month secular variation data from all virtual observatories | # | `SW_OPER_VOBS_1M_2_:SecularVariation:` | Swarm 1 month secular variation data from one selected virtual observatory | # | `SW_OPER_VOBS_4M_2_:SecularVariation` | Swarm 4 month secular variation data from all virtual observatories | # | `SW_OPER_VOBS_4M_2_:SecularVariation:` | Swarm 4 months secular variation data from one selected virtual observatory | # | `CH_OPER_VOBS_4M_2_:SecularVariation` | CHAMP 4 month secular variation data from all virtual observatories | # | `CH_OPER_VOBS_4M_2_:SecularVariation:` | CHAMP 4 secular variation months data from one selected virtual observatory | # | `CR_OPER_VOBS_4M_2_:SecularVariation` | Cryosat-2 4 month secular variation data from all virtual observatories | # | `CR_OPER_VOBS_4M_2_:SecularVariation:` | Cryosat-2 4 months secular variation data from one selected virtual observatory | # | `OR_OPER_VOBS_4M_2_:SecularVariation` | Østred 4 month secular variation data from all virtual observatories | # | `OR_OPER_VOBS_4M_2_:SecularVariation:` | Østred 4 months secular variation data from one selected virtual observatory | # | `CO_OPER_VOBS_4M_2_:SecularVariation` | Ørsted, CHAMP, CryoSat-2 and Swarm composite 4 month secular variation data from all virtual observatories | # | `CO_OPER_VOBS_4M_2_:SecularVariation:` | Ørsted, CHAMP, CryoSat-2 and Swarm composite 4 months secular variation data from one selected virtual observatory | # # # The `` is a 7-letter "virtual observatories" identifier, unique for each of the 300 "virtual observatories". # # Avalable observed and core filed variables (same for all collections) # # | Variable | Unit | Dimension | Description | # |---|---|---|---| # | `SiteCode` | $-$ | char [7] | virtual observatory identifier | # | `Timestamp` | $-$ | scalar | UTC time of observation | # | `Latitude` | $\text{deg}$ | scalar | ITRF geocentric latitude | # | `Longitude` | $\text{deg}$ | scalar | ITRF geocentric longitude | # | `Radius` | $\text{m}$ | scalar | ITRF geocentric radius | # | `B_CF` | $\text{nT}$ | vector [3] | Core magnetic field vector in ITRF NEC frame. | # | `B_OB` | $\text{nT}$ | vector [3] | Observed magnetic field vector in ITRF NEC frame. | # | `sigma_CF` | $\text{nT}$ | vector [3] | Estimated error of the core magnetic field vector in ITRF NEC frame. | # | `sigma_OB` | $\text{nT}$ | vector [3] | Estimated error of the observed magnetic field vector in ITRF NEC frame. | # # Avalable secular variation variables (same for all collections) # # | Variable | Unit | Dimension | Description | # |---|---|---|---| # | `SiteCode` | $-$ | char [7] | virtual observatory identifier | # | `Timestamp` | $-$ | scalar | UTC time of observation | # | `Latitude` | $\text{deg}$ | scalar | ITRF geocentric latitude | # | `Longitude` | $\text{deg}$ | scalar | ITRF geocentric longitude | # | `Radius` | $\text{m}$ | scalar | ITRF geocentric radius | # | `B_SV` | $\text{nT}/\text{yr}$ | vector [3] | Field secular variation vector in ITRF NEC frame. | # | `sigma_SV` | $\text{nT}/\text{yr}$ | vector [3] | Estimated error of the field secular variation vector in ITRF NEC frame. | # # In[1]: from numpy import average from matplotlib.pyplot import figure, subplot, show from viresclient import SwarmRequest VOBS_VARIABLES = ['SiteCode', 'B_CF', 'B_OB', 'sigma_CF', 'sigma_OB'] VOBS_SV_VARIABLES = ['SiteCode', 'B_SV', 'sigma_SV'] EARTH_RADIUS = 6371000 server_url = None # default VirES server request = SwarmRequest(server_url) # ## Swarm, CHAMP, and Cryosat-2 - VOBS_1M and VOBS_4M - one virtual observatory # In[2]: from datetime import datetime site = 'S77W114' collections = { 'SW_1M': 'SW_OPER_VOBS_1M_2_', 'SW_4M': 'SW_OPER_VOBS_4M_2_', #'CH_1M': 'CH_OPER_VOBS_1M_2_', 'CH_4M': 'CH_OPER_VOBS_4M_2_', 'CR_4M': 'CR_OPER_VOBS_4M_2_', 'OR_4M': 'OR_OPER_VOBS_4M_2_', 'CO_4M': 'CO_OPER_VOBS_4M_2_', } data = {} data_sv = {} def download(collection, variables): print() print(collection) request.set_collection(collection) request.set_products(measurements=variables) return request.get_between( start_time='2000-01-01T10:00:00Z', end_time=datetime.now(), asynchronous=False, ).as_xarray() for source, collection in collections.items(): data[source] = download(f'{collection}:{site}', VOBS_VARIABLES) print(data[source]) data_sv[source] = download(f'{collection}:SecularVariation:{site}', VOBS_SV_VARIABLES) print(data_sv[source]) # In[3]: get_ipython().run_line_magic('matplotlib', 'inline') fig = figure(figsize=(24, 18), dpi=100) meta = { 'SW_1M': {'mission': 'Swarm', 'sampling': '1M', 'symbol': 'o', 'color': 'tab:blue'}, 'SW_4M': {'mission': 'Swarm', 'sampling': '4M', 'symbol': 's', 'color': 'tab:blue'}, #'CH_1M': {'mission': 'CHAMP', 'sampling': '1M', 'symbol': 'o', 'color': 'tab:green'}, 'CH_4M': {'mission': 'CHAMP', 'sampling': '4M', 'symbol': 's', 'color': 'tab:green'}, 'CR_4M': {'mission': 'Cryosat-2', 'sampling': '4M', 'symbol': 's', 'color': 'tab:red'}, 'OR_4M': {'mission': 'Ørsted', 'sampling': '4M', 'symbol': 's', 'color': 'tab:orange'}, 'CO_4M': {'mission': 'composit', 'sampling': '4M', 'symbol': 's', 'color': 'tab:olive'}, } ax = subplot(3, 1, 1) idx = 0 plots, labels = [], [] for type_, data_ in data.items(): ax.errorbar(data_['Timestamp'].values, data_['B_OB'].values[:, idx], data_['sigma_OB'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.errorbar(data_['Timestamp'].values, data_['B_CF'].values[:, idx], data_['sigma_CF'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.fill_between( data_['Timestamp'].values, data_['B_OB'].values[:, idx] - data_['sigma_OB'].values[:, idx], data_['B_OB'].values[:, idx] + data_['sigma_OB'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) ax.fill_between( data_['Timestamp'].values, data_['B_CF'].values[:, idx] - data_['sigma_CF'].values[:, idx], data_['B_CF'].values[:, idx] + data_['sigma_CF'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) for type_, data_ in data.items(): plots.append(ax.plot(data_['Timestamp'].values, data_['B_CF'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=4)[0]) plots.append(ax.plot(data_['Timestamp'].values, data_['B_OB'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=5, mfc='none')[0]) mean_altitude = average(data_['Radius'].values) - EARTH_RADIUS labels.extend([ f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - core field at {1e-3 * mean_altitude :.0f}km', f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - observed field at {1e-3 * mean_altitude :.0f}km' ]) ax.set_title(site) ax.set_ylabel('B_N / nT') ax.grid() ax.legend(plots, labels) ax = subplot(3, 1, 2) idx = 1 plots, labels = [], [] for type_, data_ in data.items(): ax.errorbar(data_['Timestamp'].values, data_['B_OB'].values[:, idx], data_['sigma_OB'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.errorbar(data_['Timestamp'].values, data_['B_CF'].values[:, idx], data_['sigma_CF'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.fill_between( data_['Timestamp'].values, data_['B_OB'].values[:, idx] - data_['sigma_OB'].values[:, idx], data_['B_OB'].values[:, idx] + data_['sigma_OB'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) ax.fill_between( data_['Timestamp'].values, data_['B_CF'].values[:, idx] - data_['sigma_CF'].values[:, idx], data_['B_CF'].values[:, idx] + data_['sigma_CF'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) for type_, data_ in data.items(): plots.append(ax.plot(data_['Timestamp'].values, data_['B_CF'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=4)[0]) plots.append(ax.plot(data_['Timestamp'].values, data_['B_OB'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=5, mfc='none')[0]) mean_altitude = average(data_['Radius'].values) - EARTH_RADIUS labels.extend([ f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - core field at {1e-3 * mean_altitude :.0f}km', f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - observed field at {1e-3 * mean_altitude :.0f}km' ]) ax.set_title(site) ax.set_ylabel('B_E / nT') ax.grid() ax.legend(plots, labels) ax = subplot(3, 1, 3) idx = 2 plots, labels = [], [] for type_, data_ in data.items(): ax.errorbar(data_['Timestamp'].values, data_['B_OB'].values[:, idx], data_['sigma_OB'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.errorbar(data_['Timestamp'].values, data_['B_CF'].values[:, idx], data_['sigma_CF'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.fill_between( data_['Timestamp'].values, data_['B_OB'].values[:, idx] - data_['sigma_OB'].values[:, idx], data_['B_OB'].values[:, idx] + data_['sigma_OB'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) ax.fill_between( data_['Timestamp'].values, data_['B_CF'].values[:, idx] - data_['sigma_CF'].values[:, idx], data_['B_CF'].values[:, idx] + data_['sigma_CF'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) for type_, data_ in data.items(): plots.append(ax.plot(data_['Timestamp'].values, data_['B_CF'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=4)[0]) plots.append(ax.plot(data_['Timestamp'].values, data_['B_OB'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=5, mfc='none')[0]) mean_altitude = average(data_['Radius'].values) - EARTH_RADIUS labels.extend([ f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - core field at {1e-3 * mean_altitude :.0f}km', f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - observed field at {1e-3 * mean_altitude :.0f}km' ]) ax.set_title(site) ax.set_ylabel('B_C / nT') ax.grid() ax.legend(plots, labels) ("") # In[4]: get_ipython().run_line_magic('matplotlib', 'inline') fig = figure(figsize=(24, 18), dpi=100) meta = { 'SW_1M': {'mission': 'Swarm', 'sampling': '1M', 'symbol': 'o', 'color': 'tab:blue'}, 'SW_4M': {'mission': 'Swarm', 'sampling': '4M', 'symbol': 's', 'color': 'tab:blue'}, #'CH_1M': {'mission': 'CHAMP', 'sampling': '1M', 'symbol': 'o', 'color': 'tab:green'}, 'CH_4M': {'mission': 'CHAMP', 'sampling': '4M', 'symbol': 's', 'color': 'tab:green'}, 'CR_4M': {'mission': 'Cryosat-2', 'sampling': '4M', 'symbol': 's', 'color': 'tab:red'}, 'OR_4M': {'mission': 'Ørsted', 'sampling': '4M', 'symbol': 's', 'color': 'tab:orange'}, 'CO_4M': {'mission': 'composit', 'sampling': '4M', 'symbol': 's', 'color': 'tab:olive'}, } ax = subplot(3, 1, 1) idx = 0 plots, labels = [], [] for type_, data_ in data_sv.items(): ax.errorbar(data_['Timestamp'].values, data_['B_SV'].values[:, idx], data_['sigma_SV'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.fill_between( data_['Timestamp'].values, data_['B_SV'].values[:, idx] - data_['sigma_SV'].values[:, idx], data_['B_SV'].values[:, idx] + data_['sigma_SV'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) for type_, data_ in data_sv.items(): plots.append(ax.plot(data_['Timestamp'].values, data_['B_SV'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=4)[0]) mean_altitude = average(data_['Radius'].values) - EARTH_RADIUS labels.append(f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - secular variation at {1e-3 * mean_altitude :.0f}km') ax.set_title(site) ax.set_ylabel('dB_N/dt / nT/yr') ax.grid() ax.legend(plots, labels) ax = subplot(3, 1, 2) idx = 1 plots, labels = [], [] for type_, data_ in data_sv.items(): ax.errorbar(data_['Timestamp'].values, data_['B_SV'].values[:, idx], data_['sigma_SV'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.fill_between( data_['Timestamp'].values, data_['B_SV'].values[:, idx] - data_['sigma_SV'].values[:, idx], data_['B_SV'].values[:, idx] + data_['sigma_SV'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) for type_, data_ in data_sv.items(): plots.append(ax.plot(data_['Timestamp'].values, data_['B_SV'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=4)[0]) mean_altitude = average(data_['Radius'].values) - EARTH_RADIUS labels.append(f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - secular variation at {1e-3 * mean_altitude :.0f}km') ax.set_title(site) ax.set_ylabel('dB_E/dt / nT/yr') ax.grid() ax.legend(plots, labels) ax = subplot(3, 1, 3) idx = 2 plots, labels = [], [] for type_, data_ in data_sv.items(): ax.errorbar(data_['Timestamp'].values, data_['B_SV'].values[:, idx], data_['sigma_SV'].values[:, idx], color=meta[type_]['color'], alpha=0.5) ax.fill_between( data_['Timestamp'].values, data_['B_SV'].values[:, idx] - data_['sigma_SV'].values[:, idx], data_['B_SV'].values[:, idx] + data_['sigma_SV'].values[:, idx], color=meta[type_]['color'], alpha=0.1, ec=None, ) for type_, data_ in data_sv.items(): plots.append(ax.plot(data_['Timestamp'].values, data_['B_SV'].values[:, idx], meta[type_]['symbol'], color=meta[type_]['color'], ms=4)[0]) mean_altitude = average(data_['Radius'].values) - EARTH_RADIUS labels.append(f'{meta[type_]["mission"]} {meta[type_]["sampling"]} - secular variation at {1e-3 * mean_altitude :.0f}km') ax.set_title(site) ax.set_ylabel('dB_C/dt / nT/yr') ax.grid() ax.legend(plots, labels) ("")