resistics_readers.lemi.b423 module¶
Module for Lemi B423 data Lemi B423 always records channels in the following order
Hx, Hy, Hz, Ex, Ey
The Lemi B423 binary files are constructed from a 1024 text header followed by repeating records with the following definitions (PPS is short for deviation from PPS and PLL is short for PLL accuracy):
SECOND_TIMESTAMP, SAMPLE_NUM [0-FS], HX, HY, HZ, EX, EY, PPS, PLL
These are interpreted to have byte types
L, H, l, l, l, l, l, h, h
- pydantic model resistics_readers.lemi.b423.TimeMetadataB423[source]¶
Bases:
resistics_readers.multifile.TimeMetadataSingle
This is an extension of TimeMetadataSingle for a single B423 file
Show JSON schema
{ "title": "TimeMetadataB423", "description": "This is an extension of TimeMetadataSingle for a single B423 file", "type": "object", "properties": { "file_info": { "$ref": "#/definitions/ResisticsFile" }, "fs": { "title": "Fs", "type": "number" }, "chans": { "title": "Chans", "type": "array", "items": { "type": "string" } }, "n_chans": { "title": "N Chans", "type": "integer" }, "n_samples": { "title": "N Samples", "type": "integer" }, "first_time": { "title": "First Time", "pattern": "%Y-%m-%d %H:%M:%S.%f_%o_%q_%v", "examples": [ "2021-01-01 00:00:00.000061_035156_250000_000000" ] }, "last_time": { "title": "Last Time", "pattern": "%Y-%m-%d %H:%M:%S.%f_%o_%q_%v", "examples": [ "2021-01-01 00:00:00.000061_035156_250000_000000" ] }, "system": { "title": "System", "default": "", "type": "string" }, "serial": { "title": "Serial", "default": "", "type": "string" }, "wgs84_latitude": { "title": "Wgs84 Latitude", "default": -999.0, "type": "number" }, "wgs84_longitude": { "title": "Wgs84 Longitude", "default": -999.0, "type": "number" }, "easting": { "title": "Easting", "default": -999.0, "type": "number" }, "northing": { "title": "Northing", "default": -999.0, "type": "number" }, "elevation": { "title": "Elevation", "default": -999.0, "type": "number" }, "chans_metadata": { "title": "Chans Metadata", "type": "object", "additionalProperties": { "$ref": "#/definitions/ChanMetadata" } }, "history": { "title": "History", "default": { "records": [] }, "allOf": [ { "$ref": "#/definitions/History" } ] }, "data_file": { "title": "Data File", "type": "string" }, "data_byte_start": { "title": "Data Byte Start", "type": "integer" }, "scalings": { "title": "Scalings", "type": "object", "additionalProperties": { "type": "number" } } }, "required": [ "fs", "chans", "n_samples", "first_time", "last_time", "chans_metadata", "data_file", "data_byte_start", "scalings" ], "definitions": { "ResisticsFile": { "title": "ResisticsFile", "description": "Required information for writing out a resistics file", "type": "object", "properties": { "created_on_local": { "title": "Created On Local", "type": "string", "format": "date-time" }, "created_on_utc": { "title": "Created On Utc", "type": "string", "format": "date-time" }, "version": { "title": "Version", "type": "string" } } }, "ChanMetadata": { "title": "ChanMetadata", "description": "Channel metadata", "type": "object", "properties": { "name": { "title": "Name", "type": "string" }, "data_files": { "title": "Data Files", "type": "array", "items": { "type": "string" } }, "chan_type": { "title": "Chan Type", "type": "string" }, "chan_source": { "title": "Chan Source", "type": "string" }, "sensor": { "title": "Sensor", "default": "", "type": "string" }, "serial": { "title": "Serial", "default": "", "type": "string" }, "gain1": { "title": "Gain1", "default": 1, "type": "number" }, "gain2": { "title": "Gain2", "default": 1, "type": "number" }, "scaling": { "title": "Scaling", "default": 1, "type": "number" }, "chopper": { "title": "Chopper", "default": false, "type": "boolean" }, "dipole_dist": { "title": "Dipole Dist", "default": 1, "type": "number" }, "sensor_calibration_file": { "title": "Sensor Calibration File", "default": "", "type": "string" }, "instrument_calibration_file": { "title": "Instrument Calibration File", "default": "", "type": "string" } }, "required": [ "name" ] }, "Record": { "title": "Record", "description": "Class to hold a record\n\nA record holds information about a process that was run. It is intended to\ntrack processes applied to data, allowing a process history to be saved\nalong with any datasets.\n\nExamples\n--------\nA simple example of creating a process record\n\n>>> from resistics.common import Record\n>>> messages = [\"message 1\", \"message 2\"]\n>>> record = Record(\n... creator={\"name\": \"example\", \"parameter1\": 15},\n... messages=messages,\n... record_type=\"example\"\n... )\n>>> record.summary()\n{\n 'time_local': '...',\n 'time_utc': '...',\n 'creator': {'name': 'example', 'parameter1': 15},\n 'messages': ['message 1', 'message 2'],\n 'record_type': 'example'\n}", "type": "object", "properties": { "time_local": { "title": "Time Local", "type": "string", "format": "date-time" }, "time_utc": { "title": "Time Utc", "type": "string", "format": "date-time" }, "creator": { "title": "Creator", "type": "object" }, "messages": { "title": "Messages", "type": "array", "items": { "type": "string" } }, "record_type": { "title": "Record Type", "type": "string" } }, "required": [ "creator", "messages", "record_type" ] }, "History": { "title": "History", "description": "Class for storing processing history\n\nParameters\n----------\nrecords : List[Record], optional\n List of records, by default []\n\nExamples\n--------\n>>> from resistics.testing import record_example1, record_example2\n>>> from resistics.common import History\n>>> record1 = record_example1()\n>>> record2 = record_example2()\n>>> history = History(records=[record1, record2])\n>>> history.summary()\n{\n 'records': [\n {\n 'time_local': '...',\n 'time_utc': '...',\n 'creator': {\n 'name': 'example1',\n 'a': 5,\n 'b': -7.0\n },\n 'messages': ['Message 1', 'Message 2'],\n 'record_type': 'process'\n },\n {\n 'time_local': '...',\n 'time_utc': '...',\n 'creator': {\n 'name': 'example2',\n 'a': 'parzen',\n 'b': -21\n },\n 'messages': ['Message 5', 'Message 6'],\n 'record_type': 'process'\n }\n ]\n}", "type": "object", "properties": { "records": { "title": "Records", "default": [], "type": "array", "items": { "$ref": "#/definitions/Record" } } } } } }
- field data_byte_start: int = PydanticUndefined¶
The byte offset from the beginning of the file to the start of the data
- field scalings: Dict[str, float] = PydanticUndefined¶
Scalings in the B423 ASCII header
- resistics_readers.lemi.b423.make_subdir_B423_metadata(dir_path: pathlib.Path, fs: float, hx_serial: int = 0, hy_serial: int = 0, hz_serial: int = 0, h_gain: int = 1, dx: float = 1, dy: float = 1, folders: Optional[List[str]] = None) → None[source]¶
Construct B423 headers for sub directories of a folder
- Parameters
dir_path (Path) – The path to the folder
fs (float) – The sampling frequency, Hz
hx_serial (str, optional) – The x direction magnetic serial, used for calibration
hy_serial (str, optional) – The y direction magnetic serial, used for calibration
hz_serial (str, optional) – The z direction magnetic serial, used for calibration
h_gain (int) – Any gain on the magnetic channels which will need to be removed
dx (float, optional) – Distance between x electrodes
dy (float, optional) – Distance between y electrodes
folders (List, optional) – An optional list of subfolders, by default None. If None, all the subfolders will be processed
- resistics_readers.lemi.b423.make_B423_metadata(dir_path: pathlib.Path, fs: float, hx_serial: int = 0, hy_serial: int = 0, hz_serial: int = 0, h_gain: int = 1, dx: float = 1, dy: float = 1) → None[source]¶
Read a single B423 measurement directory, construct and write out metadata
- Parameters
dir_path (Path) – The path to the measurement
fs (float) – The sampling frequency, Hz
hx_serial (str, optional) – The x direction magnetic serial, used for calibration
hy_serial (str, optional) – The y direction magnetic serial, used for calibration
hz_serial (str, optional) – The z direction magnetic serial, used for calibration
h_gain (int) – Any gain on the magnetic channels which will need to be removed
dx (float, optional) – Distance between x electrodes
dy (float, optional) – Distance between y electrodes
- pydantic model resistics_readers.lemi.b423.TimeReaderB423[source]¶
Bases:
resistics.time.TimeReader
Data reader for Lemi B423 data
There is no separate metadata file for Lemi B423 data detailing the sampling frequency, the number of samples, the sensors etc.. Unfortunately, such a metadata file is a pre-requisite for resistics. There are helper methods to make one.
In situations where a Lemi B423 dataset is recorded in multiple files, it is required that the recording is continuous.
Other important notes about Lemi B423 files
1024 bytes of ASCII metadata in the data file with scaling information
Lemi B423 raw measurement data is signed long integer format
Important points about scalings
Raw data is integer counts for electric and magnetic channels
Scalings in B423 files convert electric channels to uV (microvolt)
Scalings in B423 files convert magnetic channels to millivolts
Scaling for the magnetic channels in B423 files leaves internal gain on
Internal gain should be specified when creating metadata
If apply_scaling is False, data will be returned in:
microvolts for the electric channels
millivolts for the magnetic with the gain applied
Which is equivalent to applying the scalings in the B423 headers
With apply_scaling True, the following additional scaling will be applied:
Electric channels converted to mV
Dipole length corrections are applied to electric channels
Magnetic channel gains are removed
Note
For more information about Lemi B423 format, please see: http://lemisensors.com/?p=485
Show JSON schema
{ "title": "TimeReaderB423", "description": "Data reader for Lemi B423 data\n\nThere is no separate metadata file for Lemi B423 data detailing the sampling\nfrequency, the number of samples, the sensors etc.. Unfortunately, such a\nmetadata file is a pre-requisite for resistics. There are helper methods to\nmake one.\n\nIn situations where a Lemi B423 dataset is recorded in multiple files, it is\nrequired that the recording is continuous.\n\nOther important notes about Lemi B423 files\n\n- 1024 bytes of ASCII metadata in the data file with scaling information\n- Lemi B423 raw measurement data is signed long integer format\n\nImportant points about scalings\n\n- Raw data is integer counts for electric and magnetic channels\n- Scalings in B423 files convert electric channels to uV (microvolt)\n- Scalings in B423 files convert magnetic channels to millivolts\n- Scaling for the magnetic channels in B423 files leaves internal gain on\n- Internal gain should be specified when creating metadata\n\nIf apply_scaling is False, data will be returned in:\n\n- microvolts for the electric channels\n- millivolts for the magnetic with the gain applied\n\nWhich is equivalent to applying the scalings in the B423 headers\n\nWith apply_scaling True, the following additional scaling will be applied:\n\n- Electric channels converted to mV\n- Dipole length corrections are applied to electric channels\n- Magnetic channel gains are removed\n\n.. note::\n\n For more information about Lemi B423 format, please see:\n http://lemisensors.com/?p=485", "type": "object", "properties": { "name": { "title": "Name", "type": "string" }, "apply_scalings": { "title": "Apply Scalings", "default": true, "type": "boolean" }, "extension": { "title": "Extension", "default": ".B423", "type": "string" }, "record_bytes": { "title": "Record Bytes", "default": 30, "type": "integer" } } }
- field record_bytes: int = 30¶
- read_metadata(dir_path: pathlib.Path) → resistics_readers.multifile.TimeMetadataMerge[source]¶
Read metadata
- Parameters
dir_path (Path) – The data directory
- Returns
TimeMetadata with a data table
- Return type
TimeMetadataMerge
- Raises
MetadataReadError – If the channels are not correct for B423
TimeDataReadError – If not all data files exist
TimeDataReadError – If extensions do not match
- read_data(dir_path: pathlib.Path, metadata: resistics.time.TimeMetadata, read_from: int, read_to: int) → resistics.time.TimeData[source]¶
Get data from data files
Lemi B423 data always has five channels, in order Hx, Hy, Hz, Ex, Ey. The raw data is integer counts. However, additional scalings from the B423 files are applied to give:
microvolts for the electric channels
millivolts for the magnetic with the gain applied
The scalings are as follows:
Hx = (Hx * Kmx) + Ax
Hx = (Hy * Kmy) + Ay
Hx = (Hz * Kmz) + Az
Ex = (Ex * Ke1) + Ae1
Ey = (Ey * Ke2) + Ae2
- Parameters
dir_path (path) – The directory path to read from
metadata (TimeMetadata) – Time series data metadata
read_from (int) – Sample to read data from
read_to (int) – Sample to read data to
- Returns
Time data object
- Return type
TimeData
- scale_data(time_data: resistics.time.TimeData) → resistics.time.TimeData[source]¶
Get data scaled to physical values
resistics uses field units, meaning physical samples will return the following:
Electrical channels in mV/km
Magnetic channels in mV
To get magnetic fields in nT, calibration needs to be performed
Notes
When Lemi data is read in, scaling in the headers is applied. Therefore, the magnetic channels is in mV with gain applied and the electric channels are in uV (microvolts). To complete the scaling to field units, the below additional corrections need to be applied.
Electric channels need to divided by 1000 along with dipole length division in km (east-west spacing and north-south spacing) to return mV/km.
Magnetic channels need to be divided by the internal gain value which should be set in the metadata
- Parameters
time_data (TimeData) – Input time data
- Returns
Time data in field units
- Return type
TimeData