text:
from __future__ import division
from __future__ import print_function
import datetime
import numpy as np
import pandas as pd
import os
import keras
from keras.models import Model as KerasModel
from keras.layers import Dense, Dropout, Flatten, ELU, ReLU, Input, Conv1D
from keras.layers import BatchNormalization, MaxPooling1D, Concatenate
from keras.layers import Cropping1D, AveragePooling1D, Cropping1D
from keras.layers.core import Activation, Reshape
from keras import optimizers
from .util import hour, minute
from .base_model import hybrid_pool_layer_2, Normalizer
from .single_track_model import SingleTrackModel
from . import util
from .util import minute, lin_interp, cos_deg, sin_deg

from keras.engine import Layer, InputSpec
from keras import initializers
from keras import regularizers
from keras import constraints
from keras import backend as K

from keras.utils.generic_utils import get_custom_objects

class GroupNormalization(Layer):
    """Group normalization layer
    Group Normalization divides the channels into groups and computes within each group
    the mean and variance for normalization. GN's computation is independent of batch sizes,
    and its accuracy is stable in a wide range of batch sizes
    # Arguments
        groups: Integer, the number of groups for Group Normalization.
        axis: Integer, the axis that should be normalized
            (typically the features axis).
            For instance, after a `Conv2D` layer with
            `data_format="channels_first"`,
            set `axis=1` in `BatchNormalization`.
        epsilon: Small float added to variance to avoid dividing by zero.
        center: If True, add offset of `beta` to normalized tensor.
            If False, `beta` is ignored.
        scale: If True, multiply by `gamma`.
            If False, `gamma` is not used.
            When the next layer is linear (also e.g. `nn.relu`),
            this can be disabled since the scaling
            will be done by the next layer.
        beta_initializer: Initializer for the beta weight.
        gamma_initializer: Initializer for the gamma weight.
        beta_regularizer: Optional regularizer for the beta weight.
        gamma_regularizer: Optional regularizer for the gamma weight.
        beta_constraint: Optional constraint for the beta weight.
        gamma_constraint: Optional constraint for the gamma weight.
    # Input shape
        Arbitrary. Use the keyword argument `input_shape`
        (tuple of integers, does not include the samples axis)
        when using this layer as the first layer in a model.
    # Output shape
        Same shape as input.
    # References
        - [Group Normalization](https://arxiv.org/abs/1803.08494)
    """

    def __init__(self,
                 groups=32,
                 axis=-1,
                 epsilon=1e-5,
                 center=True,
                 scale=True,
                 beta_initializer='zeros',
                 gamma_initializer='ones',
                 beta_regularizer=None,
                 gamma_regularizer=None,
                 beta_constraint=None,
                 gamma_constraint=None,
                 **kwargs):
        super(GroupNormalization, self).__init__(**kwargs)
        self.supports_masking = True
        self.groups = groups
        self.axis = axis
        self.epsilon = epsilon
        self.center = center
        self.scale = scale
        self.beta_initializer = initializers.get(beta_initializer)
        self.gamma_initializer = initializers.get(gamma_initializer)
        self.beta_regularizer = regularizers.get(beta_regularizer)
        self.gamma_regularizer = regularizers.get(gamma_regularizer)
        self.beta_constraint = constraints.get(beta_constraint)
        self.gamma_constraint = constraints.get(gamma_constraint)

    def build(self, input_shape):
        dim = input_shape[self.axis]

        if dim is None:
            raise ValueError('Axis ' + str(self.axis) + ' of '
                             'input tensor should have a defined dimension '
                             'but the layer received an input with shape ' +
                             str(input_shape) + '.')

        if dim < self.groups:
            raise ValueError('Number of groups (' + str(self.groups) + ') cannot be '
                             'more than the number of channels (' +
                             str(dim) + ').')

        if dim % self.groups != 0:
            raise ValueError('Number of groups (' + str(self.groups) + ') must be a '
                             'multiple of the number of channels (' +
                             str(dim) + ').')

        self.input_spec = InputSpec(ndim=len(input_shape),
                                    axes={self.axis: dim})
        shape = (dim,)

        if self.scale:
            self.gamma = self.add_weight(shape=shape,
                                         name='gamma',
                                         initializer=self.gamma_initializer,
                                         regularizer=self.gamma_regularizer,
                                         constraint=self.gamma_constraint)
        else:
            self.gamma = None
        if self.center:
            self.beta = self.add_weight(shape=shape,
                                        name='beta',
                                        initializer=self.beta_initializer,
                                        regularizer=self.beta_regularizer,
                                        constraint=self.beta_constraint)
        else:
            self.beta = None
        self.built = True

    def call(self, inputs, **kwargs):
        input_shape = K.int_shape(inputs)
        tensor_input_shape = K.shape(inputs)

        # Prepare broadcasting shape.
        reduction_axes = list(range(len(input_shape)))
        del reduction_axes[self.axis]
        broadcast_shape = [1] * len(input_shape)
        broadcast_shape[self.axis] = input_shape[self.axis] // self.groups
        broadcast_shape.insert(1, self.groups)

        reshape_group_shape = K.shape(inputs)
        group_axes = [reshape_group_shape[i] for i in range(len(input_shape))]
        group_axes[self.axis] = input_shape[self.axis] // self.groups
        group_axes.insert(1, self.groups)

        # reshape inputs to new group shape
        group_shape = [group_axes[0], self.groups] + group_axes[2:]
        group_shape = K.stack(group_shape)
        inputs = K.reshape(inputs, group_shape)

        group_reduction_axes = list(range(len(group_axes)))
        group_reduction_axes = group_reduction_axes[2:]

        mean = K.mean(inputs, axis=group_reduction_axes, keepdims=True)
        variance = K.var(inputs, axis=group_reduction_axes, keepdims=True)

        inputs = (inputs - mean) / (K.sqrt(variance + self.epsilon))

        # prepare broadcast shape
        inputs = K.reshape(inputs, group_shape)
        outputs = inputs

        # In this case we must explicitly broadcast all parameters.
        if self.scale:
            broadcast_gamma = K.reshape(self.gamma, broadcast_shape)
            outputs = outputs * broadcast_gamma

        if self.center:
            broadcast_beta = K.reshape(self.beta, broadcast_shape)
            outputs = outputs + broadcast_beta

        outputs = K.reshape(outputs, tensor_input_shape)

        return outputs

    def get_config(self):
        config = {
            'groups': self.groups,
            'axis': self.axis,
            'epsilon': self.epsilon,
            'center': self.center,
            'scale': self.scale,
            'beta_initializer': initializers.serialize(self.beta_initializer),
            'gamma_initializer': initializers.serialize(self.gamma_initializer),
            'beta_regularizer': regularizers.serialize(self.beta_regularizer),
            'gamma_regularizer': regularizers.serialize(self.gamma_regularizer),
            'beta_constraint': constraints.serialize(self.beta_constraint),
            'gamma_constraint': constraints.serialize(self.gamma_constraint)
        }
        base_config = super(GroupNormalization, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

    def compute_output_shape(self, input_shape):
        return input_shape

get_custom_objects().update({'GroupNormalization': GroupNormalization})

class LoiteringModelV1(SingleTrackModel):

    delta = 10 * minute
    window = 12 * hour + delta
    time_points = window // delta

    base_filter_count = 64
    fc_nodes = 512

    data_source_lbl='transshipping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        depth = self.base_filter_count

        input_layer = Input(shape=(self.time_points, 6))
        y = input_layer
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        y = Flatten()(y)

        y = Dense(self.fc_nodes)(y)
        y = ELU()(y)

        y = Dense(1)(y)
        y = Activation('sigmoid')(y)
        output_layer = y
        model = KerasModel(inputs=input_layer, outputs=output_layer)
        opt = optimizers.Nadam(lr=0.0005, schedule_decay=0.01)
        #opt = optimizers.Adam(lr=0.01, decay=0.5)
        model.compile(optimizer=opt, loss='binary_crossentropy', metrics=["accuracy"])
        self.model = model

class LoiteringModelV1m(SingleTrackModel):

    delta = 10 * minute
    window = 12 * hour + delta
    time_points = window // delta
    time_point_delta = 8

    delta = 10 * minute
    window = 12 * hour + delta
    time_points = window // delta
    time_point_delta = 8

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        depth = 2 * depth
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        depth = 2 * depth
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        depth = 256
        y = Conv1D(depth, 1)(y)
        y = ELU()(y)

        y = Reshape((-1, depth // 8))(y)

        y = Conv1D(1, 8)(y)

        y = Activation('sigmoid')(y)
        output_layer = y
        model = KerasModel(inputs=input_layer, outputs=output_layer)
        opt = optimizers.Nadam(lr=0.0005, schedule_decay=0.01)
        #opt = optimizers.Adam(lr=0.01, decay=0.5)
        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data)
        return self

class LoiteringModelV2(SingleTrackModel):

    delta = 10 * minute
    window = 12 * hour + delta
    time_points = window // delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 7)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = hybrid_pool_layer_2(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 1)(y)
        y = ELU()(y)
        y = Conv1D(depth, 1)(y)
        y = ELU()(y)

        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        # 1 -> (3 -> 11) -> (23 -> 31) -> (63, 77) -> 73
        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.0005, schedule_decay=0.01)
        model.compile(optimizer=opt, loss='binary_crossentropy', metrics=["accuracy"])
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape((len(labels), 1, 1))
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data)
        return self

