Example #1
0
    def sigcontainer(self) -> SigContainer:
        fs, data = self.read()
        if list(data.keys()) == [0]:
            data = np.array(data[0]).reshape((1, len(data[0])))
            channel = self.channels if self.channels[0] else self.shortpath.stem
            container = SigContainer.from_signal_array(data,
                                                       channels=[channel],
                                                       units=["mV"],
                                                       fs=self.fs)
        else:  # multichannel
            data = np.vstack(
                tuple(
                    np.array(data[chan]).reshape(1, len(data[chan]))
                    for chan in sorted(data.keys())))
            if self.channels is None:
                labels = [
                    f"{self.shortpath.stem}: channel {chan}"
                    for chan in sorted(self.data.keys())
                ]
            else:
                labels = [
                    f"{self.shortpath.stem}: {self.channels[chan]}"
                    for chan in sorted(self.data.keys())
                ]

            container = SigContainer.from_signal_array(
                data,
                channels=labels,
                units=["mV"] * len(labels),
                fs=fs,
                basepath=str(self.shortpath))
        return container
Example #2
0
 def apply(self, container: SigContainer) -> Any:
     data = container.d[self.target + "/data"]
     channels = container.d[self.target + "/channels"]
     container = self.prepare_container(container)
     container.d["signals/data"] = data
     container.d["signals/channels"] = channels
     return container
Example #3
0
 def join(self, output: SigContainer, inputs: Sequence[SigContainer]) -> SigContainer:
     result = np.copy(output.signals)
     for inc in inputs:
         self.ufunc(result, inc.signals, out=result)
     output.d["signals/data"] = result
     output.d["signals/channels"] = [
         f"{self.ufunc.__name__}({', '.join(input.d['signals/channels'][i] for input in [output] + list(inputs))})"
         for i in range(output.channel_count)]
     return output
Example #4
0
 def apply(self, container: SigContainer) -> SigContainer:
     container = self.prepare_container(container)
     oldlength = container.sample_count
     container.d["signals/data"] = sig.resample(
         container.d["signals/data"].transpose(), self.nlen).transpose()
     if self.chfreq:
         container.d["signals/fs"] = self.nlen * container.d[
             "signals/fs"] / oldlength
     #FIXME: change annotation position
     return container
Example #5
0
 def join(self, output: SigContainer, inputs: Sequence[SigContainer]) -> SigContainer:
     if self.names is not None:
         output.d["signals/channels"] = self.names
     for input in inputs:
         output.d["signals/data"] = np.hstack((output.signals, input.signals))
         if self.names is None:
             output.d["signals/channels"] = [
                 output.d["signals/channels"][i] + " + " + input.d["signals/channels"][i]
                     for i in range(len(output.d["signals/channels"]))]
     return output
Example #6
0
 def join(self, output: SigContainer, inputs: Sequence[SigContainer]) -> SigContainer:
     assert len(inputs) <= 1, "Convolution with more than two signal is not supported"
     in1 = output
     in2 = inputs[0] if inputs else in1
     result = np.vstack([
         convolve(in1.signals[i, :], in2.signals[i, :], self.mode, self.method)
         for i in range(in1.signals.shape[0])
     ])
     output.d["signals/data"] = result
     output.d["signals/lag"] = output.sample_count // 2
     return output
Example #7
0
 def apply(self, container: SigContainer) -> Any:
     dmax = np.max(container.signals,
                   axis=1).reshape(container.channel_count, 1)
     dmin = np.min(container.signals,
                   axis=1).reshape(container.channel_count, 1)
     drange = (dmax - dmin).reshape(container.channel_count, 1)
     range = self.max - self.min
     container.d["signals/data"] = self.min + range * (container.signals -
                                                       dmin) / drange
     container.d["signals/units"] = ["unit"] * container.channel_count
     return container
