# Path: dltk/utils.py
# def sliding_window_segmentation_inference(session,
#                                           ops_list,
#                                           sample_dict,
#                                           batch_size=1,
#                                           striding=None):
#     """
#     Utility function to perform sliding window inference for segmentation
# 
#     Args:
#         session (tf.Session): TensorFlow session to run ops with
# 
#         ops_list (array_like): Operators to fetch assemble with sliding window
# 
#         sample_dict (dict): Dictionary with tf.Placeholder keys mapping the
#         placeholders to their respective input
# 
#         batch_size (int, optional): Number of sliding windows to batch for
#             calculation
# 
#         striding (array_like): Striding of the sliding window. Can be used to
#             adjust overlap etc.
# 
#     Returns:
#         list: List of np.arrays corresponding to the assembled outputs of
#             ops_list
#     """
# 
#     # TODO: asserts
#     assert batch_size > 0, 'Batch size has to be 1 or bigger'
# 
#     pl_shape = list(sample_dict.keys())[0].get_shape().as_list()
# 
#     pl_bshape = pl_shape[1:-1]
# 
#     inp_shape = list(list(sample_dict.values())[0].shape)
#     inp_bshape = inp_shape[1:-1]
# 
#     out_dummies = [np.zeros(
#         [inp_shape[0], ] + inp_bshape + [op.get_shape().as_list()[-1]]
#         if len(op.get_shape().as_list()) == len(inp_shape) else []) for op in ops_list]
# 
#     out_dummy_counter = [np.zeros_like(o) for o in out_dummies]
# 
#     op_shape = list(ops_list[0].get_shape().as_list())
#     op_bshape = op_shape[1:-1]
# 
#     out_diff = np.array(pl_bshape) - np.array(op_bshape)
# 
#     padding = [[0, 0]] + [[diff // 2, diff - diff // 2] for diff
#                           in out_diff] + [[0, 0]]
# 
#     padded_dict = {k: np.pad(v, padding, mode='constant') for k, v
#                    in sample_dict.items()}
# 
#     f_bshape = list(padded_dict.values())[0].shape[1:-1]
# 
#     if not striding:
#         striding = (list(np.maximum(1, np.array(op_bshape) // 2))
#                     if all(out_diff == 0) else op_bshape)
# 
#     sw = SlidingWindow(f_bshape, pl_bshape, striding=striding)
#     out_sw = SlidingWindow(inp_bshape, op_bshape, striding=striding)
# 
#     if batch_size > 1:
#         slicers = []
#         out_slicers = []
# 
#     done = False
#     while True:
#         try:
#             slicer = next(sw)
#             out_slicer = next(out_sw)
#         except StopIteration:
#             done = True
# 
#         if batch_size == 1:
#             sw_dict = {k: v[slicer] for k, v in padded_dict.items()}
#             op_parts = session.run(ops_list, feed_dict=sw_dict)
# 
#             for idx in range(len(op_parts)):
#                 out_dummies[idx][out_slicer] += op_parts[idx]
#                 out_dummy_counter[idx][out_slicer] += 1
#         else:
#             slicers.append(slicer)
#             out_slicers.append(out_slicer)
#             if len(slicers) == batch_size or done:
#                 slices_dict = {k: np.concatenate(
#                     [v[slicer] for slicer in slicers], 0) for k, v in padded_dict.items()}
# 
#                 all_op_parts = session.run(ops_list, feed_dict=slices_dict)
# 
#                 zipped_parts = zip(*[np.array_split(part, len(slicers)) for
#                                      part in all_op_parts])
# 
#                 for out_slicer, op_parts in zip(out_slicers, zipped_parts):
#                     for idx in range(len(op_parts)):
#                         out_dummies[idx][out_slicer] += op_parts[idx]
#                         out_dummy_counter[idx][out_slicer] += 1
# 
#                 slicers = []
#                 out_slicers = []
# 
#         if done:
#             break
# 
#     return [o / c for o, c in zip(out_dummies, out_dummy_counter)]


import tensorflow as tf
import numpy as np
from dltk.utils import sliding_window_segmentation_inference


def test_sw_inference():

    inp = tf.placeholder(tf.float32, [1, 1, 2, 1])
    op = tf.ones([1, 1, 2, 1], tf.float32)
    np_inp = np.ones([1, 4, 4, 1])

    with tf.Session() as s:

# Path: dltk/utils.py
# def sliding_window_segmentation_inference(session,
#                                           ops_list,
#                                           sample_dict,
#                                           batch_size=1,
#                                           striding=None):
#     """
#     Utility function to perform sliding window inference for segmentation
# 
#     Args:
#         session (tf.Session): TensorFlow session to run ops with
# 
#         ops_list (array_like): Operators to fetch assemble with sliding window
# 
#         sample_dict (dict): Dictionary with tf.Placeholder keys mapping the
#         placeholders to their respective input
# 
#         batch_size (int, optional): Number of sliding windows to batch for
#             calculation
# 
#         striding (array_like): Striding of the sliding window. Can be used to
#             adjust overlap etc.
# 
#     Returns:
#         list: List of np.arrays corresponding to the assembled outputs of
#             ops_list
#     """
# 
#     # TODO: asserts
#     assert batch_size > 0, 'Batch size has to be 1 or bigger'
# 
#     pl_shape = list(sample_dict.keys())[0].get_shape().as_list()
# 
#     pl_bshape = pl_shape[1:-1]
# 
#     inp_shape = list(list(sample_dict.values())[0].shape)
#     inp_bshape = inp_shape[1:-1]
# 
#     out_dummies = [np.zeros(
#         [inp_shape[0], ] + inp_bshape + [op.get_shape().as_list()[-1]]
#         if len(op.get_shape().as_list()) == len(inp_shape) else []) for op in ops_list]
# 
#     out_dummy_counter = [np.zeros_like(o) for o in out_dummies]
# 
#     op_shape = list(ops_list[0].get_shape().as_list())
#     op_bshape = op_shape[1:-1]
# 
#     out_diff = np.array(pl_bshape) - np.array(op_bshape)
# 
#     padding = [[0, 0]] + [[diff // 2, diff - diff // 2] for diff
#                           in out_diff] + [[0, 0]]
# 
#     padded_dict = {k: np.pad(v, padding, mode='constant') for k, v
#                    in sample_dict.items()}
# 
#     f_bshape = list(padded_dict.values())[0].shape[1:-1]
# 
#     if not striding:
#         striding = (list(np.maximum(1, np.array(op_bshape) // 2))
#                     if all(out_diff == 0) else op_bshape)
# 
#     sw = SlidingWindow(f_bshape, pl_bshape, striding=striding)
#     out_sw = SlidingWindow(inp_bshape, op_bshape, striding=striding)
# 
#     if batch_size > 1:
#         slicers = []
#         out_slicers = []
# 
#     done = False
#     while True:
#         try:
#             slicer = next(sw)
#             out_slicer = next(out_sw)
#         except StopIteration:
#             done = True
# 
#         if batch_size == 1:
#             sw_dict = {k: v[slicer] for k, v in padded_dict.items()}
#             op_parts = session.run(ops_list, feed_dict=sw_dict)
# 
#             for idx in range(len(op_parts)):
#                 out_dummies[idx][out_slicer] += op_parts[idx]
#                 out_dummy_counter[idx][out_slicer] += 1
#         else:
#             slicers.append(slicer)
#             out_slicers.append(out_slicer)
#             if len(slicers) == batch_size or done:
#                 slices_dict = {k: np.concatenate(
#                     [v[slicer] for slicer in slicers], 0) for k, v in padded_dict.items()}
# 
#                 all_op_parts = session.run(ops_list, feed_dict=slices_dict)
# 
#                 zipped_parts = zip(*[np.array_split(part, len(slicers)) for
#                                      part in all_op_parts])
# 
#                 for out_slicer, op_parts in zip(out_slicers, zipped_parts):
#                     for idx in range(len(op_parts)):
#                         out_dummies[idx][out_slicer] += op_parts[idx]
#                         out_dummy_counter[idx][out_slicer] += 1
# 
#                 slicers = []
#                 out_slicers = []
# 
#         if done:
#             break
# 
#     return [o / c for o, c in zip(out_dummies, out_dummy_counter)]


# Path: tests/test_sliding_window_segmentation.py
import tensorflow as tf
import numpy as np
from dltk.utils import sliding_window_segmentation_inference



def test_sw_inference():

    inp = tf.placeholder(tf.float32, [1, 1, 2, 1])
    op = tf.ones([1, 1, 2, 1], tf.float32)
    np_inp = np.ones([1, 4, 4, 1])

    with tf.Session() as s:

        out = sliding_window_segmentation_inference(s, [op], {inp: np_inp})[0]