Exemple #1
0
def test_decode_data(bedmaster_reader: BedmasterReader):
    # float signal
    codified_data = np.repeat([[48, 46, 50], [49, 46, 50]], 5, axis=0)
    decoded_data = np.repeat([0.2, 1.2], 5)
    assert np.array_equal(bedmaster_reader.format_data(codified_data), decoded_data)
    # int signal
    codified_data = np.repeat([[51, 50], [50, 57]], 5, axis=0)
    decoded_data = np.repeat([32, 29], 5)
    assert np.array_equal(bedmaster_reader.format_data(codified_data), decoded_data)

    # string nan 1 and 2
    codified_data = np.repeat([[48, 46, 50, 51], [49, 46, 50, 49]], 5, axis=0)
    codified_data[3] = [78, 111, 110, 101]
    decoded_data = np.repeat([0.23, 1.21], 5)
    decoded_data[3] = np.nan

    obtained = bedmaster_reader.format_data(codified_data)
    assert np.array_equal(
        obtained[~np.isnan(obtained)],
        decoded_data[~np.isnan(decoded_data)],
    )
    assert np.isnan(obtained[3])
    codified_data[3] = [88, 32, 32, 32]
    obtained = bedmaster_reader.format_data(codified_data)
    assert np.array_equal(
        obtained[~np.isnan(obtained)],
        decoded_data[~np.isnan(decoded_data)],
    )
    assert np.isnan(obtained[3])
Exemple #2
0
def test_list_vs(bedmaster_reader: BedmasterReader, empty_matfile: h5py.File):
    expected_vs = ["CO", "CUFF", "HR", "SPO2%", "SPO2R"]
    assert bedmaster_reader.list_vs() == expected_vs

    # No vs on file:
    empty_reader = BedmasterReader(empty_matfile.name)
    assert empty_reader.list_vs() == []
Exemple #3
0
def test_contiguous_nparrays(bedmaster_reader: BedmasterReader):
    heart_rate = bedmaster_reader.get_vs("HR")
    if heart_rate is None:
        assert False
    ecgv = bedmaster_reader.get_wv("ch10", "V")
    if ecgv is None:
        assert False
    signals = [heart_rate, ecgv]
    for signal in signals:
        assert not signal.value.dtype == object
        assert not signal.time.dtype == object
Exemple #4
0
def test_get_interbundle_correction(bedmaster_reader: BedmasterReader):
    art1d = bedmaster_reader.get_vs("CO")
    if art1d is None:
        assert False
    ch10 = bedmaster_reader.get_wv("ch10", "v")
    if ch10 is None:
        assert False

    no_correction = {"vs": None, "wv": None}
    prev_max_vs = {
        "segmentNo": 2,
        "maxTime": art1d.time[4],
        "signalName": "CO",
    }
    prev_max_wv = {
        "segmentNo": 1,
        "maxTime": ch10.time[14],
        "signalName": "ch10",
    }
    prev_max_info = {"vs": prev_max_vs, "wv": prev_max_wv}

    expected_vs = {"maxTime": art1d.time[3], "timeCorr": 2}
    expected_wv = {"maxTime": ch10.time[15], "timeCorr": -0.25}

    def _change_ibcor_dict(source_type, **kwargs):
        new_dict = prev_max_info.copy()
        for source in source_type:
            for key in kwargs:
                new_dict[source][key] = kwargs[key]
        return new_dict

    assert bedmaster_reader.interbundle_corr == no_correction

    # Normal case:
    bedmaster_reader.get_interbundle_correction(prev_max_info)
    assert bedmaster_reader.interbundle_corr["vs"] == expected_vs
    assert bedmaster_reader.interbundle_corr["wv"] == expected_wv

    # Case: signal does not exist on current bundle
    previous = _change_ibcor_dict(["vs", "wv"], signalName="Random")
    bedmaster_reader.get_interbundle_correction(previous)
    assert bedmaster_reader.interbundle_corr == no_correction

    # Case: no overlap between previous and current bundle
    previous = _change_ibcor_dict(["vs", "wv"], segmentNo=-1)
    bedmaster_reader.get_interbundle_correction(previous)
    assert bedmaster_reader.interbundle_corr == no_correction

    # Case: complete overlap between previous and current
    previous = _change_ibcor_dict(["vs", "wv"], segmentNo=100)
    bedmaster_reader.get_interbundle_correction(previous)
    assert bedmaster_reader.interbundle_corr == no_correction
