from pathlib import Path from sohstationviewer.model.mseed_data.mseed_reader import MSeedReader from tests.base_test_case import BaseTestCase TEST_DATA_DIR = Path(__file__).resolve().parent.parent.parent.joinpath( 'test_data') ascii_file = TEST_DATA_DIR.joinpath( "Q330-sample/day_vols_AX08/AX08.XA..LOG.2021.186") blockettes_files = TEST_DATA_DIR.joinpath( "Q330_unimplemented_ascii_block/XX-3203_4-20221222190255") multiplex_file = TEST_DATA_DIR.joinpath( "Q330_multiplex/XX-3203_4-20221222183011") soh_file = TEST_DATA_DIR.joinpath( "Q330-sample/day_vols_AX08/AX08.XA..VKI.2021.186") waveform_file = TEST_DATA_DIR.joinpath( "Q330-sample/day_vols_AX08/AX08.XA..LHE.2021.186") mass_pos_file = TEST_DATA_DIR.joinpath( "Q330-sample/day_vols_AX08/AX08.XA..VM1.2021.186") gap_file = TEST_DATA_DIR.joinpath( "Centaur-sample/SOH/" "XX.3734.SOH.centaur-3_3734..20180817_000000.miniseed.miniseed") class TestMSeedReader(BaseTestCase): def setUp(self) -> None: self.soh_data = {} self.mass_pos_data = {} self.waveform_data = {} self.log_data = {} def test_read_ascii(self): args = { 'file_path': ascii_file, 'is_multiplex': False, 'req_soh_chans': ['LOG'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.log_data.keys()), ['AX08']) self.assertEqual(list(self.log_data['AX08'].keys()), ['LOG']) self.assertEqual(len(self.log_data['AX08']['LOG']), 16) self.assertEqual( self.log_data['AX08']['LOG'][0][:100], '\n\nSTATE OF HEALTH: From:1625456260.12 To:1625456260.12\n\r' '\nQuanterra Packet Baler Model 14 Restart. V' ) self.assertEqual( self.log_data['AX08']['LOG'][1][:100], '\n\nSTATE OF HEALTH: From:1625456366.62 To:1625456366.62' '\nReducing Status Polling Interval\r\n[2021-07-0' ) def test_read_blockettes_info(self): args = { 'file_path': blockettes_files, 'is_multiplex': True, 'req_soh_chans': ['ACE'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.log_data.keys()), ['3203']) self.assertEqual(list(self.log_data['3203'].keys()), ['ACE']) self.assertEqual(len(self.log_data['3203']['ACE']), 1) self.assertEqual( self.log_data['3203']['ACE'][0][:100], '\n\nSTATE OF HEALTH: From:1671729287.00014 To:1671729287.0' '\n===========\nVCO correction: 53.7109375\nTim' ) def test_not_is_multiplex_read_channel(self): # is_multiplex = False => stop when reach to channel not match req # so the channel 'EL1' is read but not finished args = { 'file_path': multiplex_file, 'is_multiplex': False, 'req_wf_chans': ['EL1'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.waveform_data.keys()), ['3203']) self.assertEqual(list(self.waveform_data['3203'].keys()), ['EL1']) self.assertEqual(self.waveform_data['3203']['EL1']['samplerate'], 200) self.assertEqual(self.waveform_data['3203']['EL1']['startTmEpoch'], 1671730004.145029) self.assertEqual(self.waveform_data['3203']['EL1']['endTmEpoch'], 1671730013.8) self.assertEqual(self.waveform_data['3203']['EL1']['size'], 1932) self.assertEqual(self.waveform_data['3203']['EL1']['gaps'], []) self.assertEqual(len(self.waveform_data['3203']['EL1']['tracesInfo']), 1) def test_is_multiplex_read_channel(self): # is_multiplex = True => read every record args = { 'file_path': multiplex_file, 'is_multiplex': True, 'req_wf_chans': ['EL1'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.waveform_data.keys()), ['3203']) self.assertEqual(list(self.waveform_data['3203'].keys()), ['EL1']) self.assertEqual(self.waveform_data['3203']['EL1']['samplerate'], 200) self.assertEqual(self.waveform_data['3203']['EL1']['startTmEpoch'], 1671730004.145029) self.assertEqual(self.waveform_data['3203']['EL1']['endTmEpoch'], 1671730720.4299) self.assertEqual(self.waveform_data['3203']['EL1']['size'], 143258) self.assertEqual(self.waveform_data['3203']['EL1']['gaps'], []) self.assertEqual(len(self.waveform_data['3203']['EL1']['tracesInfo']), 1) def test_not_is_multiplex_selected_channel_in_middle(self): # won't reached selected channel because previous record doesn't meet # requirement when is_multiplex = False args = { 'file_path': multiplex_file, 'is_multiplex': False, 'req_wf_chans': ['EL2'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.waveform_data.keys()), []) def test_is_multiplex_selected_channel_in_middle(self): # is_multiplex = True => the selected channel will be read args = { 'file_path': multiplex_file, 'is_multiplex': True, 'req_wf_chans': ['EL2'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.waveform_data.keys()), ['3203']) self.assertEqual(list(self.waveform_data['3203'].keys()), ['EL2']) self.assertEqual(self.waveform_data['3203']['EL2']['samplerate'], 200) self.assertEqual(self.waveform_data['3203']['EL2']['startTmEpoch'], 1671730004.3100293) self.assertEqual(self.waveform_data['3203']['EL2']['endTmEpoch'], 1671730720.5499) self.assertEqual(self.waveform_data['3203']['EL2']['size'], 143249) self.assertEqual(self.waveform_data['3203']['EL2']['gaps'], []) self.assertEqual(len(self.waveform_data['3203']['EL2']['tracesInfo']), 1) def test_existing_time_range(self): # check if data_time is from the given range, end time may get # a little greater than read_end according to record's end time args = { 'file_path': soh_file, 'is_multiplex': False, 'req_soh_chans': ['VKI'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data, 'read_start': 1625456018.0, 'read_end': 1625505627.9998999 } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.soh_data['AX08'].keys()), ['VKI']) self.assertEqual(self.soh_data['AX08']['VKI']['startTmEpoch'], 1625446018.0) self.assertEqual(self.soh_data['AX08']['VKI']['endTmEpoch'], 1625510328.0) def test_non_existing_time_range(self): # if given time range out of the data time, no station will be created args = { 'file_path': soh_file, 'is_multiplex': False, 'req_soh_chans': ['VKI'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data, 'read_start': 1625356018.0, 'read_end': 1625405627.9998999 } reader = MSeedReader(**args) reader.read() self.assertEqual(self.soh_data, {}) self.assertEqual(self.mass_pos_data, {}) self.assertEqual(self.waveform_data, {}) def test_read_waveform(self): args = { 'file_path': waveform_file, 'is_multiplex': False, 'req_wf_chans': ['LHE'], 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.waveform_data.keys()), ['AX08']) self.assertEqual(list(self.waveform_data['AX08'].keys()), ['LHE']) self.assertEqual(self.waveform_data['AX08']['LHE']['samplerate'], 1) self.assertEqual(self.waveform_data['AX08']['LHE']['startTmEpoch'], 1625445156.000001) self.assertEqual(self.waveform_data['AX08']['LHE']['endTmEpoch'], 1625532949.0) self.assertEqual(self.waveform_data['AX08']['LHE']['size'], 87794) self.assertEqual(self.waveform_data['AX08']['LHE']['gaps'], []) self.assertEqual(len(self.waveform_data['AX08']['LHE']['tracesInfo']), 1) def test_read_mass_pos_channel(self): # mass position channels will be read if one or both include_mpxxxxxx # are True args = { 'file_path': mass_pos_file, 'is_multiplex': False, 'include_mp123zne': True, 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.mass_pos_data.keys()), ['AX08']) self.assertEqual(list(self.mass_pos_data['AX08'].keys()), ['VM1']) self.assertEqual(self.mass_pos_data['AX08']['VM1']['samplerate'], 0.1) self.assertEqual(self.mass_pos_data['AX08']['VM1']['startTmEpoch'], 1625444970.0) self.assertEqual(self.mass_pos_data['AX08']['VM1']['endTmEpoch'], 1625574570.0) self.assertEqual(self.mass_pos_data['AX08']['VM1']['size'], 12961) self.assertEqual(self.mass_pos_data['AX08']['VM1']['gaps'], []) self.assertEqual(len(self.mass_pos_data['AX08']['VM1']['tracesInfo']), 1) def test_gap(self): # gaps will be detected when gap_minimum is set args = { 'file_path': gap_file, 'is_multiplex': True, 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data, 'gap_minimum': 60 } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.soh_data.keys()), ['3734']) self.assertEqual(sorted(list(self.soh_data['3734'].keys())), ['EX1', 'EX2', 'EX3', 'GAN', 'GEL', 'GLA', 'GLO', 'GNS', 'GPL', 'GST', 'LCE', 'LCQ', 'VCO', 'VDT', 'VEC', 'VEI', 'VPB']) self.assertAlmostEqual(self.soh_data['3734']['EX1']['samplerate'], 0.0166, 3) self.assertEqual(self.soh_data['3734']['EX1']['startTmEpoch'], 1534512840.0) self.assertEqual(self.soh_data['3734']['EX1']['endTmEpoch'], 1534550340.0) self.assertEqual(self.soh_data['3734']['EX1']['size'], 597) expected_gaps = [ [1534515900.0, 1534515960.0], [1534519020.0, 1534519080.0], [1534522140.0, 1534523940.0], [1534526820.0, 1534526880.0], [1534529940.0, 1534530000.0], [1534533060.0, 1534533120.0], [1534536180.0, 1534536240.0], [1534539300.0, 1534539360.0], [1534542420.0, 1534542480.0], [1534545540.0, 1534545600.0], [1534548660.0, 1534548720.0]] self.assertEqual(self.soh_data['3734']['EX1']['gaps'], expected_gaps) def test_not_detect_gap(self): # if gap_minimum isn't set but gap exist, data still be separated, but # gap won't be added to gap list args = { 'file_path': gap_file, 'is_multiplex': True, 'soh_data': self.soh_data, 'mass_pos_data': self.mass_pos_data, 'waveform_data': self.waveform_data, 'log_data': self.log_data, 'gap_minimum': None } reader = MSeedReader(**args) reader.read() self.assertEqual(list(self.soh_data.keys()), ['3734']) self.assertEqual(sorted(list(self.soh_data['3734'].keys())), ['EX1', 'EX2', 'EX3', 'GAN', 'GEL', 'GLA', 'GLO', 'GNS', 'GPL', 'GST', 'LCE', 'LCQ', 'VCO', 'VDT', 'VEC', 'VEI', 'VPB']) self.assertAlmostEqual(self.soh_data['3734']['EX1']['samplerate'], 0.0166, 3) self.assertEqual(self.soh_data['3734']['EX1']['startTmEpoch'], 1534512840.0) self.assertEqual(self.soh_data['3734']['EX1']['endTmEpoch'], 1534550340.0) self.assertEqual(self.soh_data['3734']['EX1']['size'], 597) self.assertEqual(self.soh_data['3734']['EX1']['gaps'], []) # no gaps