class LoiteringModelV3(SingleTrackModel):

    delta = 10 * minute
    time_points = 93 # 72 = 12 hours, 120 = 20 hours, should be odd
    window = time_points * delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(self.time_points, 6))
        y = input_layer
        y = Conv1D(depth, 4)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o1 = y
        y = MaxPooling1D(2)(y)

        d2 = depth = 3 * depth // 2
        y = Conv1D(depth, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o2 = y
        y = MaxPooling1D(2)(y)

        d3 = depth = 3 * depth // 2
        y = Conv1D(depth, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o3 = y
        y = MaxPooling1D(2)(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (4 -> 8) -> (16 -> 20) -> (40 -> 44) -> (88, 93)

        # Upward branch

        y = keras.layers.UpSampling1D(2)(y) # 7.5 / 8
        y = keras.layers.Concatenate()([y,
                            keras.layers.Cropping1D((4,4))(o3)])
        y = Conv1D(d3, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d3, 3)(y)
        y = ELU()(y) # 3.5 / 4
        y = BatchNormalization(scale=False, center=False)(y)

        y = keras.layers.UpSampling1D(2)(y) # 7 / 8
        y = keras.layers.Concatenate()([y,
                            keras.layers.Cropping1D((16,16))(o2)])
        y = Conv1D(d2, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d2, 3)(y)
        y = ELU()(y) # 3 / 4
        y = BatchNormalization(scale=False, center=False)(y)

        y = keras.layers.UpSampling1D(2)(y) # 6 / 8
        y = keras.layers.Concatenate()([y,
                            keras.layers.Cropping1D((40,40))(o1)])
        y = Conv1D(d1, 3)(y)
        y = ELU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d1, 3)(y)
        y = ELU()(y) # 2 / 4

        y = Conv1D(1, 4)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.0005, schedule_decay=0.01)
        model.compile(optimizer=opt, loss='binary_crossentropy', metrics=["accuracy"])
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape((len(labels), 1, 1))
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data)
        return self

import keras.backend as K
from keras.layers import Conv2DTranspose, Lambda

def Conv1DTranspose(input_tensor, filters, kernel_size, strides=2, padding='same'):
    x = Lambda(lambda x: K.expand_dims(x, axis=2))(input_tensor)
    x = Conv2DTranspose(filters=filters, kernel_size=(kernel_size, 1), strides=(strides, 1), padding=padding)(x)
    x = Lambda(lambda x: K.squeeze(x, axis=2))(x)
    return x

