Airborne Time-Domain¶
This type of survey can be used to store airborne time-domain electromagnetic (ATEM) data defined by a fixed transmitter-receiver loop configuration. The survey is made up of two entities (AirborneTEMTransmitters and AirborneTEMReceivers) linked by their metadata.
The following example shows how to generate an airborne TEM survey with associated data stored in geoh5
format and accessible from Geoscience ANALYST.
[1]:
import numpy as np
from geoh5py.objects import AirborneTEMReceivers, AirborneTEMTransmitters
from geoh5py.workspace import Workspace
# Create a new project
workspace = Workspace("my_project.geoh5")
# Define the pole locations
n_stations = 9
n_lines = 2
x_loc, y_loc = np.meshgrid(
np.linspace(0, 60, n_stations), np.linspace(-20, 20.0, n_lines)
)
vertices = np.c_[x_loc.ravel(), y_loc.ravel(), np.zeros_like(x_loc).ravel()]
# Assign a line ID to the poles (vertices)
parts = np.kron(np.arange(n_lines), np.ones(n_stations)).astype("int")
# Create the survey as a coincident loop system
aem_receivers = AirborneTEMReceivers.create(workspace, vertices=vertices, parts=parts)
aem_transmitters = AirborneTEMTransmitters.create(
workspace, vertices=vertices, parts=parts
)
We have so far created two seperate entities, one for transmitter locations and another for the receivers. In order to finalize the survey, the association must be made between the two entities:
[2]:
aem_receivers.transmitters = aem_transmitters
or equivalently
[3]:
aem_transmitters.receivers = aem_receivers
Only one of the two options above is needed.
Once linked, the two entities will share changes applied to the metadata. For example, changing the input_type
property on the transmitters yield:
[4]:
aem_transmitters.input_type = "Tx and Rx"
print(aem_receivers.input_type)
Tx and Rx
Metadata¶
Along with the survey object itself, the metadata contains all the necessary information to define the geophysical experiment.
[5]:
aem_receivers.metadata
[5]:
{'EM Dataset': {'Channels': [],
'Input type': 'Tx and Rx',
'Property groups': [],
'Receivers': UUID('e035c1a2-91f0-48b7-b51e-f9fc2d16fcb4'),
'Survey type': 'Airborne TEM',
'Transmitters': UUID('324a8132-7da3-400b-8d2e-dde34cb3bb2c'),
'Unit': 'Milliseconds (ms)',
'Waveform': {'Timing mark': 0.0}}}
Channels¶
List of time channels at which the data are provided.
[6]:
aem_receivers.channels = np.logspace(-5, -2, 10) # Simple sweep from 1 to 10 ms
Input type¶
Label defining how the survey was created.
Rx
: Survey defined from theAirborneTEMReceivers
positions, with theAirborneTEMTransmitters
added from offsets.Tx
: Survey defined from theAirborneTEMTransmitters
position, with theAirborneTEMReceivers
added from offsets.Tx and Rx
: Survey defined by both theAirborneTEMTransmitters
and theAirborneTEMReceivers
positions.
Property groups¶
List of PropertyGroups defining the various data components (e.g. dBzdt
, Bz
, …). It is expected that each component contains data channels at all times and in the same order as defined in Channels
.
The class method add_component_data can help users add data from nested dictionaries. Below is an example using four components:
[7]:
# Create some simple data
def data_fun(t):
return 1.0 / t * np.sin(np.pi * (x_loc * y_loc).ravel() / 800.0)
# Create a nested dictionary of time data.
data = {
"dBdt": {
f"time[{tt}]": {"values": data_fun(time)}
for tt, time in enumerate(aem_receivers.channels)
}
}
aem_receivers.add_components_data(data)
[7]:
[<geoh5py.groups.property_group.PropertyGroup at 0x7f61fb6d1b40>]
Metadata are also updated to reflect the addition of component data.
[8]:
aem_receivers.metadata
[8]:
{'EM Dataset': {'Channels': [9.999999999999999e-06,
2.154434690031882e-05,
4.6415888336127825e-05,
9.999999999999999e-05,
0.00021544346900318823,
0.00046415888336127773,
0.001,
0.002154434690031882,
0.004641588833612777,
0.01],
'Input type': 'Tx and Rx',
'Property groups': ['dBdt'],
'Receivers': UUID('e035c1a2-91f0-48b7-b51e-f9fc2d16fcb4'),
'Survey type': 'Airborne TEM',
'Transmitters': UUID('324a8132-7da3-400b-8d2e-dde34cb3bb2c'),
'Unit': 'Milliseconds (ms)',
'Waveform': {'Timing mark': 0.0}}}
Data channels associated with each component can be quickly accessed through the BaseEMSurvey.components property:
[9]:
aem_receivers.components["dBdt"]
[9]:
[<geoh5py.data.float_data.FloatData at 0x7f61e7953bb0>,
<geoh5py.data.float_data.FloatData at 0x7f61e7950e80>,
<geoh5py.data.float_data.FloatData at 0x7f61e79510c0>,
<geoh5py.data.float_data.FloatData at 0x7f61e7950e20>,
<geoh5py.data.float_data.FloatData at 0x7f61e7950b50>,
<geoh5py.data.float_data.FloatData at 0x7f61e7950220>,
<geoh5py.data.float_data.FloatData at 0x7f61fb501750>,
<geoh5py.data.float_data.FloatData at 0x7f61fb503d00>,
<geoh5py.data.float_data.FloatData at 0x7f61fb502ef0>,
<geoh5py.data.float_data.FloatData at 0x7f61fb503b20>]
Receivers¶
Generic label used for surveys to identify the receiver entity. References to itself in the case of AirborneTEMReceivers
.
Survey type¶
Static label identifier for Airborne TEM
survey type.
Transmitters¶
Generic label used for surveys to identify the transmitter entity. References to itself in the case of AirborneTEMTransmitters
.
Unit¶
Units for time sampling of the data - must be one of Seconds (s)
, Milliseconds (ms)
, Microseconds (us)
or Nanoseconds (ns)
.
Loop radius¶
Specifies the transmitter loop radius.
Custom fields¶
Metadata
are stored in geoh5
as a json
structure allowing for custom data fields to be added to the survey. Information such as flight data, date/time, offsets, etc. can be added as string
, float
and int
.
[10]:
aem_receivers.edit_metadata({"Weather": "sunny"})
/home/docs/checkouts/readthedocs.org/user_builds/mirageoscience-geoh5py/conda/latest/lib/python3.10/site-packages/geoh5py/objects/surveys/electromagnetics/base.py:394: UserWarning: DEPRECATION WARNINGThe method 'edit_metadata' will be deprecated in 0.10 version. It will be replaced by 'edit_em_metadata'
warn(
Aternatively, a uuid.UUID
value can be used if the information is to be provided at every survey position.
[11]:
# Add a new data entry
abc = aem_receivers.add_data(
{"abc": {"values": np.random.randn(aem_receivers.n_vertices)}}
)
# Assign the data as 'Weather' metadata
aem_receivers.edit_metadata({"Weather": abc.uid})
Geoscience ANALYST
will automatically create a link referencing the data field to the entity in the project tree.
Reserved keywords¶
For known metadata, such as flight dynamics (yaw
, pitch
, roll
) and offsets (inline
, crossline
, vertical
) the suffix property
and value
will get replaced based on the input value:
[12]:
aem_receivers.yaw = 15.0
[13]:
aem_receivers.yaw = abc.uid # Assign to the yaw property
[14]:
workspace.close()