Exemple #5
0
def test_list_wv(bedmaster_reader: BedmasterReader, empty_matfile: h5py.File):
    expected_dict = {
        "I": "ch7",
        "II": "ch8",
        "III": "ch9",
        "V": "ch10",
        "SPO2": "ch39",
        "RESP": "ch40",
    }
    assert bedmaster_reader.list_wv() == expected_dict

    # No wv on file:
    empty_reader = BedmasterReader(empty_matfile.name)
    assert empty_reader.list_vs() == []
Exemple #6
0
def test_get_vs(bedmaster_reader: BedmasterReader, matfile: h5py.File):
    def _linearize(arr):
        return np.transpose(arr)[0]

    # Standard case
    heart_rate = bedmaster_reader.get_vs("HR")
    if heart_rate is None:
        assert False
    assert heart_rate.name == "HR"
    assert np.array_equal(heart_rate.value, _linearize(matfile["vs/HR"][()]))
    assert np.array_equal(
        heart_rate.time,
        _linearize(matfile["vs_time_corrected/HR/res_vs"][()]),
    )
    assert heart_rate.scale_factor == 0.5
    assert heart_rate.units == "Bpm"
    assert heart_rate.sample_freq == np.array([(0.5, 0)], dtype="float,int")

    # Check that dataevents are collected
    time_corr_arr = np.unpackbits(heart_rate.time_corr_arr, axis=None)
    irregularities = np.where(time_corr_arr)[0]
    expected_irr_idx = np.array([2, 3, 11])
    assert np.array_equal(irregularities, expected_irr_idx)

    # Check that interbundle correction is applied
    bedmaster_reader.interbundle_corr["vs"] = {
        "maxTime": heart_rate.time[10],
        "timeCorr": 3,
    }
    heart_rate_corr = bedmaster_reader.get_vs("HR")
    if heart_rate_corr is None:
        assert False
    assert len(heart_rate_corr.time) == len(heart_rate.time) - 11
    assert len(heart_rate_corr.value) == len(heart_rate.value) - 11

    # Case with unknown scale factor and unit
    spo2r = bedmaster_reader.get_vs("SPO2R")
    if spo2r is None:
        assert False
    assert spo2r.scale_factor == 1
    assert spo2r.units == "UNKNOWN"
    assert spo2r.sample_freq == np.array([(0.5, 0)], dtype="float,int")
Exemple #7
0
def test_format_data(bedmaster_reader: BedmasterReader):
    expected_data = np.arange(10)

    #  Case column vector [[0], [1]] -> [0,1]
    unformatted_data = np.transpose([expected_data])
    assert np.array_equal(bedmaster_reader.format_data(unformatted_data), expected_data)

    # Case single-row 2D vector [[0,1]] -> [0,1]
    unformatted_data = np.array([expected_data])
    assert np.array_equal(bedmaster_reader.format_data(unformatted_data), expected_data)

    # Case column matrix
    input_2d_data = np.repeat([[48, 46, 50], [49, 46, 50]], 5, axis=0)
    formatted_data = np.repeat([0.2, 1.2], 5)
    assert np.array_equal(bedmaster_reader.format_data(input_2d_data), formatted_data)

    # Case row matrix
    input_2d_data = np.transpose(input_2d_data)
    formatted_data = np.repeat([0.2, 1.2], 5)
    assert np.array_equal(bedmaster_reader.format_data(input_2d_data), formatted_data)