class LoiteringModelV4(SingleTrackModel):

    delta = 10 * minute
    time_points = 73 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 8
    window = time_points * delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 6)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o1 = y
        y = MaxPooling1D(2)(y)

        d2 = depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o2 = y
        y = MaxPooling1D(2)(y)

        d3 = depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (4 -> 12) -> (24 -> 32) -> (64 -> 73)

        # Upward branch

        y = Conv1DTranspose(y, d2, 2, strides=2, padding='same') # 7 / 8
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((8,8))(o2)])
        y = Conv1D(d2, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d2, 3)(y)
        y = ReLU()(y) # 3 / 4
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1DTranspose(y, d1, 2, strides=2, padding='same') # 6 / 8
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((28,28))(o1)])
        y = Conv1D(d1, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d1, 3)(y)
        y = ReLU()(y) # 2 / 4
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(d1, 4)(y)
        y = ReLU()(y)
        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        print(np.shape(x1), np.shape(labels))
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data)

class LoiteringModelV4s(SingleTrackModel):

    delta = 10 * minute
    time_points = 93 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 8
    window = time_points * delta

    base_filter_count = 16

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 6)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o1 = y
        y = MaxPooling1D(2)(y)

        d2 = depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o2 = y
        y = MaxPooling1D(2)(y)

        d3 = depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o3 = y
        y = MaxPooling1D(2)(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (4 -> 8) -> (16 -> 20) -> (40 -> 44) -> (88, 93)

        # Upward branch

        y = Conv1DTranspose(y, d3, 2, strides=2, padding='same') # 7.5 / 8
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = keras.layers.Concatenate()([y,  keras.layers.Cropping1D((4,4))(o3)])
        y = Conv1D(d3, 5)(y)
        y = ReLU()(y)

        y = Conv1DTranspose(y, d2, 2, strides=2, padding='same') # 7 / 8
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((16,16))(o2)])
        y = Conv1D(d2, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1DTranspose(y, d1, 2, strides=2, padding='same') # 6 / 8
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((40,40))(o1)])
        y = Conv1D(d1, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(1, 4)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0,
            validation_data=0, verbose=1):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        print(np.shape(x1), np.shape(labels))
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose)

class LoiteringModelV4sb(SingleTrackModel):

    delta = 10 * minute
    time_points = 93 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 8
    window = time_points * delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 6)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o1 = y
        y = MaxPooling1D(2)(y)

        d2 = depth = 2 * depth
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o2 = y
        y = MaxPooling1D(2)(y)

        d3 = depth = 2 * depth
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o3 = y
        y = MaxPooling1D(2)(y)

        depth = 2 * depth
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (4 -> 8) -> (16 -> 20) -> (40 -> 44) -> (88, 93)

        # Upward branch

        y = Conv1DTranspose(y, d3, 2, strides=2, padding='same') # 7.5 / 8
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = keras.layers.Concatenate()([y,  keras.layers.Cropping1D((4,4))(o3)])
        y = Conv1D(d3, 5)(y)
        y = ReLU()(y)

        y = Conv1DTranspose(y, d2, 2, strides=2, padding='same') # 7 / 8
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((16,16))(o2)])
        y = Conv1D(d2, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1DTranspose(y, d1, 2, strides=2, padding='same') # 6 / 8
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((40,40))(o1)])
        y = Conv1D(d1, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(1, 4)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        print(np.shape(x1), np.shape(labels))
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data)

class LoiteringModelV5(SingleTrackModel):

    delta = 10 * minute
    time_points = 101 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 8
    window = time_points * delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o1 = y
        y = MaxPooling1D(2)(y)

        d2 = depth = 3 * depth // 2
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o2 = y
        y = MaxPooling1D(2)(y)

        d3 = depth = 3 * depth // 2
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        o3 = y
        y = MaxPooling1D(2)(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (5 -> 9) -> (18 -> 22) -> (44 -> 48) -> (96, 101)

        # Upward branch

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y,  keras.layers.Cropping1D((4,4))(o3)])
        y = Conv1D(d3, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d3, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d3, 3)(y)
        y = ReLU()(y) # 3.5 / 4
        y = BatchNormalization(scale=False, center=False)(y) # 5

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((17,17))(o2)])
        y = Conv1D(d3, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d2, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d2, 3)(y)
        y = ReLU()(y) # 3 / 4
        y = BatchNormalization(scale=False, center=False)(y) # 5

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((43,43))(o1)])
        y = Conv1D(d3, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d1, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(d1, 3)(y)
        y = ReLU()(y) # 2 / 4
        y = BatchNormalization(scale=False, center=False)(y) # 5

        y = Conv1D(1, 5)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data)
        return self

class LoiteringModelV6(SingleTrackModel):

    delta = 10 * minute
    time_points = 101 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 8
    window = time_points * delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        input_layer = Input(shape=(None, 6))

        d1 = depth = self.base_filter_count
        y = input_layer
        y = Conv1D(depth, 4, activation='relu')(y)
        y = Conv1D(depth, 3, activation='relu')(y)
        o1 = y
        y = MaxPooling1D(2)(y)

        d2 = depth = 3 * depth // 2
        y = Conv1D(depth, 3, activation='relu')(y)
        y = Conv1D(depth, 3, activation='relu')(y)
        y = o2 = Dropout(0.1)(y)
        y = MaxPooling1D(2)(y)

        d3 = depth = 3 * depth // 2
        y = Conv1D(depth, 3, activation='relu')(y)
        y = Conv1D(depth, 3, activation='relu')(y)
        y = o3 = Dropout(0.2)(y)
        y = MaxPooling1D(2)(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 3, activation='relu')(y)
        y = Conv1D(depth, 3, activation='relu')(y)
        y = Dropout(0.3)(y)

        # (5 -> 9) -> (18 -> 22) -> (44 -> 48) -> (96, 101)

        # Upward branch

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y,  keras.layers.Cropping1D((4,4))(o3)])
        y = Conv1D(d3, 2, activation='relu')(y)
        y = Conv1D(d3, 3, activation='relu')(y)
        y = Conv1D(d3, 3, activation='relu')(y)

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((17,17))(o2)])
        y = Conv1D(d3, 2, activation='relu')(y)
        y = Conv1D(d2, 3, activation='relu')(y)
        y = Conv1D(d2, 3, activation='relu')(y)

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((43,43))(o1)])
        y = Conv1D(d3, 2, activation='relu')(y)
        y = Conv1D(d1, 3, activation='relu')(y)
        y = Conv1D(d1, 3, activation='relu')(y)

        y = Conv1D(1, 5)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05,
                               clipnorm=1.)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data)
        return self

