Motion Recorder for accelerometer, gyroscope, and magnetometer.
Used for waveform/motion analysis, generate training data set for pattern recognition and machine learning, and seismic research, especially in LSKK and PPTIK Institut Teknologi Bandung (ITB). Initially we want to save to miniSEED format (to make it easier to analyze using SRC Waves or SeisGram2K), however as there is currently no miniSEED library for JavaScript, we decided to save in custom JSON format instead, which can be both saved to files and inserted into MongoDB directly.
Future plan: Server-side converter using Python/ObsPy to export the JSON waveform data to miniSEED format.
Full source code is available at https://github.com/lskk/motionrecorder
from http://www.fdsn.org/pdf/SEEDManual_V2.4.pdf : Orientation Code
- Z N E Traditional (Vertical, North-South, East-West) (see 5 degree convention above)
- A B C Triaxial (Along the edges of a cube turned up on a corner)
- [DONE_xyz] Accelerometer (x, y, z and/or Z, N, E?) in m/s^2 + samplingRate.
SNA
,SNB
,SNC
,SNZ
,SNN
,SNE
. Channel flag: G. - [DONE_xyz] Geomagnetic Field (calibrated) (x, y, z) in μT (Android) or T (SEED) + samplingRate.
SFA
.SFB
,SFC
,SFZ
,SFN
,SFE
. Channel flag: G. - Orientation (x, y, z) in degree or rad (?) + samplingRate.
- [DONE_xyz] Gyroscope (x, y, z) in rad/s + samplingRate.
SJA
,SJB
,SJC
. Channel flag: G. - Light in lux
- Promixity in cm
- [TODO] Gravity (x, y, z) in m/s^2
- Linear acceleration (x, y, z or Z, N, E?) in m/s^2 + samplingRate
- Rotation vector (x, y, z) (unitless) + scalar + samplingRate
- Step counter in steps + samplingRate
- Pressure. Barometer/pressure in Pa.
SDO
. flag: W/H. - [TODO] Location (latitude, longitude, accuracy; provider)
- [TODO] Elevation (m)
- [TODO] UTC timestamp at start and end of recording
- [DONE] Device: brand/model/deviceCountry, System: systemName/systemVersion
A miniSEED file supports multiple stations, each station with multiple channels.
QuakeZone JSON also supports multiple stations, in order to facilitate each data exchange for a single seismic event (with waveforms from multiple stations). However, Motion Recorder only writes one station (i.e. device) per document, and multiple channels (traces) for that station. We use ObsPy's Stream conventions and metadata field names, so each station is only uniquely identified by a trace/s network-station-location combination.
Station schema uses the modern StationXML. ObsPy interpretation: https://docs.obspy.org/tutorial/code_snippets/stationxml_file_from_scratch.html.
To aid classification training, we also add annotations:
{"motionCategory": "", "motionSubCategory": ""}
{
"_id": "(autogenerated by MongoDB)",
"source": "Motion Recorder",
"networks": [
{
"code": "",
"startDate": "",
"endDate": "",
"stations": [
{
"code": "X001",
"startDate": "",
"endDate": "",
"latitude": 1.0, // Note that these coordinates can differ from the station coordinates.
"longitude": 2.0,
"elevation": 345.0,
"site": "",
"operator": {
"agencies": [],
"contacts": [
{
"name": "...",
"agency": "...",
"email": "...",
"phone": "..."
}
],
"webSite": "https://..."
},
"creationDate": "...",
"terminationDate": "...",
"channels": [
{
"code": "SNZ", // This is the channel code according to the SEED standard.
"startDate": "",
"endDate": "",
"locationCode": "", // This is the location code according to the SEED standard.
"latitude": 1.0, // Note that these coordinates can differ from the station coordinates.
"longitude": 2.0,
"elevation": 345.0,
depth: 10.0, // The local depth or overburden of the instrument's location. For downhole instruments, the depth of the instrument under the surface ground level. For underground vaults, the distance from the instrument to the local ground level above.
// azimuth: 0.0, // Azimuth of the sensor in degrees from north, clockwise.
// dip: -90.0, // Dip of the instrument in degrees, down from horizontal
// The type of data this channel collects. Corresponds to channel flags in SEED blockette 52. The SEED volume producer could use the first letter of an Output value as the SEED channel flag.
"types": [
"TRIGGERED",
"CONTINUOUS"
"HEALTH"
"GEOPHYSICAL",
"WEATHER",
"FLAG",
"SYNTHESIZED",
"INPUT",
"EXPERIMENTAL",
"MAINTENANCE",
"BEAM"
],
"storageFormat": "",
"clockDrift": 0.0,
"calibrationUnits": "",
"sensor": "",
"preAmplifier": "",
"dataLogger": "",
"equipment": "",
"response": {
"instrumentSensitivity": {
// A scalar that, when applied to the data values, converts the data to different units (e.g. Earth units)
"value": 1000,
// The frequency (in Hertz) at which the Value is valid.
"frequency": 40,
// The units of the data as input from the perspective of data acquisition. After correcting data for this response, these would be the resulting units.
"inputUnits": {
// Name of units, e.g. "M/S", "V", "PA".
"name": "M/S",
"description": ""
},
// The units of the data as output from the perspective of data acquisition. These would be the units of the data prior to correcting for this response.
"outputUnits": {
// Name of units, e.g. "M/S", "V", "PA".
"name": "",
"description": ""
}
},
"stages": [...]
}
sample_rate: 200
},
{
"code": "SNN",
...
},
{
"code": "SNE",
...
}
]
}
]
}
],
"traces": [
{
"network": "XX",
"station": "X001",
"location": "",
"channel": "SNZ",
"starttime": "2003-05-29T02:13:22.043400Z",
"endtime": "2003-05-29T02:18:20.693400Z",
"sampling_rate": 40.0,
"delta": 0.025, // fractional seconds
"npts": 11947, // number of sample points
"calib": 1.0,
"values": [
// null not allowed
]
}
],
}
Initially the target sampling rate is 40 Hz.
However, using react-native-sensors
the actual rate is about 50% of the target sampling rate (with stable use):
asus/ASUS_Z01RD/GB
(Zenfone 5Z) accelerometer+gyroscope+magnetometer: ~20 Hz with interval 25ms, ~40 Hz with interval 13ms. ~80 Hz with target 160 Hz except magnetometer stuck at ~75 Hz.- Samsung A50: accelerometer 53-66 Hz, gyroscope 54-65 Hz, magnetometer 50-61 Hz
Sensor models:
- Zenfone 5Z: ICM20626 accelerometer, ICM20626 gyroscope, ak0991x magnetometer
For Zenfone 5Z, target of 55 Hz consistently achieves ~40 Hz with 3 sensors, interpolation/resampling (both upsampling and downsampling) will be necessary.
WARNING: react-native-svg-charts rendering is significantly reducing sensor performance. BarChart is fastest, followed by LineChart-curveLinear, then LineChart-curveStep.
- Resample
- check with Samsung A50 and Vivo Y17. We may need to interpolate in-between samples.
- Gravitation vector.
- GPS.
SNZ
: Short-period 10-80 Hz, Accelerometer, Vertical.SNN
: Short-period 10-80 Hz, Accelerometer, North-South.SNE
: Short-period 10-80 Hz, Accelerometer, East-West.SFZ
: Short-period 10-80 Hz, Magnetometer, Vertical.SFN
: Short-period 10-80 Hz, Magnetometer, North-South.SFE
: Short-period 10-80 Hz, Magnetometer, East-West.
Metadata
Blockette 1000 - Data Only (MiniSEED) Blockette. Data records by themselves do not contain enough information by themselves to allow time series data to be plotted or even simply analyzed. With the addition of a small amount of additional information these limitations are removed. Blockette 1000 is the Data Only (MiniSEED) Blockette that will allow SEED data records to be self-sufficient in terms of defining a time series.
stats = {'network': 'BW', 'station': 'RJOB', 'location': '',
'channel': 'WLZ', 'npts': len(data), 'sampling_rate': 0.1,
'mseed': {'dataquality': 'D'}}
Network Station(4-chars) Location(2-digit, optional)
e.g. "XX:X001::SNZ"
To get actual units, divide the counts by gain.
From Google Drive/PSN_Tsunami/sysadmin
, copy the quakezone.keystore
(upload key) file into the android/app
directory in your project folder.
The App Signing Key is managed by Google Play Console.