Example #8
0
 def container_factory(self, container: SigContainer, a: int, b: int,
                       splitter_id: str) -> SigContainer:
     c = SigContainer(
         container.d.deepcopy(empty_folders=["meta", "annotations"]))
     c.d["signals/data"] = c.d["signals/data"][:, a:b]
     newlog = list(c.d["log"])
     newlog.append(f"{splitter_id}@{a}-{b}")
     c.d["log"] = newlog
     if "annotations" in container.d:
         c.d["annotations"].update(
             SigContainer.cut_annots(container.d["annotations"], a, b))
     return c
Example #9
0
 def apply(self, container: SigContainer) -> SigContainer:
     container = self.prepare_container(container)
     assert container.channel_count == 1, "only one channel signal is supported"
     emd = EMD()
     IMFs = emd(container.signals[0,:])
     oname = container.d["signals/channels"][0]
     if self.include:
         container.d["signals/data"] = np.vstack((container.signals, IMFs))
         container.d["signals/channels"] = [oname] + [f"{oname} IMF_{i+1}" for i in range(IMFs.shape[0])]
         container.d["signals/units"] *= IMFs.shape[0] + 1
     else:
         container.d["signals/data"] = IMFs
         container.d["signals/channels"] = [f"{oname} IMF_{i+1}" for i in range(IMFs.shape[0])]
         container.d["signals/units"] *= IMFs.shape[0]
     return container
Example #10
0
    def sigcontainer(self) -> SigContainer:
        """
        Returns
        -------
        SigContainer
            Generated waveform in a SigContainer type.

        """
        if self.channel_name is None:
            self.channel_name = [
                self.sig_type.value + '(f=' + str(self.sig_frequency) +
                ', φ=' + str(self.sig_phase) + 'π, A=' +
                str(self.sig_amplitude)
            ]
        if self.amplitude_units is None:
            self.amplitude_units = ['']

        x = np.linspace(0, self.sig_duration,
                        int(self.fs * self.sig_duration)).reshape(
                            1, int(self.fs * self.sig_duration))
        sig_base = self.__sig_switch(self.sig_type, self.sig_frequency,
                                     self.sig_amplitude, self.sig_phase, x)
        generated_sig = SigContainer.from_signal_array(sig_base,
                                                       self.channel_name,
                                                       self.amplitude_units,
                                                       float(self.fs),
                                                       basepath=self.filepath)
        return generated_sig
Example #11
0
    def sigcontainer(self) -> SigContainer:
        """
        Returns
        -------
        SigContainer
            Generated noise in a SigContainer type.

        """
        noise = self.__noise_switch(self.noise_type, self.st_deviation, self.noise_duration, self.fs) \
            .reshape(1, int(self.fs * self.noise_duration))

        for _ in range(self.channels - 1):
            noise = np.vstack([
                noise,
                self.__noise_switch(self.noise_type, self.st_deviation,
                                    self.noise_duration, self.fs)
            ])
        if self.channel_names is None:
            self.channel_names = [
                f"{self.noise_type.value} noise (σ={self.st_deviation})"
            ] * self.channels
        if self.amplitude_units is None:
            self.amplitude_units = [' '] * self.channels

        generated_noise = SigContainer.from_signal_array(
            noise,
            self.channel_names,
            self.amplitude_units,
            float(self.fs),
            basepath=self.filepath)
        return generated_noise
Example #12
0
 def join(self, outcontainer: SigContainer,
          incontainers: Sequence[SigContainer]) -> SigContainer:
     result = np.copy(outcontainer.signals)
     for inc in incontainers:
         result += inc.signals
     outcontainer.d["signals/data"] = result
     return outcontainer
Example #13
0
 def apply(self, container: SigContainer) -> SigContainer:
     container = self.prepare_container(container)
     fs = container.d["signals/fs"]
     sos = self.cg(fs)
     container.d["signals/data"] = sig.sosfilt(sos,
                                               container.d["signals/data"],
                                               **self.params)
     return container
Example #14
0
 def apply(self, container: SigContainer) -> SigContainer:
     container = self.prepare_container(container)
     result = np.empty_like(container.d["signals/data"])
     for i in range(container.channel_count):
         result[i] = sig.medfilt(container.d["signals/data"][i, :],
                                 self.window_length)
     container.d["signals/data"] = result
     return container
def simpledata():
    sig = np.array([[0, 1, 0, -1, 0, 1, 0, -1, 0], [1, 1, 1, 1, 1, 1, 1, 1,
                                                    1]])
    c = SigContainer.from_signal_array(signals=sig,
                                       channels=["saw", "ones"],
                                       units=["mV", "mV"],
                                       fs=1)
    return c
Example #16
0
 def sigcontainer(self) -> SigContainer:
     return SigContainer.from_csv(self._filepath,
                                  dialect=self.dialect,
                                  header=self.header,
                                  default_unit=self.default_unit,
                                  fs=self.fs,
                                  transpose=self.transpose,
                                  annotation=self.annotation)
Example #17
0
    def apply(self, container: SigContainer) -> SigContainer:
        container = self.prepare_container(container)
        fs = container.d["signals/fs"]
        lag = container.lag
        start = TimeUnit.to_sample(self.start, fs,
                                   TimeUnit.time_unit_mapper(self.start), lag)
        end = TimeUnit.to_sample(self.end, fs,
                                 TimeUnit.time_unit_mapper(self.end), lag)
        container.d["signals/data"] = container.d["signals/data"][:, start:end]
        container.d["signals/lag"] = lag - start

        if "annotations" in container.d:
            adict = container.d["annotations"]
            newdict = SigContainer.cut_annots(adict, start, end)
            adict.update(newdict)

        return container
Example #18
0
    def sigcontainer(self) -> SigContainer:
        data = np.full((self.channels, int(self.duration * self.fs)), self.value, dtype=np.float64)
        if self.channel_names is None:
            self.channel_names = [f"constant:{self.value}"] * self.channels
        if self.units is None:
            self.units = [''] * self.channels

        return SigContainer.from_signal_array(data, self.channel_names, self.units, self.fs, basepath=self.filepath)
Example #19
0
 def join(self, output: SigContainer,
          inputs: Sequence[SigContainer]) -> SigContainer:
     for input in inputs:
         output.d["signals/data"] = np.vstack(
             (output.signals, input.signals))
         output.d["signals/channels"].extend(input.d["signals/channels"])
         output.d["signals/units"].extend(input.d["signals/units"])
     return output
Example #20
0
 def apply(self, container: SigContainer) -> SigContainer:
     container = self.prepare_container(container)
     result = np.empty_like(container.d["signals/data"])
     for i in range(container.channel_count):
         result[i] = np.correlate(container.d["signals/data"][i, :],
                                  self.v,
                                  mode="same") / self.sum
     container.d["signals/data"] = result
     return container
Example #21
0
    def sigcontainer(self) -> SigContainer:
        container = SigContainer.from_signal_array(self.data.transpose(), channels=self.channels,
                                                   units=self.units, fs=self.fs)
        for annotator in self.annotations.keys():
            samples = self.annotations[annotator]["sample"]
            symbols = [self.annotations[annotator]["symbol"]] * len(samples)
            notes = "" * len(samples)
            container.add_annotation(annotator, samples, types=symbols, notes=notes)

        return container
Example #22
0
 def apply(self, container: SigContainer) -> SigContainer:
     container = self.prepare_container(container)
     if self.new_freq is not None:
         f = fractions.Fraction(
             self.new_freq /
             container.d["signals/fs"]).limit_denominator(100)
         self.up = f.numerator
         self.down = f.denominator
     container.d["signals/data"] = sig.resample_poly(
         container.d["signals/data"], self.up, self.down, axis=1)
     container.d[
         "signals/fs"] = self.up * container.d["signals/fs"] / self.down
     if "annotations" in container.d:
         andict = container.d["annotations"]
         for ann in andict.keys():
             andict[ann]["samples"] = [
                 self.up * sample // self.down
                 for sample in andict[ann]["samples"]
             ]
     return container