class LoiteringModelV7(SingleTrackModel):

    delta = 10 * minute
    time_points = 101 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 8
    window = time_points * delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        input_layer = Input(shape=(None, 6))

        d1 = depth = self.base_filter_count
        y = input_layer
        y = Conv1D(depth, 4, activation='relu')(y)
        y = Conv1D(depth, 3, activation='relu')(y)
        o1 = Dropout(0.1)(y)
        y = MaxPooling1D(2)(y)

        d2 = 3 * depth // 2
        y = Conv1D(depth, 3, activation='relu')(y)
        y = Conv1D(depth, 3, activation='relu')(y)
        o2 = Dropout(0.2)(y)
        y = MaxPooling1D(2)(y)

        d3 = 3 * depth // 2
        y = Conv1D(depth, 3, activation='relu')(y)
        y = Conv1D(depth, 3, activation='relu')(y)
        o3 = Dropout(0.3)(y)
        y = MaxPooling1D(2)(y)

        depth = 3 * depth // 2
        y = Conv1D(depth, 3, activation='relu')(y)
        y = Conv1D(depth, 3, activation='relu')(y)
        y = Dropout(0.4)(y)

        # (5 -> 9) -> (18 -> 22) -> (44 -> 48) -> (96, 101)

        # Upward branch

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y,  keras.layers.Cropping1D((4,4))(o3)])
        y = Conv1D(d3, 2, activation='relu')(y)
        y = Conv1D(d3, 3, activation='relu')(y)
        y = Conv1D(d3, 3, activation='relu')(y)

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((17,17))(o2)])
        y = Conv1D(d3, 2, activation='relu')(y)
        y = Conv1D(d2, 3, activation='relu')(y)
        y = Conv1D(d2, 3, activation='relu')(y)

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((43,43))(o1)])
        y = Conv1D(d3, 2, activation='relu')(y)
        y = Conv1D(d1, 3, activation='relu')(y)
        y = Conv1D(d1, 3, activation='relu')(y)

        y = Conv1D(1, 5)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.1,
                               clipnorm=0.1)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data)
        return self

class LoiteringModelV8(SingleTrackModel):

    delta = 10 * minute
    time_points = 65 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 1
    window = time_points * delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(depth, 3, dilation_rate=2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(depth, 3, dilation_rate=4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(depth, 3, dilation_rate=8)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=8)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (1 - 5) (5 37) (37 53) (53 61) (61 65)

        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1, callbacks=[]):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose, callbacks=callbacks)

class LoiteringModelV8_128(LoiteringModelV8):
	base_filter_count = 128

class LoiteringModelV8Shallow(SingleTrackModel):

    delta = 10 * minute
    time_points = 17 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 1
    window = time_points * delta

    base_filter_count = 16

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(depth, 3, dilation_rate=2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (1 - 5) (5 13) (13 17)

        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1, callbacks=[]):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose, callbacks=callbacks)

class LoiteringModelV8Max(SingleTrackModel):

    delta = 10 * minute
    time_points = 21 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 1
    window = time_points * delta

    base_filter_count = 16

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y0 = Cropping1D((2, 2))(y)
        y1 = MaxPooling1D(5, strides=1)(y)
        y = Concatenate()([y0, y1])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y0 = Cropping1D((2, 2))(y)
        y1 = MaxPooling1D(5, strides=1)(y)
        y = Concatenate()([y0, y1])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (1 - 5) (5 9) (9 13) (13 17) (13 21)

        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1, callbacks=[]):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose, callbacks=callbacks)

class LoiteringModelV8Avg(SingleTrackModel):

    delta = 10 * minute
    time_points = 21 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 1
    window = time_points * delta

    base_filter_count = 16

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y0 = Cropping1D((2, 2))(y)
        y1 = AveragePooling1D(5, strides=1)(y)
        y = Concatenate()([y0, y1])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y0 = Cropping1D((2, 2))(y)
        y1 = AveragePooling1D(5, strides=1)(y)
        y = Concatenate()([y0, y1])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (1 - 5) (5 9) (9 13) (13 17) (13 21)

        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1, callbacks=[]):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose, callbacks=callbacks)

class LoiteringModelV9(SingleTrackModel):

    delta = 10 * minute
    time_points = 65 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 1
    window = time_points * delta

    base_filter_count = 64

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y1 = Conv1D(depth, 3)(y)
        y1 = ReLU()(y1)
        y1 = BatchNormalization(scale=False, center=False)(y1)
        y2 = MaxPooling1D(3, strides=1)(y)
        y = Concatenate()([y1, y2])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y1 = Conv1D(depth, 3, dilation_rate=2)(y)
        y1 = ReLU()(y1)
        y1 = BatchNormalization(scale=False, center=False)(y1)
        y2 = MaxPooling1D(5, strides=1)(y)
        y = Concatenate()([y1, y2])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y1 = Conv1D(depth, 3, dilation_rate=4)(y)
        y1 = ReLU()(y1)
        y1 = BatchNormalization(scale=False, center=False)(y1)
        y2 = MaxPooling1D(9, strides=1)(y)
        y = Concatenate()([y1, y2])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=8)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y1 = Conv1D(depth, 3, dilation_rate=8)(y)
        y1 = ReLU()(y1)
        y1 = BatchNormalization(scale=False, center=False)(y1)
        y2 = MaxPooling1D(17, strides=1)(y)
        y = Concatenate()([y1, y2])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (1 - 5) (5 37) (37 53) (53 61) (61 65)

        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose)

class LoiteringModelV10(SingleTrackModel):

    delta = 10 * minute
    time_points = 65 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 1
    window = time_points * delta

    base_filter_count = 32

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y1 = Conv1D(depth // 2, 3)(y)
        y1 = ReLU()(y1)
        y1 = BatchNormalization(scale=False, center=False)(y1)
        y2 = Conv1D(depth // 2, 1)(y)
        y2 = MaxPooling1D(3, strides=1)(y2)
        y = Concatenate()([y1, y2])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y1 = Conv1D(depth // 2, 3, dilation_rate=2)(y)
        y1 = ReLU()(y1)
        y1 = BatchNormalization(scale=False, center=False)(y1)
        y2 = Conv1D(depth // 2, 1)(y)
        y2 = MaxPooling1D(5, strides=1)(y2)
        y = Concatenate()([y1, y2])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y1 = Conv1D(depth // 2, 3, dilation_rate=4)(y)
        y1 = ReLU()(y1)
        y1 = BatchNormalization(scale=False, center=False)(y1)
        y2 = Conv1D(depth // 2, 1)(y)
        y2 = MaxPooling1D(9, strides=1)(y2)
        y = Concatenate()([y1, y2])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=8)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y1 = Conv1D(depth // 2, 3, dilation_rate=8)(y)
        y1 = ReLU()(y1)
        y1 = BatchNormalization(scale=False, center=False)(y1)
        y2 = Conv1D(depth // 2, 1)(y)
        y2 = MaxPooling1D(17, strides=1)(y2)
        y = Concatenate()([y1, y2])
        y = Conv1D(depth, 1)(y)

        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3, dilation_rate=1)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        # (1 - 5) (5 37) (37 53) (53 61) (61 65)

        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
        validation_split=0, validation_data=0, verbose=1):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose)

class LoiteringModelV11(SingleTrackModel):

    delta = 10 * minute
    time_points = 101 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 8
    window = time_points * delta

    base_filter_count = 60

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        groups = g1 = self.base_filter_count // 16
        d1 = depth = 16 * groups

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 4)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=groups, scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=groups, scale=False, center=False)(y)
        o1 = y
        y = MaxPooling1D(2)(y)

        groups = g2 = 3 * groups // 2
        d2 = depth = 16 * groups
        groups = g1 = depth // 16
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=groups, scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=groups, scale=False, center=False)(y)
        o2 = Dropout(0.1)(y)
        y = MaxPooling1D(2)(y)

        groups = g3 = 3 * groups // 2
        d3 = depth = 16 * groups
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=groups, scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=groups, scale=False, center=False)(y)
        o3 = Dropout(0.2)(y)
        y = MaxPooling1D(2)(y)

        groups = g4 = 3 * groups // 2
        d4 = depth = 16 * groups
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=groups, scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=groups, scale=False, center=False)(y)
        y = Dropout(0.3)(y)

        # (5 -> 9) -> (18 -> 22) -> (44 -> 48) -> (96, 101)

        # Upward branch

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y,  keras.layers.Cropping1D((4,4))(o3)])
        y = Conv1D(d3, 2)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=g1, scale=False, center=False)(y)
        y = Conv1D(d3, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=g1, scale=False, center=False)(y)
        y = Conv1D(d3, 3)(y)
        y = ReLU()(y) # 3.5 / 4
        y = GroupNormalization(groups=g1, scale=False, center=False)(y)

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((17,17))(o2)])
        y = Conv1D(d3, 2)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=g2, scale=False, center=False)(y)
        y = Conv1D(d2, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=g2, scale=False, center=False)(y)
        y = Conv1D(d2, 3)(y)
        y = ReLU()(y) # 3 / 4
        y = GroupNormalization(groups=g2, scale=False, center=False)(y)

        y = keras.layers.UpSampling1D(2)(y) # 10
        y = keras.layers.Concatenate()([y, keras.layers.Cropping1D((43,43))(o1)])
        y = Conv1D(d3, 2)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=g3, scale=False, center=False)(y)
        y = Conv1D(d1, 3)(y)
        y = ReLU()(y)
        y = GroupNormalization(groups=g3, scale=False, center=False)(y)
        y = Conv1D(d1, 3)(y)
        y = ReLU()(y) # 2 / 4

        y = Conv1D(1, 5)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.05)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None, validation_split=0, validation_data=0,
            verbose=1):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose)

class LoiteringModelV12(SingleTrackModel):

    delta = 10 * minute
    time_points = 105 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 4
    window = time_points * delta

    base_filter_count = 16

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y0 = y = Dropout(0.2)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = MaxPooling1D(5, strides=4)(y)
        y1 = y = Dropout(0.3)(y)

        depth *= 2
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = MaxPooling1D(5, strides=4)(y)
        y = Dropout(0.4)(y)

        depth *= 2
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Dropout(0.4)(y)

        # Above is 1->5->21->25->101->105
        # Below is 4 * k - 3, where k is center size

        depth //= 2
        y = keras.layers.UpSampling1D(size=4)(y)
        y = Concatenate()([y,
                            keras.layers.Cropping1D((10,11))(y1)])
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        depth //= 2
        y = keras.layers.UpSampling1D(size=4)(y)
        y = keras.layers.Concatenate()([y,
                            Cropping1D((49,50))(y0)]) # TODO make symmetric
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.1)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1, callbacks=[]):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose, callbacks=callbacks)

class LoiteringModelV13(SingleTrackModel):

    delta = 10 * minute
    time_points = 105 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 4
    window = time_points * delta

    base_filter_count = 8

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y0 = y = Dropout(0.1)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = MaxPooling1D(5, strides=4)(y)
        y1 = y = Dropout(0.3)(y)

        depth *= 2
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Dropout(0.3)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = MaxPooling1D(5, strides=4)(y)
        y = Dropout(0.5)(y)

        depth *= 2
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Dropout(0.5)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Dropout(0.5)(y)

        # Above is 1->5->21->25->101->(103)-> 105
        # Below is 4 * k - 3, where k is center size

        depth //= 2
        y = keras.layers.UpSampling1D(size=4)(y)
        y = Dropout(0.3)(y)
        y = Concatenate()([y,
                            keras.layers.Cropping1D((10,11))(y1)])
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Dropout(0.3)(y)
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)

        depth //= 2
        y = keras.layers.UpSampling1D(size=4)(y)
        y = Dropout(0.1)(y)
        y = keras.layers.Concatenate()([y,
                            Cropping1D((49,50))(y0)]) # TODO make symmetric
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Dropout(0.1)(y)
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False)(y)
        y = Dropout(0.1)(y)
        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.1)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1, callbacks=[]):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose, callbacks=callbacks)

class LoiteringModelV14(SingleTrackModel):

    delta = 10 * minute
    time_points = 81 # 72 = 12 hours, 120 = 20 hours, should be odd
    time_point_delta = 4
    window = time_points * delta

    base_filter_count = 32

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 6))
        y = input_layer
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y0 = y = Dropout(0.1)(y)
        y = Conv1D(depth, 4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = MaxPooling1D(4, strides=3)(y)
        y = Dropout(0.3)(y)

        depth *= 2
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y1 = y = Dropout(0.3)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = MaxPooling1D(4, strides=3)(y)
        y = Dropout(0.5)(y)

        depth *= 2
        y = Conv1D(depth, 4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.5)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.5)(y)

        # Above is 1->6->19->(21)->25->76->(79)->81
        # Below is 4 * k - 3, where k is center size
        # Above is 1->5->(21)->25->101->[(103)]-> 105

        depth //= 2
        y = keras.layers.UpSampling1D(size=3)(y)
        y = Dropout(0.3)(y)
        y = Concatenate()([y,
                            keras.layers.Cropping1D((9,9))(y1)])
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.3)(y)
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)

        depth //= 2
        y = keras.layers.UpSampling1D(size=3)(y)
        y = Dropout(0.1)(y)
        y = keras.layers.Concatenate()([y,
                            Cropping1D((38,38))(y0)]) # TODO make symmetric
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.1)(y)
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.1)(y)
        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.1)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def preprocess(self, x):
        x = np.asarray(x)
        return self.normalizer.norm(x)

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1, callbacks=[]):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose, callbacks=callbacks)

class LoiteringModelV15(SingleTrackModel):

    delta = 10 * minute
    time_points = 81 # 72 = 12 hours, 120 = 20 hours, should be odd
    internal_time_points = 80
    time_point_delta = 4
    window = time_points * delta

    base_filter_count = 32

    data_source_lbl='transshiping'
    data_target_lbl='is_target_encounter'
    data_undefined_vals = (0, 3)
    data_defined_vals = (1, 2)
    data_true_vals = (1,)
    data_false_vals = (2,)
    data_far_time = 3 * 10 * minute

    def __init__(self):

        self.normalizer = None

        d1 = depth = self.base_filter_count

        input_layer = Input(shape=(None, 7))
        y = input_layer
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y0 = y = Dropout(0.1)(y)
        y = Conv1D(depth, 4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = MaxPooling1D(4, strides=3)(y)
        y = Dropout(0.3)(y)

        depth *= 2
        y = Conv1D(depth, 5)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y1 = y = Dropout(0.3)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = MaxPooling1D(4, strides=3)(y)
        y = Dropout(0.5)(y)

        depth *= 2
        y = Conv1D(depth, 4)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.5)(y)
        y = Conv1D(depth, 3)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.5)(y)

        # Above is 1->6->19->(21)->25->76->(79)->80 (+1 for delta)
        # Below is 4 * k - 3, where k is center size
        # Above is 1->5->(21)->25->101->[(103)]-> 105

        depth //= 2
        y = keras.layers.UpSampling1D(size=3)(y)
        y = Dropout(0.3)(y)
        y = Concatenate()([y,
                            keras.layers.Cropping1D((9,9))(y1)])
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.3)(y)
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)

        depth //= 2
        y = keras.layers.UpSampling1D(size=3)(y)
        y = Dropout(0.1)(y)
        y = keras.layers.Concatenate()([y,
                            Cropping1D((38,38))(y0)]) # TODO make symmetric
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.1)(y)
        y = Conv1D(depth, 2)(y)
        y = ReLU()(y)
        y = BatchNormalization(scale=False, center=False, momentum=0.995)(y)
        y = Dropout(0.1)(y)
        y = Conv1D(1, 1)(y)
        y = Activation('sigmoid')(y)

        model = KerasModel(inputs=input_layer, outputs=y)
        opt = optimizers.Nadam(lr=0.002, schedule_decay=0.1)
        # opt = keras.optimizers.SGD(lr=0.00001, momentum=0.9,
        #                                 decay=0.5, nesterov=True)

        model.compile(optimizer=opt, loss='binary_crossentropy',
            metrics=["accuracy"], sample_weight_mode="temporal")
        self.model = model

    def preprocess(self, x):
        x0 = np.asarray(x)
        x = 0.5 * (x0[:, 1:, :] + x0[:, :-1, :])
        x[:, :, 3:5] = x0[:, 1:, 3:5] - x0[:, :-1, 3:5]
        return self.normalizer.norm(x)

    def fit(self, x, labels, epochs=1, batch_size=32, sample_weight=None,
            validation_split=0, validation_data=0, verbose=1, callbacks=[]):
        self.normalizer = Normalizer().fit(x)
        x1 = self.preprocess(x)
        l1 = np.asarray(labels).reshape(len(labels), -1, 1)
        if validation_data not in (None, 0):
            a, b, c = validation_data
            validation_data = self.preprocess(a), b, c
        return self.model.fit(x1, l1, epochs=epochs, batch_size=batch_size,
                        sample_weight=sample_weight,
                      validation_split=validation_split,
                      validation_data=validation_data,
                      verbose=verbose, callbacks=callbacks)

max_stars_repo_name: GlobalFishingWatch/track-based-models

max_issues_repo_name: GlobalFishingWatch/track-based-models

