-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
42 changed files
with
2,855 additions
and
195 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
[DEFAULT] | ||
Sense = /Users/saraiva/Desktop/LongTermBiosignals/resources/Sense_CSV_tests/sense_defaults.json | ||
Sense = /Users/saraiva/PycharmProjects/IT-LongTermBiosignals/resources/Sense_CSV_tests/sense_defaults.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# -- encoding: utf-8 -- | ||
# =================================== | ||
# ScientISST LTBio | Long-Term Biosignals | ||
|
||
# Package: | ||
# Module: | ||
# Description: | ||
|
||
# Contributors: João Saraiva | ||
# Created: | ||
# Last Updated: | ||
# =================================== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
# -- encoding: utf-8 -- | ||
# =================================== | ||
# ScientISST LTBio | Long-Term Biosignals | ||
from datetimerange import DateTimeRange | ||
|
||
from ltbio.biosignals.timeseries import Timeline | ||
|
||
|
||
#from ltbio.biosignals._Timeline import Timeline | ||
#from ltbio.biosignals._Timeseries import Timeseries | ||
#from ltbio.biosignals.units import Unit, Frequency | ||
#from ltbio.clinical import BodyLocation | ||
|
||
|
||
# Package: | ||
# Module: | ||
# Description: | ||
|
||
# Contributors: João Saraiva | ||
# Created: | ||
# Last Updated: | ||
# =================================== | ||
|
||
|
||
class IncompatibleTimeseriesError(Exception): | ||
def __init__(self, why: str): | ||
super().__init__(f"These Timeseries are incompatible because {why}") | ||
|
||
|
||
class DifferentSamplingFrequenciesError(IncompatibleTimeseriesError): | ||
def __init__(self, *frequencies): | ||
super().__init__(f"these different sampling frequencies were found: {','.join(frequencies)}. " | ||
f"Try to resample first.") | ||
|
||
|
||
class DifferentUnitsError(IncompatibleTimeseriesError): | ||
def __init__(self, *units): | ||
super().__init__(f"these different units were found: {','.join(units)}. " | ||
f"Try to convert first.") | ||
|
||
|
||
class DifferentDomainsError(IncompatibleTimeseriesError): | ||
def __init__(self, *timelines): | ||
note = "they have different domains: " | ||
note += '; '.join([f"({i+1}): {domain}" for i, domain in enumerate(timelines)]) | ||
super().__init__(note) | ||
|
||
|
||
class IncompatibleBiosignalsError(Exception): | ||
def __init__(self, why: str): | ||
super().__init__(f"These Biosignals are incompatible because {why}") | ||
|
||
|
||
class DifferentPatientsError(IncompatibleTimeseriesError): | ||
def __init__(self, first, second): | ||
super().__init__(f"at least two different patients were found: {first} and {second}. " | ||
f"Try to drop the patients first.") | ||
|
||
class IncompatibleSegmentsError(Exception): | ||
def __init__(self, why: str): | ||
super().__init__(f"These Segments are incompatible because {why}") | ||
|
||
class DifferentLengthsError(Exception): | ||
def __init__(self, first: int, second: int): | ||
super().__init__(f"the first has length {first} and the second has length {second}.") | ||
|
||
|
||
class TimeError(Exception): | ||
... | ||
|
||
|
||
class ChannelsWithDifferentStartTimepointsError(TimeError): | ||
def __init__(self, first_name, first_start, second_name, second_start, additional: str = ''): | ||
super().__init__(f"{first_name} starts at {first_start} and {second_name} starts at {second_start}. " + additional) | ||
|
||
class ChannelsWithDifferentDomainsError(TimeError): | ||
def __init__(self, domains_by_channel_name: dict[str, Timeline], additional: str = ''): | ||
super().__init__(f"The channels of this Biosignal do not have the same domain. " | ||
+ additional + "\n" | ||
+ "\n".join([f"{channel_name}: {domain}" for channel_name, domain in domains_by_channel_name.items()])) | ||
|
||
|
||
class OverlappingError(TimeError): | ||
def __init__(self, what: str): | ||
super().__init__(f"There is an overlap between {what}") | ||
|
||
|
||
class TimeseriesOverlappingError(OverlappingError): | ||
def __init__(self, first, second, *overlap: DateTimeRange): | ||
super().__init__(f"Timeseries {first} and Timeseries {second}" + f" on {overlap}." if overlap else ".") | ||
|
||
|
||
class OperationError(Exception): | ||
... | ||
|
||
|
||
class UndoableOperationError(OperationError): | ||
def __init__(self, operation, by_nature: bool): | ||
note = f"Operation {operation} is undoable" | ||
if by_nature: | ||
note += " by nature, i.e. there is no mathematical way of reversing it or, at least, it's not implemented." | ||
else: | ||
note += ", most likely because this operation was what created this object." | ||
super().__init__(note) | ||
|
||
|
||
class BiosignalError(Exception): | ||
... | ||
|
||
|
||
class ChannelNotFoundError(BiosignalError, IndexError, AttributeError): | ||
def __init__(self, name): | ||
super().__init__(f"There is no channel named '{name}'.") | ||
|
||
|
||
class EventNotFoundError(BiosignalError, IndexError, AttributeError): | ||
def __init__(self, name: str): | ||
super().__init__(f"There is no event named '{name}'.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# -- encoding: utf-8 -- | ||
# =================================== | ||
# ScientISST LTBio | Long-Term Biosignals | ||
from abc import ABC, abstractmethod | ||
from datetime import datetime | ||
from typing import Any, ClassVar | ||
|
||
from .exceptions import UndoableOperationError | ||
|
||
|
||
# Package: | ||
# Module: | ||
# Description: | ||
|
||
# Contributors: João Saraiva | ||
# Created: | ||
# Last Updated: | ||
# =================================== | ||
|
||
|
||
class Operator(ABC): | ||
NAME: str | ||
DESCRIPTION: str | ||
SHORT: str | ||
|
||
def __init__(self, **parameters): | ||
... | ||
|
||
def __call__(self, *args, **kwargs) -> Any: | ||
result, _ = self._apply(*args, **kwargs) | ||
return | ||
|
||
@abstractmethod | ||
def _apply(self, *args, **kwargs) -> (Any, 'Operation'): | ||
pass | ||
|
||
@abstractmethod | ||
def _undo(self, *args, **kwargs): | ||
raise NotImplementedError() | ||
|
||
@property | ||
def is_reversible(self) -> bool: | ||
# Check if "_undo" method is implemented, not if it is callable | ||
try: | ||
x = self._undo | ||
return True | ||
except NotImplementedError: | ||
return False | ||
|
||
|
||
class Operation: | ||
def __init__(self, operator: Operator, when: datetime, allow_undo: bool, *objects, **kwargs): | ||
self.__operator = operator | ||
self.__when = when | ||
self.__objects = objects | ||
self.__kwargs = kwargs | ||
self.__allow_undo = allow_undo | ||
|
||
# Getters | ||
@property | ||
def operator(self) -> Operator: | ||
return self.__operator | ||
|
||
@property | ||
def when(self) -> datetime: | ||
return self.__when | ||
|
||
@property | ||
def objects(self): | ||
return self.__objects | ||
|
||
@property | ||
def is_undoable(self) -> bool: | ||
return self.__allow_undo and hasattr(self.__operator, "undo") | ||
|
||
def undo(self): | ||
if not self.__allow_undo: | ||
raise UndoableOperationError(self, by_nature=False) | ||
if not hasattr(self, "undo"): | ||
raise UndoableOperationError(self, by_nature=True) | ||
return self.__operator.undo(*self.__objects, **self.__kwargs) | ||
|
||
def __str__(self): | ||
return str(self.__operator) | ||
|
||
def __repr__(self): | ||
return repr(self.__operator) + " performed in " + str(self.__when) | ||
|
||
|
||
class ArithmeticOperator(Operator, ABC): ... | ||
|
||
|
||
class BinaryOperator(Operator, ABC): ... | ||
|
||
|
||
class UnaryOperator(Operator, ABC): ... | ||
|
||
|
||
class Addition(ArithmeticOperator, BinaryOperator): | ||
NAME = "Add" | ||
DESCRIPTION = "Adds two Biosignals, Timeseries or Segments, sample by sample." | ||
SHORT = "+" | ||
|
||
def _apply(self, first, second): | ||
return first + second | ||
|
||
def _undo(self, first, second): | ||
return first - second |
Oops, something went wrong.