# Path: settings.py
# FLAGS = flags.FLAGS
# OUT_DIR = '/common/homes/students/rothfuss/Documents/selected_trainings/9_20bn_vae_no_OF/08-06-18_10-21'
# DUMP_DIR = "/common/homes/students/rothfuss/Documents/selected_trainings/9_20bn_vae_no_OF/08-06-18_10-21"
# TF_RECORDS_DIR = "/localhome/rothfuss/data/20bn-something/tf_records_train"
# MODE = 'valid_mode'
# VALID_MODE = 'data_frame' #'data_frame gif'
# NUM_IMAGES = 15
# NUM_DEPTH = 3
# WIDTH = 128
# HEIGHT = 128
# NUM_THREADS_QUEUERUNNER = 32 # specifies the number of pre-processing threads
# PRETRAINED_MODEL = "/common/homes/students/rothfuss/Documents/selected_trainings/9_20bn_vae_no_OF/08-06-18_10-21"
# EXCLUDE_FROM_RESTORING = None
# FINE_TUNING_WEIGHTS_LIST = None
# INPUT_DIR = ""
# MEMORY_PATH = ""
# LOSS_FUNCTIONS = ['mse', 'gdl', 'mse_gdl', 'vae']
# MODES = ["train_mode", "valid_mode", "feeding_mode"]
# VALID_MODES = ['count_trainable_weights', 'vector', 'gif', 'similarity', 'data_frame', 'psnr', 'memory_prep', 'measure_test_time']
# 
# Path: models/loss_functions.py
# def gradient_difference_loss(true, pred, alpha=2.0):
# def difference_gradient(image, vertical=True):
# def mean_squared_error(true, pred):
# def peak_signal_to_noise_ratio(true, pred):
# def kl_penalty(mu, sigma):
# def decoder_loss(frames_gen, frames_original, loss_fun):
# def decoder_psnr(frames_gen, frames_original):
# def composite_loss(original_frames, frames_pred, frames_reconst, loss_fun='mse',
#                    encoder_length=5, decoder_future_length=5,
#                    decoder_reconst_length=5, mu_latent=None, sigm_latent=None):


import tensorflow as tf
import math
import numpy as np
import data_prep.model_input as input
from pprint import pprint
from settings import FLAGS, model
from models import loss_functions
     loss: tf.Tensor skalar which is the mean over all losses
  """
  losses = []
  for l in tower_losses:
    # Add 0 dimension to the gradients to represent the tower.
    expanded_l = tf.expand_dims(l, 0)

    # Append on a 'tower' dimension which we will average over below.
    losses.append(expanded_l)

  # Average over the 'tower' dimension.
  loss = tf.concat(0, losses)
  loss = tf.reduce_mean(loss, 0)
  return loss


def create_model(mode=None, train_model_scope=None):
  model = None

  if mode is "train":
    model = TrainModel('train', scope_name='train_model')
  elif mode is 'valid':
    assert train_model_scope is not None, "train_model_scope is None, valid mode requires a train scope"
    model = ValidationModel('valid', reuse_scope=train_model_scope)
  elif mode is 'feeding':
    assert train_model_scope is not None, "train_model_scope is None, valid mode requires a train scope"
    model = FeedingValidationModel(reuse_scope=train_model_scope)

  assert model is not None


# Path: settings.py
# FLAGS = flags.FLAGS
# OUT_DIR = '/common/homes/students/rothfuss/Documents/selected_trainings/9_20bn_vae_no_OF/08-06-18_10-21'
# DUMP_DIR = "/common/homes/students/rothfuss/Documents/selected_trainings/9_20bn_vae_no_OF/08-06-18_10-21"
# TF_RECORDS_DIR = "/localhome/rothfuss/data/20bn-something/tf_records_train"
# MODE = 'valid_mode'
# VALID_MODE = 'data_frame' #'data_frame gif'
# NUM_IMAGES = 15
# NUM_DEPTH = 3
# WIDTH = 128
# HEIGHT = 128
# NUM_THREADS_QUEUERUNNER = 32 # specifies the number of pre-processing threads
# PRETRAINED_MODEL = "/common/homes/students/rothfuss/Documents/selected_trainings/9_20bn_vae_no_OF/08-06-18_10-21"
# EXCLUDE_FROM_RESTORING = None
# FINE_TUNING_WEIGHTS_LIST = None
# INPUT_DIR = ""
# MEMORY_PATH = ""
# LOSS_FUNCTIONS = ['mse', 'gdl', 'mse_gdl', 'vae']
# MODES = ["train_mode", "valid_mode", "feeding_mode"]
# VALID_MODES = ['count_trainable_weights', 'vector', 'gif', 'similarity', 'data_frame', 'psnr', 'memory_prep', 'measure_test_time']
# 
# Path: models/loss_functions.py
# def gradient_difference_loss(true, pred, alpha=2.0):
# def difference_gradient(image, vertical=True):
# def mean_squared_error(true, pred):
# def peak_signal_to_noise_ratio(true, pred):
# def kl_penalty(mu, sigma):
# def decoder_loss(frames_gen, frames_original, loss_fun):
# def decoder_psnr(frames_gen, frames_original):
# def composite_loss(original_frames, frames_pred, frames_reconst, loss_fun='mse',
#                    encoder_length=5, decoder_future_length=5,
#                    decoder_reconst_length=5, mu_latent=None, sigm_latent=None):


# Path: core/Model.py
import tensorflow as tf
import math
import numpy as np
import data_prep.model_input as input
from pprint import pprint
from settings import FLAGS, model
from models import loss_functions

     loss: tf.Tensor skalar which is the mean over all losses
  """
  losses = []
  for l in tower_losses:
    # Add 0 dimension to the gradients to represent the tower.
    expanded_l = tf.expand_dims(l, 0)

    # Append on a 'tower' dimension which we will average over below.
    losses.append(expanded_l)

  # Average over the 'tower' dimension.
  loss = tf.concat(0, losses)
  loss = tf.reduce_mean(loss, 0)
  return loss


def create_model(mode=None, train_model_scope=None):
  model = None

  if mode is "train":
    model = TrainModel('train', scope_name='train_model')
  elif mode is 'valid':
    assert train_model_scope is not None, "train_model_scope is None, valid mode requires a train scope"
    model = ValidationModel('valid', reuse_scope=train_model_scope)
  elif mode is 'feeding':
    assert train_model_scope is not None, "train_model_scope is None, valid mode requires a train scope"
    model = FeedingValidationModel(reuse_scope=train_model_scope)

  assert model is not None


  return model