Build MTH5 from USGS Geomagnetic data
Its common to look at observatory data for geomagnetic storms or to use as a remote reference. The USGS provides geomagnetic observatory data for observatories in North America. In the future this will be expanded to the various other observatories using well developed packages like geomagpy.
You will need to know ahead of time what observatories you would like to download data from, dates, and type of data. There are no wildcards. See USGS Geomagnetic webservices for more information on allowed options.
Here we will download 2 days of data from 2 different observatories for the x and y components of calibrated data (‘adjusted’).
[1]:
import pandas as pd
from mth5.clients import MakeMTH5
Create a request DataFrame
The request input is in the form of a pandas.DataFrame with the following columns
Column |
Description |
Options |
|---|---|---|
observatory |
Observatory code |
BDT, BOU, TST, BRW, BRT, BSL, CMO, CMT, DED, DHT, FRD, FRN, GUA, HON, NEW, SHU, SIT, SJG, TUC, USGS, BLC, BRD, CBB, EUA, FCC, IQA, MEA, OTT, RES, SNK, STJ, VIC, YKC, HAD, HER, KAK |
type |
The type of data to download |
variation, adjusted, quasi-definitive, definitivevariation, adjusted (default), quasi-definitive, definitive |
elements |
Components or elements of the geomagnetic data to download, should be a list |
D, DIST, DST, E, E-E, E-N, F, G, H, SQ, SV, UK1, UK2, UK3, UK4, X, Y, ZD, DIST, DST, E, E-E, E-N, F, G, H, SQ, SV, UK1, UK2, UK3, UK4, X, Y, Z |
sampling_period |
Sampling period of data to download in seconds |
1, 60, 3600 |
start |
Start time (YYYY-MM-DDThh:mm:ss) in UTC time |
|
end |
End time (YYYY-MM-DDThh:mm:ss) in UTC time |
[2]:
request_df = pd.DataFrame(
{
"observatory": ["frn", "frn", "ott", "ott"],
"type": ["adjusted"] * 4,
"elements": [["x", "y"]] * 4,
"sampling_period": [1] * 4,
"start": [
"2022-01-01T00:00:00",
"2022-01-03T00:00:00",
"2022-01-01T00:00:00",
"2022-01-03T00:00:00",
],
"end": [
"2022-01-02T00:00:00",
"2022-01-04T00:00:00",
"2022-01-02T00:00:00",
"2022-01-04T00:00:00",
],
}
)
[3]:
request_df
[3]:
| observatory | type | elements | sampling_period | start | end | |
|---|---|---|---|---|---|---|
| 0 | frn | adjusted | [x, y] | 1 | 2022-01-01T00:00:00 | 2022-01-02T00:00:00 |
| 1 | frn | adjusted | [x, y] | 1 | 2022-01-03T00:00:00 | 2022-01-04T00:00:00 |
| 2 | ott | adjusted | [x, y] | 1 | 2022-01-01T00:00:00 | 2022-01-02T00:00:00 |
| 3 | ott | adjusted | [x, y] | 1 | 2022-01-03T00:00:00 | 2022-01-04T00:00:00 |
Adding Run ID
When the request is input automatically run names will be assigned to different windows of time by f"sp{sampling_period}_{count:03}". So the first run is sp1_001, alternatively you can add a run column and name them as you like.
Create MTH5
Once the request is complete get the data. The file name will be created automatically as usgs_geomag_{list of observatories}_{list of elements}.h5.
Note: If the key word interact is set to True then the MTH5 stays open and the returned object is the opened MTH5 file object. If interact is set to False then the MTH5 is closed and the returned object is the path to the created file.
[4]:
mth5_object = MakeMTH5.from_usgs_geomag(request_df, mth5_version="0.2.0", interact=True)
2026-05-07T15:34:36.400006-0600 | WARNING | mth5.mth5 | open_mth5 | line: 795 | usgs_geomag_frn_ott_xy.h5 will be overwritten in 'w' mode
2026-05-07T15:34:37.440363-0600 | INFO | mth5.mth5 | _initialize_file | line: 900 | Initialized MTH5 0.2.0 file C:\Users\jpopelar\OneDrive - DOI\Documents\mtproject\mth5\docs\examples\notebooks\usgs_geomag_frn_ott_xy.h5 in mode w
data
2022-01-01T00:00:00.000Z 22558.020
2022-01-01T00:00:01.000Z 22558.010
2022-01-01T00:00:02.000Z 22558.039
2022-01-01T00:00:03.000Z 22558.045
2022-01-01T00:00:04.000Z 22558.071
... ...
2022-01-01T23:59:56.000Z 22540.641
2022-01-01T23:59:57.000Z 22540.625
2022-01-01T23:59:58.000Z 22540.638
2022-01-01T23:59:59.000Z 22540.666
2022-01-02T00:00:00.000Z 22540.685
[86402 rows x 1 columns]
data
2022-01-01T00:00:00.000Z 5029.007
2022-01-01T00:00:01.000Z 5029.028
2022-01-01T00:00:02.000Z 5029.061
2022-01-01T00:00:03.000Z 5029.055
2022-01-01T00:00:04.000Z 5029.054
... ...
2022-01-01T23:59:56.000Z 5028.165
2022-01-01T23:59:57.000Z 5028.167
2022-01-01T23:59:58.000Z 5028.152
2022-01-01T23:59:59.000Z 5028.183
2022-01-02T00:00:00.000Z 5028.166
[86402 rows x 1 columns]
2026-05-07T15:35:35.491394-0600 | WARNING | mt_timeseries.run_ts | validate_metadata | line: 1102 | sample rate of dataset 1.0 is different than metadata sample rate 0.0 updating metatdata value to 1.0
RunTS Summary:
Survey: USGS-GEOMAG
Station: Fresno
Run: sp1_001
Start: 2022-01-01T00:00:00+00:00
End: 2022-01-02T00:00:01+00:00
Sample Rate: 1.0
Components: ['hx', 'hy']
data
2022-01-03T00:00:00.000Z 22548.540
2022-01-03T00:00:01.000Z 22548.555
2022-01-03T00:00:02.000Z 22548.555
2022-01-03T00:00:03.000Z 22548.581
2022-01-03T00:00:04.000Z 22548.594
... ...
2022-01-03T23:59:56.000Z 22539.686
2022-01-03T23:59:57.000Z 22539.678
2022-01-03T23:59:58.000Z 22539.665
2022-01-03T23:59:59.000Z 22539.671
2022-01-04T00:00:00.000Z 22539.629
[86402 rows x 1 columns]
data
2022-01-03T00:00:00.000Z 5024.867
2022-01-03T00:00:01.000Z 5024.871
2022-01-03T00:00:02.000Z 5024.885
2022-01-03T00:00:03.000Z 5024.890
2022-01-03T00:00:04.000Z 5024.887
... ...
2022-01-03T23:59:56.000Z 5031.129
2022-01-03T23:59:57.000Z 5031.122
2022-01-03T23:59:58.000Z 5031.133
2022-01-03T23:59:59.000Z 5031.142
2022-01-04T00:00:00.000Z 5031.138
[86402 rows x 1 columns]
2026-05-07T15:36:32.699859-0600 | WARNING | mt_timeseries.run_ts | validate_metadata | line: 1102 | sample rate of dataset 1.0 is different than metadata sample rate 0.0 updating metatdata value to 1.0
RunTS Summary:
Survey: USGS-GEOMAG
Station: Fresno
Run: sp1_002
Start: 2022-01-03T00:00:00+00:00
End: 2022-01-04T00:00:01+00:00
Sample Rate: 1.0
Components: ['hx', 'hy']
2026-05-07T15:36:32.740998-0600 | INFO | mth5.groups.base | _add_group | line: 631 | StationGroup Fresno already exists, returning existing group.
2026-05-07T15:36:54.686945-0600 | INFO | mth5.mth5 | close_mth5 | line: 1035 | Flushing and closing C:\Users\jpopelar\OneDrive - DOI\Documents\mtproject\mth5\docs\examples\notebooks\usgs_geomag_frn_ott_xy.h5
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
Cell In[4], line 1
----> 1 mth5_object = MakeMTH5.from_usgs_geomag(request_df, mth5_version="0.2.0", interact=True)
File ~\AppData\Local\miniforge3\envs\mtenv\Lib\site-packages\mth5\clients\make_mth5.py:465, in MakeMTH5.from_usgs_geomag(cls, request_df, **kwargs)
457 kw_dict = maker.get_h5_kwargs()
459 geomag_client = USGSGeomag(
460 save_path=maker.save_path,
461 interact=maker.interact,
462 **kw_dict,
463 )
--> 465 return geomag_client.make_mth5_from_geomag(request_df)
File ~\AppData\Local\miniforge3\envs\mtenv\Lib\site-packages\mth5\clients\geomag.py:655, in USGSGeomag.make_mth5_from_geomag(self, request_df)
644 for row in request_df.itertuples():
645 geomag_client = GeomagClient(
646 observatory=row.observatory,
647 type=row.type,
(...) 652 **{"_ch_map": {"x": "hx", "y": "hy", "z": "hz"}},
653 )
--> 655 run = geomag_client.get_data(run_id=row.run)
656 print(run)
657 station_group = survey_group.stations_group.add_station(
658 run.station_metadata.id,
659 station_metadata=run.station_metadata,
660 )
File ~\AppData\Local\miniforge3\envs\mtenv\Lib\site-packages\mth5\clients\geomag.py:415, in GeomagClient.get_data(self, run_id)
406 ch[element["metadata"]["element"].lower()].append(
407 pd.DataFrame(
408 {
(...) 412 )
413 )
414 else:
--> 415 raise IOError(
416 "Could not connect to server. Error code: "
417 f"{request_obj.status_code}"
418 )
420 survey_metadata = Survey(id="USGS-GEOMAG")
421 station_metadata = self._to_station_metadata(request_json["metadata"])
OSError: Could not connect to server. Error code: 422
Check to make sure everything was downloaded properly
[ ]:
mth5_object.channel_summary.summarize()
mth5_object.channel_summary.to_dataframe()
Have a look at a run
[ ]:
run = mth5_object.get_run("Fresno", "sp1_001", "USGS-GEOMAG")
[ ]:
run_ts = run.to_runts()
run_ts.plot()
Close the MTH5 file
IMPORTANT: Be sure to close the file, otherwise bad things can happen.
[ ]:
mth5_object.close_mth5()
[ ]: