"""
python celltk/postprocess.py -f gap_closing -i c0/img_00000000* -l c2/img_00000000*  -o c3 -p DISPLACEMENT=30
"""

from scipy.ndimage import imread
import argparse
import tifffile as tiff
from os.path import basename, join
import numpy as np
import postprocess_operation
from utils.postprocess_utils import regionprops, LCell # set default parent and next as None
from utils.file_io import make_dirs, imsave, lbread
from utils.filters import labels2outlines
from scipy.ndimage import binary_dilation
from utils.parser import ParamParser
from utils.global_holder import holder
import logging

logger = logging.getLogger(__name__)


def neg2poslabels(labels):
    maxint = labels.max()
    negatives = np.unique(labels[labels < 0])
    for i in negatives:
        maxint += 1
        labels[labels == i] = maxint
    return labels


def cells2labels0(cells, frame, shape):
    inframe = [i for i in cells if i.frame == frame]
    template = np.zeros(shape)
    for cell in inframe:
        for c0, c1 in cell.coords:
            template[c0, c1] = cell.label
    return template


def cells2labels(cells, frame, labels):
    inframe = [i for i in cells if i.frame == frame]
    template = np.zeros(labels.shape)
    for cell in inframe:
        template[labels == cell._original_label] = cell.label
        if cell.parent is not None:
            outline = labels2outlines(binary_dilation(template == cell.label))
            # outline = labels2outlines(template == cell.label)
            template[outline > 0] = -cell.parent
    return template


def caller(inputs, inputs_labels, output, functions, params):
    make_dirs(output)

    # Make cells. cells are a list of regionproperties or subclasses.
    logger.info('Postprocess.\tcollecting cells...')
    store = []
    for frame, (path, pathl) in enumerate(zip(inputs, inputs_labels)):
        img, labels = imread(path), lbread(pathl)
        cells = regionprops(labels, img)
        cells = [LCell(cell) for cell in cells]
        for cell in cells:
            cell.frame = frame
            if frame > 0:
                all_labels = [i.label for i in store[frame - 1]]
                if cell.label in all_labels:
                    store[frame - 1][all_labels.index(cell.label)].nxt = cell
        store.append(cells)
    cells = [i for j in store for i in j]
    # Each function receives cells (regionprops) and finally return labels generated by cells.label
    for function, param in zip(functions, params):
        logger.info('\trunning {0}'.format(function))
        func = getattr(postprocess_operation, function)
        cells = func(cells, **param)

    logger.info('\tsaving images...')
    for frame, (path, pathl) in enumerate(zip(inputs, inputs_labels)):
        labels = cells2labels(cells, frame, lbread(pathl))
        imsave(labels, output, path, dtype=np.int16)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--input", help="images", nargs="+")
    parser.add_argument("-l", "--labels", help="labels", nargs="+")
    parser.add_argument("-o", "--output", help="output directory", type=str, default='temp')
    parser.add_argument("-f", "--functions", help="functions", nargs="+")
    parser.add_argument('-p', '--param', nargs='+', help='parameters', action='append')
    args = parser.parse_args()

    if args.functions is None:
        print help(postprocess_operation)
        return

    params = ParamParser(args.param).run()
    params = [{}, {}]  # FIXME
    holder.args = args

    caller(args.input, args.labels, args.output, args.functions, params)

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    main()

"""
python celltk/postprocess.py -f gap_closing -i c0/img_00000000* -l c2/img_00000000*  -o c3 -p DISPLACEMENT=30
"""

from scipy.ndimage import imread
import argparse
import tifffile as tiff
from os.path import basename, join
import numpy as np
import postprocess_operation
from utils.postprocess_utils import regionprops, LCell # set default parent and next as None
from utils.file_io import make_dirs, imsave, lbread
from utils.filters import labels2outlines
from scipy.ndimage import binary_dilation
from utils.parser import ParamParser
from utils.global_holder import holder
import logging

logger = logging.getLogger(__name__)


def neg2poslabels(labels):
    maxint = labels.max()
    negatives = np.unique(labels[labels < 0])
    for i in negatives:
        maxint += 1
        labels[labels == i] = maxint
    return labels


def cells2labels0(cells, frame, shape):
    inframe = [i for i in cells if i.frame == frame]
    template = np.zeros(shape)
    for cell in inframe:
        for c0, c1 in cell.coords:
            template[c0, c1] = cell.label
    return template


def cells2labels(cells, frame, labels):
    inframe = [i for i in cells if i.frame == frame]
    template = np.zeros(labels.shape)
    for cell in inframe:
        template[labels == cell._original_label] = cell.label
        if cell.parent is not None:
            outline = labels2outlines(binary_dilation(template == cell.label))
            # outline = labels2outlines(template == cell.label)
            template[outline > 0] = -cell.parent
    return template


def caller(inputs, inputs_labels, output, functions, params):
    make_dirs(output)

    # Make cells. cells are a list of regionproperties or subclasses.
    logger.info('Postprocess.\tcollecting cells...')
    store = []
    for frame, (path, pathl) in enumerate(zip(inputs, inputs_labels)):
        img, labels = imread(path), lbread(pathl)
        cells = regionprops(labels, img)
        cells = [LCell(cell) for cell in cells]
        for cell in cells:
            cell.frame = frame
            if frame > 0:
                all_labels = [i.label for i in store[frame - 1]]
                if cell.label in all_labels:
                    store[frame - 1][all_labels.index(cell.label)].nxt = cell
        store.append(cells)
    cells = [i for j in store for i in j]
    # Each function receives cells (regionprops) and finally return labels generated by cells.label
    for function, param in zip(functions, params):
        logger.info('\trunning {0}'.format(function))
        func = getattr(postprocess_operation, function)
        cells = func(cells, **param)

    logger.info('\tsaving images...')
    for frame, (path, pathl) in enumerate(zip(inputs, inputs_labels)):
        labels = cells2labels(cells, frame, lbread(pathl))
        imsave(labels, output, path, dtype=np.int16)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--input", help="images", nargs="+")
    parser.add_argument("-l", "--labels", help="labels", nargs="+")
    parser.add_argument("-o", "--output", help="output directory", type=str, default='temp')
    parser.add_argument("-f", "--functions", help="functions", nargs="+")
    parser.add_argument('-p', '--param', nargs='+', help='parameters', action='append')
    args = parser.parse_args()

    if args.functions is None:
        print help(postprocess_operation)
        return

    params = ParamParser(args.param).run()
    params = [{}, {}]  # FIXME
    holder.args = args

    caller(args.input, args.labels, args.output, args.functions, params)

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    main()

python celltk/postprocess.py -f gap_closing -i c0/img_00000000* -l c2/img_00000000*  -o c3 -p DISPLACEMENT=30 # set default parent and next as None # outline = labels2outlines(template == cell.label) # Make cells. cells are a list of regionproperties or subclasses. # Each function receives cells (regionprops) and finally return labels generated by cells.label # FIXME