def query_annotations(self, ts, layer, start=None, end=None, channels=None, limit=100, offset=0): """ Retrieves timeseries annotations for a particular range on array of channels. """ ch_list = self.requested_channels(ts, channels) ts_start, ts_end = ts.limits() if start is None: start = ts_start elif isinstance(start, datetime.datetime): start = usecs_since_epoch(start) if end is None: end = ts_end elif isinstance(end, datetime.datetime): end = usecs_since_epoch(end) params = { 'start': int(start), 'end': int(end), 'channelIds': ch_list, 'layerName': layer.name, 'limit': limit, 'offset': offset } path = self._uri('/{ts_id}/layers/{layer_id}/annotations', ts_id = ts.id,layer_id = layer.id) resp = self._get(path, params=params) return [TimeSeriesAnnotation.from_dict(x, api=self.session) for x in resp['annotations']['results']]
def test_timeseries_annotations_can_get_more_than_default_limit(timeseries): ch = TimeSeriesChannel(name="test_channel", rate=256, unit="uV", start=0, end=2e6) timeseries.add_channels(ch) layer = TimeSeriesAnnotationLayer( name="limit_layer", time_series_id=timeseries.id, description="layer with many small annotations", ) timeseries.add_layer(layer) for i in range(200): annotation = TimeSeriesAnnotation( label="annotation_{}".format(i), channel_ids=ch.id, start=i * 1e4, end=(i + 1) * 1e4, ) layer.add_annotations(annotation) # Should retrieve all annotations assert len(layer.annotations()) == 200 # All of these annotations should be in the first 10-second window annots = next(layer.iter_annotations()) assert len(annots) == 200 layer.delete()
def update_annotation(self, ts, layer, annot): """ Update annotation on the platform. """ path = self._uri('/{ts_id}/layers/{layer_id}/annotations/{annot_id}', ts_id=self._get_id(ts), layer_id=self._get_id(layer), annot_id=self._get_id(annot)) resp = self._put(path, json=annot.as_dict()) return TimeSeriesAnnotation.from_dict(resp, api=self.session)
def get_annotation(self, ts, layer, annot): """ Returns a timeseries annotation """ path = self._uri('/{ts_id}/layers/{layer_id}/annotations/{annot_id}', ts_id = self._get_id(ts), layer_id = self._get_id(layer), annot_id = self._get_id(annot)) resp = self._get(path) return TimeSeriesAnnotation.from_dict(resp["annotation"], api=self.session)
def create_annotation(self, layer, annotation, **kwargs): """ Creates annotation for some timeseries package on the platform. """ if isinstance(annotation, TimeSeriesAnnotation): data = annotation.as_dict() elif all(x in kwargs for x in ["start", "end"]): start_time = infer_epoch(kwargs["start"]) end_time = infer_epoch(kwargs["end"]) data = { "name": "", "label": annotation, "start": int(start_time), "end": int(end_time), } if kwargs["channel_ids"]: channel_ids = kwargs["channel_ids"] if isinstance(channel_ids, string_types): channel_ids = [channel_ids] data["channelIds"] = channel_ids else: ts = layer._api.core.get(layer.time_series_id) data["channelIds"] = [x.id for x in ts.channels] if "description" in annotation: data["description"] = kwargs["description"] else: data["description"] = None else: raise Exception( "Must provide TimeSeriesAnnotation object or 'annotation','start','end' at minimum" ) data["time_series_id"] = layer.time_series_id data["layer_id"] = layer.id path = self._uri( "/{ts_id}/layers/{layer_id}/annotations", ts_id=layer.time_series_id, layer_id=layer.id, ) resp = self._post(path, json=data) tmp = TimeSeriesAnnotation.from_dict(resp, api=self.session) if isinstance(annotation, TimeSeriesAnnotation): annotation.__dict__.update(tmp.__dict__) return tmp
def create_annotation(self, layer, annotation, **kwargs): """ Creates annotation for some timeseries package on the platform. """ if isinstance(annotation, TimeSeriesAnnotation): data = annotation.as_dict() elif all(x in kwargs for x in ['start', 'end']): start_time = infer_epoch(kwargs['start']) end_time = infer_epoch(kwargs['end']) data = { 'name': '', 'label': annotation, 'start': long(start_time), 'end': long(end_time), } if kwargs['channel_ids']: channel_ids = kwargs['channel_ids'] if isinstance(channel_ids, basestring): channel_ids = [channel_ids] data['channelIds'] = channel_ids else: ts = layer._api.core.get(layer.time_series_id) data['channelIds'] = [x.id for x in ts.channels] if 'description' in annotation: data['description'] = kwargs['description'] else: data['description'] = None else: raise Exception( "Must provide TimeSeriesAnnotation object or 'annotation','start','end' at minimum" ) data['time_series_id'] = layer.time_series_id data['layer_id'] = layer.id path = self._uri('/{ts_id}/layers/{layer_id}/annotations', ts_id=layer.time_series_id, layer_id=layer.id) resp = self._post(path, json=data) tmp = TimeSeriesAnnotation.from_dict(resp, api=self.session) if isinstance(annotation, TimeSeriesAnnotation): annotation.__dict__.update(tmp.__dict__) return tmp
def test_timeseries_annotations(client, timeseries): assert timeseries.exists print 'layers = ', timeseries.layers #Create Layer layer1 = TimeSeriesAnnotationLayer(name="test_layer", time_series_id = timeseries.id, description="test_description") a = layer1.as_dict() assert a['name'] == 'test_layer' assert a['description'] == 'test_description' # Add Layer timeseries.add_layer(layer1) assert layer1.exists # Get Layer layer1b = timeseries.get_layer('test_layer') assert layer1b.exists assert layer1b.name == "test_layer" assert layer1.id == layer1b.id assert layer1._api.timeseries is not None # Add another layer layer2 = timeseries.add_layer('test_layer2','test_description2') assert layer2.exists layer2copy = timeseries.add_layer('test_layer2') assert layer2copy.id == layer2.id # Get Layer layer2b = timeseries.get_layer('test_layer2') assert layer2b.exists assert layer2b.name == "test_layer2" assert layer2.id == layer2b.id assert layer2._api.timeseries is not None layers = timeseries.layers assert len(layers)==2 assert layers[0].name == "test_layer" assert layers[1].name == 'test_layer2' #Create channels ch = TimeSeriesChannel( name='test_channel', rate=256, unit='uV', start=1, end=60*1e6) #Create annotation over one channel # create timeseries.add_channels(ch) assert ch.exists assert ch.id in [x.id for x in timeseries.channels] annot = TimeSeriesAnnotation(label = 'test_label', channel_ids = timeseries.channels[0].id,start = timeseries.channels[0].start,end=timeseries.channels[0].start+1*1e6) #Add Annotation layer1.add_annotations(annot) assert annot.exists # get annotations annotb = layer1.annotations() print "annotations = ", annotb assert annotb[0].label == annot.label #Create annotation over multiple channels ch2 = TimeSeriesChannel( name='test_channel', rate=256, unit='uV', start=1, end=60*1e6) timeseries.add_channels(ch2) channels = timeseries.channels ch_ids = [x.id for x in channels] assert ch2.exists assert ch2.id in ch_ids assert ch.id in ch_ids for ch in channels: assert ch.rate == 256 assert ch.exists #add annotation over two channels channel_ids = [timeseries.channels[x].id for x in range(len(timeseries.channels))] annot2 = layer1.insert_annotation(annotation='test_label2', channel_ids = channel_ids, start =timeseries.channels[0].start+1*1e6, end = timeseries.channels[0].start+2*1e6) assert annot2.exists annot_gen = layer1.iter_annotations(1) annot = annot_gen.next() assert annot[0].label == 'test_label' next_annot= annot_gen.next() assert next_annot[0].label == 'test_label2' ### TEST DELETION annot3 = TimeSeriesAnnotation(label= 'test_label3', channel_ids= channel_ids,start = timeseries.channels[0].start+1*1e6,end=timeseries.channels[0].start+2*1e6) #layer1.add_annotations([annot2,annot3]) annot3 = timeseries.add_annotations(layer=layer1,annotations=annot3) assert annot3.exists annot3.delete() assert not annot3.exists annot4 = timeseries.insert_annotation(layer=layer1,annotation='test_label3',start= timeseries.channels[0].start+1*1e6,end=timeseries.channels[0].start+2*1e6) assert annot4.exists annot4.delete() assert not annot4.exists annot5 = timeseries.insert_annotation(layer='test_layer4',annotation='test_label3',start=timeseries.channels[0].start+1*1e6,end=timeseries.channels[0].start+2*1e6) assert annot5.exists annot5.delete() assert not annot5.exists layer1.add_annotations([annot2,annot3]) assert annot2.exists assert annot3.exists #test datetime input annot4 = timeseries.insert_annotation(layer='test_layer4',annotation='test_label3',start= datetime.datetime.utcfromtimestamp((timeseries.channels[0].start+1*1e6)/1e6),end=datetime.datetime.utcfromtimestamp(timeseries.channels[0].start+2*1e6)) assert annot4.exists annot4.delete() assert not annot4.exists layer = timeseries.get_layer('test_layer4') assert layer.exists layer.delete() assert not layer.exists # delete annotations annot[0].delete() assert not annot[0].exists assert timeseries.exists timeseries.delete_layer(layer1) assert not layer1.exists assert layer2.exists layer2.delete() assert not layer2.exists
def test_timeseries_annotations(client, timeseries): assert timeseries.exists print("layers = ", timeseries.layers) # Create Layer layer1 = TimeSeriesAnnotationLayer(name="test_layer", time_series_id=timeseries.id, description="test_description") a = layer1.as_dict() assert a["name"] == "test_layer" assert a["description"] == "test_description" # Add Layer timeseries.add_layer(layer1) assert layer1.exists # Get Layer layer1b = timeseries.get_layer("test_layer") assert layer1b.exists assert layer1b.name == "test_layer" assert layer1.id == layer1b.id assert layer1._api.timeseries is not None # Add another layer layer2 = timeseries.add_layer("test_layer2", "test_description2") assert layer2.exists layer2copy = timeseries.add_layer("test_layer2") assert layer2copy.id == layer2.id # Get Layer layer2b = timeseries.get_layer("test_layer2") assert layer2b.exists assert layer2b.name == "test_layer2" assert layer2.id == layer2b.id assert layer2._api.timeseries is not None layers = timeseries.layers assert len(layers) == 2 assert set([layers[0].name, layers[1].name]) == set(["test_layer", "test_layer2"]) # Create channels ch = TimeSeriesChannel(name="test_channel", rate=256, unit="uV", start=1, end=60 * 1e6) # Create annotation over one channel # create timeseries.add_channels(ch) assert ch.exists assert ch.id in [x.id for x in timeseries.channels] annot = TimeSeriesAnnotation( label="test_label", channel_ids=timeseries.channels[0].id, start=timeseries.channels[0].start, end=timeseries.channels[0].start + 1 * 1e6, ) # Add Annotation layer1.add_annotations(annot) assert annot.exists # get annotations annotb = layer1.annotations() assert annotb[0].label == annot.label annotc = client._api.timeseries.get_annotation(timeseries, layer1, annot) assert annotc.label == annot.label # Create annotation over multiple channels ch2 = TimeSeriesChannel(name="test_channel", rate=256, unit="uV", start=1, end=60 * 1e6) timeseries.add_channels(ch2) channels = timeseries.channels ch_ids = [x.id for x in channels] assert ch2.exists assert ch2.id in ch_ids assert ch.id in ch_ids for ch in channels: assert ch.rate == 256 assert ch.exists # add annotation over two channels channel_ids = [ timeseries.channels[x].id for x in range(len(timeseries.channels)) ] annot2 = layer1.insert_annotation( annotation="test_label2", channel_ids=channel_ids, start=timeseries.channels[0].start + 1 * 1e6, end=timeseries.channels[0].start + 2 * 1e6, ) assert annot2.exists annot_gen = layer1.iter_annotations(1) annot = next(annot_gen) assert annot[0].label == "test_label" next_annot = next(annot_gen) assert next_annot[0].label == "test_label2" ### TEST ANNOTATION COUNTS layer1_expected_counts = [ { "start": 0, "end": 250000, "value": 1.0 }, { "start": 250000, "end": 500000, "value": 1.0 }, { "start": 500000, "end": 750000, "value": 1.0 }, { "start": 750000, "end": 1000000, "value": 1.0 }, { "start": 1000000, "end": 1250000, "value": 2.0 }, { "start": 1250000, "end": 1500000, "value": 1.0 }, { "start": 1500000, "end": 1750000, "value": 1.0 }, { "start": 1750000, "end": 2000000, "value": 1.0 }, { "start": 2000000, "end": 2000001, "value": 1.0 }, ] def _sort_counts(counts): return sorted(counts, key=lambda c: c["start"]) assert (_sort_counts( timeseries.annotation_counts( start=timeseries.channels[0].start * 1e6, end=timeseries.channels[0].start + 2 * 1e6, layers=[layer1], period="0.25s", )[str(layer1.id)]) == layer1_expected_counts) assert (_sort_counts( layer1.annotation_counts( start=timeseries.channels[0].start * 1e6, end=timeseries.channels[0].start + 2 * 1e6, period="0.25s", )[str(layer1.id)]) == layer1_expected_counts) ### TEST DELETION annot3 = TimeSeriesAnnotation( label="test_label3", channel_ids=channel_ids, start=timeseries.channels[0].start + 1 * 1e6, end=timeseries.channels[0].start + 2 * 1e6, ) layer1.add_annotations([annot2, annot3]) annot3 = timeseries.add_annotations(layer=layer1, annotations=annot3) assert annot3.exists annot3.delete() assert not annot3.exists annot4 = timeseries.insert_annotation( layer=layer1, annotation="test_label3", start=timeseries.channels[0].start + 1 * 1e6, end=timeseries.channels[0].start + 2 * 1e6, ) assert annot4.exists annot4.delete() assert not annot4.exists annot5 = timeseries.insert_annotation( layer="test_layer4", annotation="test_label3", start=timeseries.channels[0].start + 1 * 1e6, end=timeseries.channels[0].start + 2 * 1e6, ) assert annot5.exists annot5.delete() assert not annot5.exists layer1.add_annotations([annot2, annot3]) assert annot2.exists assert annot3.exists # test datetime input annot4 = timeseries.insert_annotation( layer="test_layer4", annotation="test_label3", start=datetime.datetime.utcfromtimestamp( (timeseries.channels[0].start + 1 * 1e6) / 1e6), end=datetime.datetime.utcfromtimestamp(timeseries.channels[0].start + 2 * 1e6), ) assert annot4.exists annot4.delete() assert not annot4.exists layer = timeseries.get_layer("test_layer4") assert layer.exists layer.delete() assert not layer.exists # delete annotations annot[0].delete() assert not annot[0].exists assert timeseries.exists timeseries.delete_layer(layer1) assert not layer1.exists assert layer2.exists layer2.delete() assert not layer2.exists
def test_timeseries_annotations(client, timeseries): assert timeseries.exists print('layers = ', timeseries.layers) #Create Layer layer1 = TimeSeriesAnnotationLayer(name="test_layer", time_series_id=timeseries.id, description="test_description") a = layer1.as_dict() assert a['name'] == 'test_layer' assert a['description'] == 'test_description' # Add Layer timeseries.add_layer(layer1) assert layer1.exists # Get Layer layer1b = timeseries.get_layer('test_layer') assert layer1b.exists assert layer1b.name == "test_layer" assert layer1.id == layer1b.id assert layer1._api.timeseries is not None # Add another layer layer2 = timeseries.add_layer('test_layer2', 'test_description2') assert layer2.exists layer2copy = timeseries.add_layer('test_layer2') assert layer2copy.id == layer2.id # Get Layer layer2b = timeseries.get_layer('test_layer2') assert layer2b.exists assert layer2b.name == "test_layer2" assert layer2.id == layer2b.id assert layer2._api.timeseries is not None layers = timeseries.layers assert len(layers) == 2 assert layers[0].name == "test_layer" assert layers[1].name == 'test_layer2' #Create channels ch = TimeSeriesChannel(name='test_channel', rate=256, unit='uV', start=1, end=60 * 1e6) #Create annotation over one channel # create timeseries.add_channels(ch) assert ch.exists assert ch.id in [x.id for x in timeseries.channels] annot = TimeSeriesAnnotation(label='test_label', channel_ids=timeseries.channels[0].id, start=timeseries.channels[0].start, end=timeseries.channels[0].start + 1 * 1e6) #Add Annotation layer1.add_annotations(annot) assert annot.exists # get annotations annotb = layer1.annotations() assert annotb[0].label == annot.label annotc = client._api.timeseries.get_annotation(timeseries, layer1, annot) assert annotc.label == annot.label #Create annotation over multiple channels ch2 = TimeSeriesChannel(name='test_channel', rate=256, unit='uV', start=1, end=60 * 1e6) timeseries.add_channels(ch2) channels = timeseries.channels ch_ids = [x.id for x in channels] assert ch2.exists assert ch2.id in ch_ids assert ch.id in ch_ids for ch in channels: assert ch.rate == 256 assert ch.exists #add annotation over two channels channel_ids = [ timeseries.channels[x].id for x in range(len(timeseries.channels)) ] annot2 = layer1.insert_annotation( annotation='test_label2', channel_ids=channel_ids, start=timeseries.channels[0].start + 1 * 1e6, end=timeseries.channels[0].start + 2 * 1e6) assert annot2.exists annot_gen = layer1.iter_annotations(1) annot = next(annot_gen) assert annot[0].label == 'test_label' next_annot = next(annot_gen) assert next_annot[0].label == 'test_label2' ### TEST ANNOTATION COUNTS layer1_expected_counts = [{ 'start': 0, 'end': 250000, 'value': 1.0 }, { 'start': 250000, 'end': 500000, 'value': 1.0 }, { 'start': 500000, 'end': 750000, 'value': 1.0 }, { 'start': 750000, 'end': 1000000, 'value': 1.0 }, { 'start': 1000000, 'end': 1250000, 'value': 2.0 }, { 'start': 1250000, 'end': 1500000, 'value': 1.0 }, { 'start': 1500000, 'end': 1750000, 'value': 1.0 }, { 'start': 1750000, 'end': 2000000, 'value': 1.0 }, { 'start': 2000000, 'end': 2000001, 'value': 1.0 }] def _sort_counts(counts): return sorted(counts, key=lambda c: c['start']) assert _sort_counts( timeseries.annotation_counts( start=timeseries.channels[0].start * 1e6, end=timeseries.channels[0].start + 2 * 1e6, layers=[layer1], period="0.25s")[str(layer1.id)]) == layer1_expected_counts assert _sort_counts( layer1.annotation_counts(start=timeseries.channels[0].start * 1e6, end=timeseries.channels[0].start + 2 * 1e6, period="0.25s")[str( layer1.id)]) == layer1_expected_counts ### TEST DELETION annot3 = TimeSeriesAnnotation(label='test_label3', channel_ids=channel_ids, start=timeseries.channels[0].start + 1 * 1e6, end=timeseries.channels[0].start + 2 * 1e6) layer1.add_annotations([annot2, annot3]) annot3 = timeseries.add_annotations(layer=layer1, annotations=annot3) assert annot3.exists annot3.delete() assert not annot3.exists annot4 = timeseries.insert_annotation( layer=layer1, annotation='test_label3', start=timeseries.channels[0].start + 1 * 1e6, end=timeseries.channels[0].start + 2 * 1e6) assert annot4.exists annot4.delete() assert not annot4.exists annot5 = timeseries.insert_annotation( layer='test_layer4', annotation='test_label3', start=timeseries.channels[0].start + 1 * 1e6, end=timeseries.channels[0].start + 2 * 1e6) assert annot5.exists annot5.delete() assert not annot5.exists layer1.add_annotations([annot2, annot3]) assert annot2.exists assert annot3.exists # test datetime input annot4 = timeseries.insert_annotation( layer='test_layer4', annotation='test_label3', start=datetime.datetime.utcfromtimestamp( (timeseries.channels[0].start + 1 * 1e6) / 1e6), end=datetime.datetime.utcfromtimestamp(timeseries.channels[0].start + 2 * 1e6)) assert annot4.exists annot4.delete() assert not annot4.exists layer = timeseries.get_layer('test_layer4') assert layer.exists layer.delete() assert not layer.exists # delete annotations annot[0].delete() assert not annot[0].exists assert timeseries.exists timeseries.delete_layer(layer1) assert not layer1.exists assert layer2.exists layer2.delete() assert not layer2.exists