Example #23
0
 def apply(self,
           container: SigContainer) -> Union[SigContainer, pd.DataFrame]:
     df = pd.DataFrame(data=container.d["signals/data"].transpose(),
                       columns=container.d["signals/channels"],
                       index=container.x_index(self.time_unit,
                                               container.d["signals/fs"]))
     if self.to_file is None:
         return df
     else:
         file = self.to_file.format(container)
         df.to_pickle(file)
         return container
Example #24
0
 def apply(self, container: SigContainer) -> Sequence[SigContainer]:
     container = self.prepare_container(container)
     limits = container.get_annotation_positions(self.aspec,
                                                 TimeUnit.SAMPLE,
                                                 container.d["signals/fs"])
     if self.left_segment and limits[0] != 0:
         limits = np.insert(limits, 0, 0)
     if self.right_segment and limits[-1] != container.sample_count - 1:
         limits = np.append(limits, [container.sample_count])
     return [
         self.container_factory(container, a, b, f"MSPL@{self.aspec}]")
         for a, b in zip(limits, limits[1:])
     ]
Example #25
0
 def apply(self, container: SigContainer) -> SigContainer:
     import csv
     container = self.prepare_container(container)
     path = self.filepath.base_path(
         container.basepath.extend_stem(container.id).resuffix(".csv"))
     x = container.x_index(self.time_unit, container.d["signals/fs"])
     opener = open if not self.gzipped else gzip.open
     with opener(str(path), "wt", newline='') as csvfile:
         writer = csv.writer(csvfile, dialect=self.dialect)
         writer.writerow(["time"] + container.d["signals/channels"])
         for i in range(container.signals.shape[1]):
             writer.writerow([
                 f"{val:g}"
                 for val in np.hstack((x[i], container.signals[:, i]))
             ])
     return container
Example #26
0
 def apply(self, container: SigContainer) -> Sequence[SigContainer]:
     container = self.prepare_container(container)
     containers = []
     #TODO: zohlednit kanály
     for i in range(container.channel_count):
         c = SigContainer(
             container.d.deepcopy(["annotations"],
                                  empty_folders=["signals", "meta"]))
         c.d["signals/data"] = container.d["signals/data"][i, :].reshape(
             1, container.sample_count)
         c.d["signals/channels"] = [container.d["signals/channels"][i]]
         c.d["signals/units"] = [container.d["signals/units"][i]]
         c.d["signals/fs"] = container.d["signals/fs"]
         c.d["log"] = list(container.d["log"])
         c.d["log"].append(f"C{i}")
         containers.append(c)
     return containers
Example #27
0
 def sigcontainer(self, annotators: Iterable[str] = None) -> SigContainer:
     c = SigContainer.from_signal_array(signals=np.transpose(self.record.p_signal),
                                        channels=self.record.sig_name,
                                        units=self.record.units, fs=self.record.fs)
     if annotators is not None:
         with h5py.File("physionet_cache.h5") as store:
             for annotator in annotators:
                 if annotator not in self.annotations:
                     annopath = f"{self.path}/{annotator}"
                     if annopath not in store:
                         self.annotations[annotator] = wfdb.rdann(self.name, annotator,
                                                                  pb_dir=self.database)
                         store.create_dataset(annopath, data=dumpa(self.annotations[annotator]),
                                              compression="gzip")
                     else:
                         self.annotations[annotator] = pickle.loads(store[annopath][:])
                 data = self.annotations[annotator]
                 c.add_annotation(annotator, data.sample, data.symbol, data.aux_note)
     return c
def test_hdf5_roundtrip(megawindata):
    original = megawindata | Hdf5("/tmp/test.h5")
    serialized = SigContainer.from_hdf5("/tmp/test.h5")
    assert np.all(original.signals == serialized.signals)
Example #29
0
 def apply(self, container: SigContainer) -> Any:
     container = self.prepare_container(container)
     h = sig.hilbert(container.signals, axis=1)
     container.d["signals/data"] = np.sqrt(np.real(h)**2 + np.imag(h)**2)
     return container
Example #30
0
 def prepare_container(self, container: SigContainer) -> SigContainer:
     return SigContainer(container.d.deepcopy(shared_folders=["annotations"],
                                              empty_folders=["meta"]))