Exemple #8
0
def test_apply_interbundle_correction(bedmaster_reader: BedmasterReader):
    def _create_ib_corr_dict(signal: BedmasterSignal, cut_idx: int, time_corr: int):
        source_corr = {
            "maxTime": signal.time[cut_idx],
            "timeCorr": time_corr,
        }
        return source_corr

    def _apply_and_assert_ib(signal: Optional[BedmasterSignal], sig_type: str):
        if signal is None:
            assert False
        signal.time_corr_arr = np.unpackbits(signal.time_corr_arr)
        signal_original = copy.deepcopy(signal)
        bedmaster_reader.interbundle_corr[sig_type] = _create_ib_corr_dict(
            signal,
            cut_idx[sig_type],
            time_corr[sig_type],
        )
        bedmaster_reader.apply_ibcorr(signal)
        _assert_ib_correction(
            signal_original,
            signal,
            cut_idx[sig_type],
            time_corr[sig_type],
        )
        bedmaster_reader.interbundle_corr[sig_type] = None

    cut_idx = {"wv": 10, "vs": 4}
    time_corr = {"wv": 5, "vs": 3}

    # Standard case
    ecgi = bedmaster_reader.get_wv("ch7", "I")
    _apply_and_assert_ib(ecgi, "wv")

    cuff = bedmaster_reader.get_vs("CUFF")
    _apply_and_assert_ib(cuff, "vs")

    # With DE
    ecgv = bedmaster_reader.get_wv("ch10", "V")
    _apply_and_assert_ib(ecgv, "wv")

    hr = bedmaster_reader.get_vs("HR")
    _apply_and_assert_ib(hr, "vs")

    # With missing values
    ecgiii = bedmaster_reader.get_wv("ch9", "prova")
    _apply_and_assert_ib(ecgiii, "wv")

    # Multiple sf
    ecgii = bedmaster_reader.get_wv("ch8", "II")
    _apply_and_assert_ib(ecgii, "wv")
Exemple #9
0
    def _write_bedmaster_data(
        bedmaster_files: List[str],
        writer: Writer,
        scaling_and_units: Dict,
    ):
        all_files = True
        previous_max = None
        untensorized_files: Dict[str, List[str]] = {"file": [], "error": []}
        for bedmaster_file in bedmaster_files:
            try:
                with BedmasterReader(bedmaster_file, scaling_and_units) as reader:
                    if previous_max:
                        reader.get_interbundle_correction(previous_max)

                    # These blocks can be easily parallelized with MPI:
                    # >>> rank = MPI.COMM_WORLD.rank
                    # >>> if rank == 1:
                    vs_signals = reader.list_vs()
                    for vs_signal_name in vs_signals:
                        vs_signal = reader.get_vs(vs_signal_name)
                        if vs_signal:
                            writer.write_signal(vs_signal)

                    # >>> if rank == 2
                    wv_signals = reader.list_wv()
                    for wv_signal_name, channel in wv_signals.items():
                        wv_signal = reader.get_wv(channel, wv_signal_name)
                        if wv_signal:
                            writer.write_signal(wv_signal)

                    previous_max = reader.max_segment
            except Exception as error:
                untensorized_files["file"].append(bedmaster_file)
                untensorized_files["error"].append(repr(error))
        if len(untensorized_files["file"]) > 0:
            all_files = False
        return all_files, untensorized_files
