cytometer/data.py
def aida_write_new_items(filename, items, mode='append_to_last_layer', indent=0, ensure_ascii=False,
                         double_precision=10, number_of_attempts=1):
    """
    Create a new or update existing AIDA annotations file, adding new items.
    :param filename: String with path to .json annotations file.
    :param items: List of items, obtained e.g. with aida_contour_items() or aida_rectangle_items().
    :param mode:
        - 'append_to_last_layer': (def) Append items to the last layer with the same item type.
        - 'append_new_layer': Create new layer for items.
        - 'w': Overwrite existing file, or create a new one with only these items.
    :param indent: (def 0) Number of indentation spaces for pretty print format. By default, 0, everything is saved to
    one line without spaces.
    :param ensure_ascii: (def False) Limits output to ASCII and escapes all extended characters above 127. Default is
    true. If your end format supports UTF-8 setting this option to false is highly recommended to save space.
    :param double_precision: (def 10) Controls how many decimals to encode for double or decimal values.
    :param number_of_attempts: (def 1) Number of times we try to write the file if the server returns
    ConnectionResetError.
    :return:
    * None
    """

    if type(items) != list:
        raise SyntaxError('items must be a list, but is type: ' + type(items))

    # get item type
    item_type = items[0]['type']

    # layer name that corresponds to this item type
    if item_type == 'path':
        layer_name = 'White adipocyte'
    elif item_type == 'rectangle':
        layer_name = 'Blocks'
    else:
        raise NotImplementedError('item_type not implemented: ' + item_type)

    # if an annotations file already exists with the filename path, read it so that we can add to it
    if mode != 'w' and os.path.isfile(filename):

        # load existing data
        with open(filename) as fp:
            annotations = ujson.load(fp)

        # check that this file has the expected format
        if 'name' not in annotations:
            raise KeyError('Annotations have no \'name\' key')
        if 'layers' not in annotations:
            raise KeyError('Annotations have no \'layers\' key')

    else:  # if previous file doesn't exist, create an annotations file from scratch

        # top-most segmentation object. It contains only one layer
        annotations = {'name': 'DeepCytometer annotations', 'layers': []}

    if DEBUG:
        print('Loaded file: ' + filename)
        print('Annotations name: ' + annotations['name'])
        print('Number of layers: ' + str(len(annotations['layers'])))
        for j in range(len(annotations['layers'])):
            print('    Layer ' + str(j) + ': ' + annotations['layers'][j]['name'] + '. Number of '
                  + annotations['layers'][j]['items'][0]['type'] + ' items: '
                  + str(len(annotations['layers'][j]['items'])))

    # find the last layer for the current item type, if there's any
    i_layer = layer_number = []  # in case there isn't any layer of this type
    for l in range(len(annotations['layers'])):
        if layer_name in annotations['layers'][l]['name']:
            # index of layer where we are going to append items
            i_layer = l
            # number that we are going to add to the layer name. Note that this, in general, will be different from
            # the layer's index
            layer_number = int(annotations['layers'][l]['name'].replace(layer_name, ''))

    # if no layer exists, we'll need to add a new layer
    if i_layer == []:
        mode = 'append_new_layer'
        layer_number = -1

    # if we want to append items to a new layer
    if mode == 'append_new_layer':

        # new layer object
        layer = {'name': layer_name + ' ' + str(layer_number + 1), 'opacity': 1.0, 'items': items}

        # append layer to current annotations
        annotations['layers'] += [layer, ]

    elif mode == 'append_to_last_layer':

        # append items to currently selected layer
        annotations['layers'][i_layer]['items'] += items

    else:
        raise NotImplementedError('mode not implemented: ' + mode)

    # if we are trying to save to a network filesystem, the server hosting the filesystem may return a
    # ConnectionResetError. Because this would corrupt the output file, we let the user try a couple of times, with
    # with a little wait between tries
    for attempt in range(number_of_attempts):
        try:
            # write annotations to file
            with open(filename, 'w') as fp:
                ujson.dump(annotations, fp, indent=indent, ensure_ascii=ensure_ascii)
            break
        except ConnectionResetError:
            print('# ======> ConnectionResetError. Attempt ' + str(attempt) + '/' + str(number_of_attempts) + ' ...')
            time.sleep(5)  # secs
        except BrokenPipeError:
            print('# ======> BrokenPipeError. Attempt ' + str(attempt) + '/' + str(number_of_attempts) + ' ...')
            time.sleep(5)  # secs
        except:
            raise

    Create a new or update existing AIDA annotations file, adding new items.
    :param filename: String with path to .json annotations file.
    :param items: List of items, obtained e.g. with aida_contour_items() or aida_rectangle_items().
    :param mode:
        - 'append_to_last_layer': (def) Append items to the last layer with the same item type.
        - 'append_new_layer': Create new layer for items.
        - 'w': Overwrite existing file, or create a new one with only these items.
    :param indent: (def 0) Number of indentation spaces for pretty print format. By default, 0, everything is saved to
    one line without spaces.
    :param ensure_ascii: (def False) Limits output to ASCII and escapes all extended characters above 127. Default is
    true. If your end format supports UTF-8 setting this option to false is highly recommended to save space.
    :param double_precision: (def 10) Controls how many decimals to encode for double or decimal values.
    :param number_of_attempts: (def 1) Number of times we try to write the file if the server returns
    ConnectionResetError.
    :return:
    * None
    