max_forks_repo_name: GlobalFishingWatch/track-based-models


text:
from core.node import *
import numpy as np
import logging

class Node_scalar(Node):

    def __init__(self, scene, title="Variável", parent=None, method=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.MODULO = 'Variável'
        self.MODULO_INITIALIZED = False
        self.scene = scene
        self.parent = parent
        self.method = method
        self.title = title
        self.content = QDMNodeScalar(self)
        self.grNode = QDMGraphicsNode(self)
        self.grNode.resize(240, 180)
        self.scene.addNode(self)
        self.scene.grScene.addItem(self.grNode)

        inputs = []
        outputs = [{'pos': 0.81, 'type': 'float', 'label': 'Escalar'}]

        self.configInputsOutputs(inputs, outputs)
        self.configureObjectTree()

class QDMNodeScalar(QWidget):
    def __init__(self, node, parent=None):
        self.node = node
        super().__init__(parent)
        self.initUI()
        self.data = None

    def updateDisplayText(self):
        try:
            self.svg_widget.load(self.display.text() + '=' + self.output_label.text(), fontsize=12, color='#f0f0f0')
            self.svg_widget.adjustSize()
        except ValueError:
            pass
    def initUI(self):
        self.layout = QGridLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.layout)
        self.entry = LineEntryEdit('Valor')

        self.display = QLineEdit('Display')
        self.alias = QLineEdit('Alias')
        self.svg_widget = SVGLabel()
        self.svg_widget.load(self.display.text(), color='#f0f0f0')

        self.svg_widget.adjustSize()
        self.output_label = QLabel(' ')
        self.display.textChanged.connect(self.updateDisplayText)

        self.entry.textChanged.connect(self.node.updateNode)

        self.layout.addWidget(self.display, 0, 1)
        self.layout.addWidget(QLabel('Display'), 0, 0)
        self.layout.addWidget(self.alias, 1, 1)
        self.layout.addWidget(QLabel('Alias'), 1, 0)
        self.layout.addWidget(self.entry, 2, 1)
        self.layout.addWidget(QLabel('Expressão'), 2, 0)

        self.layout.addWidget(self.svg_widget, 3, 0, 1, 2)
        #self.layout.addWidget(self.output_label, 4, 0, 1, 2)
        self.entrys = [self.entry, self.display, self.alias]
        self.node.parent.variables.append(self.node)

    def refresh(self):

        value = self.entry.text()
        readdata = self.entry.evaluate(value)
        try:
            self.output_label.setText(f'{readdata:.3e}')
        except ValueError:
            self.output_label.setText(f'---')
        self.updateDisplayText()

        self.data = readdata
        if (self.node.outputs[0].hasEdge()):
            self.node.sendSignal([self.data], self.node.outputs, [self], ['float'])

ext: py

max_stars_repo_name: rkavenaghi/MECOM

max_issues_repo_name: rkavenaghi/MECOM

max_forks_repo_name: rkavenaghi/MECOM

reason: import numpy


text:
from loguru import logger
import random
from dataclasses import dataclass
from pathlib import Path
from typing import Tuple

import ganslate
import numpy as np
import torch
from ganslate import configs
from ganslate.data.utils.body_mask import apply_body_mask
from ganslate.data.utils.ops import pad
from ganslate.data.utils.registration_methods import truncate_CT_to_scope_of_CBCT
from ganslate.data.utils.stochastic_focal_patching import StochasticFocalPatchSampler
from ganslate.utils import io, sitk_utils
from omegaconf import MISSING
from torch.utils.data import Dataset

from .common import clamp_normalize, mask_out_ct

EXTENSIONS = ['.nrrd']

@dataclass
class CBCTtoCTDatasetConfig(configs.base.BaseDatasetConfig):
    # Allows 2D or 3D patches
    patch_size: Tuple[int] = (32, 32, 32)
    hounsfield_units_range: Tuple[int, int] = (-1000, 2000)
    # Proportion of focal region size compared to original volume size
    focal_region_proportion: float = 0.2