Exemple #10
0
def test_max_segment(bedmaster_reader: BedmasterReader):
    def _create_max_seg_dict(seg_no, max_time, signal_name):
        return {
            "segmentNo": seg_no,
            "maxTime": max_time,
            "signalName": signal_name,
        }

    empty_vs_dict = _create_max_seg_dict(0, -1, "")
    empty_wv_dict = _create_max_seg_dict(0, -1, "")
    expected_wv_max = _create_max_seg_dict(
        seg_no=6,
        max_time=1452438403.75,
        signal_name="ch10",
    )
    expected_vs_max = _create_max_seg_dict(
        seg_no=6,
        max_time=1452438402.0,
        signal_name="CO",
    )

    assert bedmaster_reader.max_segment["vs"] == empty_vs_dict
    assert bedmaster_reader.max_segment["wv"] == empty_wv_dict

    wv_signals = bedmaster_reader.list_wv()
    for wv_signal_name, channel in wv_signals.items():
        bedmaster_reader.get_wv(channel, wv_signal_name)

    assert bedmaster_reader.max_segment["vs"] == empty_vs_dict
    assert bedmaster_reader.max_segment["wv"] == expected_wv_max

    vs_signals = bedmaster_reader.list_vs()
    for vs_signal_name in vs_signals:
        bedmaster_reader.get_vs(vs_signal_name)
    assert bedmaster_reader.max_segment["vs"] == expected_vs_max
    assert bedmaster_reader.max_segment["wv"] == expected_wv_max
Exemple #11
0
def test_get_wv(bedmaster_reader: BedmasterReader, matfile: h5py.File):
    def linearize(arr):
        return np.transpose(arr)[0]

    # Check standard case
    ecgv = bedmaster_reader.get_wv("ch10", "V")
    if ecgv is None:
        assert False
    assert ecgv.name == "V"
    assert np.array_equal(ecgv.value, linearize(matfile["wv/ch10"][()]))
    assert np.array_equal(
        ecgv.time,
        linearize(matfile["wv_time_corrected/ch10/res_wv"][()]),
    )
    assert ecgv.units == "mV"
    assert ecgv.scale_factor == 0.0243
    assert np.array_equal(ecgv.sample_freq, np.array([(240, 0)], dtype="float,int"))

    # Check that it works without specifying signal name
    ecgv_copy = bedmaster_reader.get_wv("ch10")
    if ecgv_copy is None:
        assert False
    assert ecgv_copy.name == ecgv.name
    assert np.array_equal(ecgv_copy.value, ecgv.value)

    # Check dataevents are collected
    time_corr_arr = np.unpackbits(ecgv.time_corr_arr, axis=None)
    irregularities = np.where(time_corr_arr)[0]
    expected_irr_idx = np.array([3, 4, 20, 32, 40, 50, 54])
    assert np.array_equal(irregularities, expected_irr_idx)

    # Case with multiple sample frequency
    ecg2 = bedmaster_reader.get_wv("ch8", "II")
    if ecg2 is None:
        assert False
    assert np.array_equal(
        ecg2.sample_freq,
        np.array([(240, 0), (120, 80)], dtype="float,int"),
    )

    # Check that interbundle correction is applied
    overlap = 5
    bedmaster_reader.interbundle_corr["wv"] = {
        "maxTime": ecgv.time[overlap - 1],
        "timeCorr": 8,
    }
    ecg2_corr = bedmaster_reader.get_wv("ch8", "II")
    if ecg2_corr is None:
        assert False
    values_cut = overlap * ecg2_corr.sample_freq[0][0] / 4
    assert len(ecg2_corr.time) == len(ecgv.time) - overlap
    assert len(ecg2_corr.value) == len(ecgv.value) - values_cut
    assert np.array_equal(
        ecg2_corr.sample_freq,
        np.array([(240, 0), (120, 75)], dtype="float,int"),
    )

    # Case with unknown scale factor and unit
    ecg3 = bedmaster_reader.get_wv("ch9", "III")
    if ecg3 is None:
        assert False
    assert ecg3.units == "??V"
    assert ecg3.scale_factor == 2.44
    assert np.array_equal(ecg3.sample_freq, np.array([(240, 0)], dtype="float,int"))
Exemple #12
0
def bedmaster_reader(
    test_scale_units: Dict[str, Dict[str, Union[int, float, str]]],
) -> Iterator[BedmasterReader]:
    with h5py.File(pytest.mat_file, "r") as mat_file:
        reader = BedmasterReader(mat_file.filename, test_scale_units)
        yield reader