Create a new or update existing AIDA annotations file, adding new items.
Create a new or update existing AIDA annotations file adding new items .
def aida_write_new_items(filename, items, mode='append_to_last_layer', indent=0, ensure_ascii=False,
                         double_precision=10, number_of_attempts=1):
    if type(items) != list:
        raise SyntaxError('items must be a list, but is type: ' + type(items))
    item_type = items[0]['type']
    if item_type == 'path':
        layer_name = 'White adipocyte'
    elif item_type == 'rectangle':
        layer_name = 'Blocks'
    else:
        raise NotImplementedError('item_type not implemented: ' + item_type)
    if mode != 'w' and os.path.isfile(filename):
        with open(filename) as fp:
            annotations = ujson.load(fp)
        if 'name' not in annotations:
            raise KeyError('Annotations have no \'name\' key')
        if 'layers' not in annotations:
            raise KeyError('Annotations have no \'layers\' key')
    else:  
        annotations = {'name': 'DeepCytometer annotations', 'layers': []}
    if DEBUG:
        print('Loaded file: ' + filename)
        print('Annotations name: ' + annotations['name'])
        print('Number of layers: ' + str(len(annotations['layers'])))
        for j in range(len(annotations['layers'])):
            print('    Layer ' + str(j) + ': ' + annotations['layers'][j]['name'] + '. Number of '
                  + annotations['layers'][j]['items'][0]['type'] + ' items: '
                  + str(len(annotations['layers'][j]['items'])))
    i_layer = layer_number = []  
    for l in range(len(annotations['layers'])):
        if layer_name in annotations['layers'][l]['name']:
            i_layer = l
            layer_number = int(annotations['layers'][l]['name'].replace(layer_name, ''))
    if i_layer == []:
        mode = 'append_new_layer'
        layer_number = -1
    if mode == 'append_new_layer':
        layer = {'name': layer_name + ' ' + str(layer_number + 1), 'opacity': 1.0, 'items': items}
        annotations['layers'] += [layer, ]
    elif mode == 'append_to_last_layer':
        annotations['layers'][i_layer]['items'] += items
    else:
        raise NotImplementedError('mode not implemented: ' + mode)
    for attempt in range(number_of_attempts):
        try:
            with open(filename, 'w') as fp:
                ujson.dump(annotations, fp, indent=indent, ensure_ascii=ensure_ascii)
            break
        except ConnectionResetError:
            print('# ======> ConnectionResetError. Attempt ' + str(attempt) + '/' + str(number_of_attempts) + ' ...')
            time.sleep(5)  
        except BrokenPipeError:
            print('# ======> BrokenPipeError. Attempt ' + str(attempt) + '/' + str(number_of_attempts) + ' ...')
            time.sleep(5)  
        except:
            raise