class CBCTtoCTDataset(Dataset):

    def __init__(self, conf):
        root_path = Path(conf.train.dataset.root).resolve()

        self.paths_CBCT = []
        self.paths_CT = []

        for patient in root_path.iterdir():
            cbct_dir = patient / "CBCT"
            if cbct_dir.is_dir():
                patient_cbcts = io.make_dataset_of_directories(cbct_dir, EXTENSIONS)
                self.paths_CBCT.extend(patient_cbcts)

            ct_dir = patient / "CT"
            if ct_dir.is_dir():
                patient_cts = io.make_dataset_of_directories(ct_dir, EXTENSIONS)
                self.paths_CT.extend(patient_cts)

        self.num_datapoints_CBCT = len(self.paths_CBCT)
        self.num_datapoints_CT = len(self.paths_CT)

        # Min and max HU values for clipping and normalization
        self.hu_min, self.hu_max = conf.train.dataset.hounsfield_units_range

        focal_region_proportion = conf.train.dataset.focal_region_proportion
        self.patch_size = conf.train.dataset.patch_size
        assert (len(self.patch_size) in [2, 3]), "Patch has to be 2D or 3D."
        self.patch_sampler = StochasticFocalPatchSampler(self.patch_size, focal_region_proportion)

    def __getitem__(self, index):

        index_CBCT = index % self.num_datapoints_CBCT
        index_CT = random.randint(0, self.num_datapoints_CT - 1)

        path_CBCT = self.paths_CBCT[index_CBCT]
        path_CT = self.paths_CT[index_CT]

        # Fetches the scans, and does part of the preprocessing.
        # If the scan is smaller than the patch size, it will get another one.
        CT = self._get_and_preprocess_CT(path_CT)
        CBCT = self._get_and_preprocess_CBCT(path_CBCT)

        # Limit the slices of CT to correspond to those of CBCT
        CT = self._limit_CT_to_CBCT(CT, CBCT)

        # Masking is applied on numpy arrays
        CBCT = sitk_utils.get_npy(CBCT)
        CT = sitk_utils.get_npy(CT)

        # Perform morphological ops to find the mask of the body and set all the
        # outside values to the minimum value.
        CBCT = apply_body_mask(CBCT, apply_mask=True, masking_value=self.hu_min, hu_threshold=-800)
        CT = apply_body_mask(CT, apply_mask=True, masking_value=self.hu_min, hu_threshold=-600)

        CBCT = torch.tensor(CBCT)
        CT = torch.tensor(CT)

        # Extract patches
        CBCT, CT = self.patch_sampler.get_patch_pair(CBCT, CT)

        CBCT, CT = clamp_normalize(CBCT, CT, self.hu_min, self.hu_max)

        return {'A': CBCT, 'B': CT}

    def _get_and_preprocess_CT(self, path_CT, num_replacements_threshold=10):
        for i in reversed(range(num_replacements_threshold)):
            # load nrrd as SimpleITK objects
            CT = sitk_utils.load(Path(path_CT) / 'CT.nrrd')

            # Selected if it's big enough for the training
            if not sitk_utils.is_image_smaller_than(CT, self.patch_size):
                # Mask out the
                CT = mask_out_ct(CT, path_CT, self.hu_min)
                return CT

            # Remove from the paths since it's too small for the training.
            # If-statement since the path might already be deleted by another worker.
            if path_CT in self.paths_CT:
                self.paths_CT.remove(path_CT)
                logger.info(f"Removed the image with size {sitk_utils.get_torch_like_size(CT)}"
                            f" as it's smaller than the defined patch_size. Path: {path_CT}")

            # Randomly select another one
            path_CT = random.choice(self.paths_CT)

            if i == 0:
                raise ValueError(
                    f"Could not replace the image for {num_replacements_threshold}"
                    " consecutive times. Please verify your images and the specified config.")

    def _get_and_preprocess_CBCT(self, path_CBCT, num_replacements_threshold=10):
        for i in reversed(range(num_replacements_threshold)):
            # load nrrd as SimpleITK objects
            CBCT = sitk_utils.load(Path(path_CBCT) / 'CBCT.nrrd')

            # Remove warped slices in CBCT
            num_slices = sitk_utils.get_size(CBCT)[-1]
            start_slice = int(num_slices * 0.13)
            end_slice = int(num_slices * 0.82)
            CBCT = sitk_utils.slice_image(CBCT, start=(0, 0, start_slice), end=(-1, -1, end_slice))

            # Selected if it's big enough for the training
            if not sitk_utils.is_image_smaller_than(CBCT, self.patch_size):
                return CBCT

            # Remove from the paths since it's too small for the training.
            # If-statement since the path might already be deleted by another worker.
            if path_CBCT in self.paths_CBCT:
                self.paths_CBCT.remove(path_CBCT)
                logger.info(f"Removed the image with size {sitk_utils.get_torch_like_size(CBCT)}"
                            f" as it's smaller than the defined patch_size. Path: {path_CBCT}")

            # Randomly select another one
            path_CBCT = random.choice(self.paths_CBCT)

            if i == 0:
                raise ValueError(
                    f"Could not replace the image for {num_replacements_threshold}"
                    " consecutive times. Please verify your images and the specified config.")

    def _limit_CT_to_CBCT(self, CT, CBCT):
        # Limit CT so that it only contains part of the body shown in CBCT
        CT_truncated = truncate_CT_to_scope_of_CBCT(CT, CBCT)
        if sitk_utils.is_image_smaller_than(CT_truncated, self.patch_size):
            logger.info("Post-registration truncated CT is smaller than the defined patch size."
                        " Passing the whole CT volume.")
            return CT
        return CT_truncated

    def __len__(self):
        return max(self.num_datapoints_CBCT, self.num_datapoints_CT)

max_stars_repo_name: ganslate-team/placeholder-name


text:
import numpy as np
import os.path as osp
from PIL import Image
from torch.utils import data

class cityscapesDataSetSSL(data.Dataset):
    """
    Class to help load the Cityscapes dataset pseduo labels for SSL training
    """

    def __init__(self, root, list_path, crop_size=(11, 11), mean=(128, 128, 128), max_iters=None, set='val', label_folder=None):
        """
        Initialises the object

        Args:
            root (string): Cityscapes directory path
            list_path (string): Path to image list file
            crop_size (tuple, optional): resizes images. Defaults to (11, 11).
            mean (tuple, optional): value for mean subtraction. Defaults to (128, 128, 128).
            max_iters (int, optional): maximum number of iterations. Defaults to None.
            set (str, optional): either set to 'train' or 'val'. Defaults to 'val'.
            label_folder (string, optional): path to pseudo labels. Defaults to None.
        """
        self.root = root
        self.list_path = list_path
        self.crop_size = crop_size
        self.mean = mean
        self.img_ids = [i_id.strip() for i_id in open(list_path)]
        if not max_iters == None:
            self.img_ids = self.img_ids * \
                int(np.ceil(float(max_iters)/len(self.img_ids)))
        self.files = []
        self.set = set
        self.label_folder = label_folder

    def __len__(self):
        """
        Returns:
            int: number of images
        """
        return len(self.img_ids)

    def __getitem__(self, index):
        """
        Interator function

        Args:
            index (int)

        Returns:
            tuple: (image, label, image.shape, image.name)
        """
        name = self.img_ids[index]
        image = Image.open(
            osp.join(self.root, "leftImg8bit/%s/%s" % (self.set, name))).convert('RGB')
        label = Image.open(
            osp.join(self.root, self.label_folder+"/%s" % name.split('/')[1]))
        # resize
        image = image.resize(self.crop_size, Image.BICUBIC)
        image = np.asarray(image, np.float32)
        label = np.asarray(label, np.float32)

        size = image.shape
        image = image[:, :, ::-1]  # change to BGR
        image -= self.mean
        image = image.transpose((2, 0, 1))

        return image.copy(), label.copy(), np.array(size), name

max_stars_repo_name: thefatbandit/FDA

max_issues_repo_name: thefatbandit/FDA

max_forks_repo_name: thefatbandit/FDA