def aida_write_new_items ( filename , items , mode = 'append_to_last_layer' , indent = 0 , ensure_ascii = False , double_precision = 10 , number_of_attempts = 1 ) : if type ( items ) != list : raise SyntaxError ( 'items must be a list, but is type: ' + type ( items ) ) item_type = items [ 0 ] [ 'type' ] if item_type == 'path' : layer_name = 'White adipocyte' elif item_type == 'rectangle' : layer_name = 'Blocks' else : raise NotImplementedError ( 'item_type not implemented: ' + item_type ) if mode != 'w' and os . path . isfile ( filename ) : with open ( filename ) as fp : annotations = ujson . load ( fp ) if 'name' not in annotations : raise KeyError ( 'Annotations have no \'name\' key' ) if 'layers' not in annotations : raise KeyError ( 'Annotations have no \'layers\' key' ) else : annotations = { 'name' : 'DeepCytometer annotations' , 'layers' : [ ] } if DEBUG : print ( 'Loaded file: ' + filename ) print ( 'Annotations name: ' + annotations [ 'name' ] ) print ( 'Number of layers: ' + str ( len ( annotations [ 'layers' ] ) ) ) for j in range ( len ( annotations [ 'layers' ] ) ) : print ( '    Layer ' + str ( j ) + ': ' + annotations [ 'layers' ] [ j ] [ 'name' ] + '. Number of ' + annotations [ 'layers' ] [ j ] [ 'items' ] [ 0 ] [ 'type' ] + ' items: ' + str ( len ( annotations [ 'layers' ] [ j ] [ 'items' ] ) ) ) i_layer = layer_number = [ ] for l in range ( len ( annotations [ 'layers' ] ) ) : if layer_name in annotations [ 'layers' ] [ l ] [ 'name' ] : i_layer = l layer_number = int ( annotations [ 'layers' ] [ l ] [ 'name' ] . replace ( layer_name , '' ) ) if i_layer == [ ] : mode = 'append_new_layer' layer_number = - 1 if mode == 'append_new_layer' : layer = { 'name' : layer_name + ' ' + str ( layer_number + 1 ) , 'opacity' : 1.0 , 'items' : items } annotations [ 'layers' ] += [ layer , ] elif mode == 'append_to_last_layer' : annotations [ 'layers' ] [ i_layer ] [ 'items' ] += items else : raise NotImplementedError ( 'mode not implemented: ' + mode ) for attempt in range ( number_of_attempts ) : try : with open ( filename , 'w' ) as fp : ujson . dump ( annotations , fp , indent = indent , ensure_ascii = ensure_ascii ) break except ConnectionResetError : print ( '# ======> ConnectionResetError. Attempt ' + str ( attempt ) + '/' + str ( number_of_attempts ) + ' ...' ) time . sleep ( 5 ) except BrokenPipeError : print ( '# ======> BrokenPipeError. Attempt ' + str ( attempt ) + '/' + str ( number_of_attempts ) + ' ...' ) time . sleep ( 5 ) except : raise
Create a new or update existing AIDA annotations file, adding new items.
Create a new or update existing AIDA annotations file adding new items .
"""
    Create a new or update existing AIDA annotations file, adding new items.
    :param filename: String with path to .json annotations file.
    :param items: List of items, obtained e.g. with aida_contour_items() or aida_rectangle_items().
    :param mode:
        - 'append_to_last_layer': (def) Append items to the last layer with the same item type.
        - 'append_new_layer': Create new layer for items.
        - 'w': Overwrite existing file, or create a new one with only these items.
    :param indent: (def 0) Number of indentation spaces for pretty print format. By default, 0, everything is saved to
    one line without spaces.
    :param ensure_ascii: (def False) Limits output to ASCII and escapes all extended characters above 127. Default is
    true. If your end format supports UTF-8 setting this option to false is highly recommended to save space.
    :param double_precision: (def 10) Controls how many decimals to encode for double or decimal values.
    :param number_of_attempts: (def 1) Number of times we try to write the file if the server returns
    ConnectionResetError.
    :return:
    * None
    """ # get item type # layer name that corresponds to this item type # if an annotations file already exists with the filename path, read it so that we can add to it # load existing data # check that this file has the expected format # if previous file doesn't exist, create an annotations file from scratch # top-most segmentation object. It contains only one layer # find the last layer for the current item type, if there's any # in case there isn't any layer of this type # index of layer where we are going to append items # number that we are going to add to the layer name. Note that this, in general, will be different from # the layer's index # if no layer exists, we'll need to add a new layer # if we want to append items to a new layer # new layer object # append layer to current annotations # append items to currently selected layer # if we are trying to save to a network filesystem, the server hosting the filesystem may return a # ConnectionResetError. Because this would corrupt the output file, we let the user try a couple of times, with # with a little wait between tries # write annotations to file # secs # secs
None
filename
String with path to .json annotations file.
String with path to . json annotations file .
items
List of items, obtained e.g. with aida_contour_items() or aida_rectangle_items().
List of items obtained e . g . with aida_contour_items () or aida_rectangle_items () .
mode
'append_to_last_layer': (def) Append items to the last layer with the same item type.
'append_new_layer': Create new layer for items.
'w': Overwrite existing file, or create a new one with only these items.
' append_to_last_layer ' : ( def ) Append items to the last layer with the same item type . ' append_new_layer ' : Create new layer for items . ' w ' : Overwrite existing file or create a new one with only these items .
indent
(def 0) Number of indentation spaces for pretty print format. By default, 0, everything is saved to
one line without spaces.
( def 0 ) Number of indentation spaces for pretty print format . By default 0 everything is saved to one line without spaces .
ensure_ascii
(def False) Limits output to ASCII and escapes all extended characters above 127. Default is
true. If your end format supports UTF-8 setting this option to false is highly recommended to save space.
( def False ) Limits output to ASCII and escapes all extended characters above 127 . Default is true . If your end format supports UTF - 8 setting this option to false is highly recommended to save space .
double_precision
(def 10) Controls how many decimals to encode for double or decimal values.
( def 10 ) Controls how many decimals to encode for double or decimal values .
number_of_attempts
(def 1) Number of times we try to write the file if the server returns
ConnectionResetError.
( def 1 ) Number of times we try to write the file if the server returns ConnectionResetError .