# Path: imagernn/data_provider.py
# def getDataProvider(params):
#   """ we could intercept a special dataset and return different data providers """
#   assert params['dataset'] in ['flickr8k', 'flickr30k', 'coco', 'lsmdc2015'], 'dataset %s unknown' % (dataset, )
#   return BasicDataProvider(params)
# 
# Path: imagernn/imagernn_utils.py
# def decodeGenerator(params):
#   """ 
#   in the future we may want to have different classes
#   and options for them. For now there is this one generator
#   implemented and simply returned here.
#   """ 
#   if params.get('generator','lstm') == 'lstm':
#     return LSTMGenerator(params)
#   else:
#     return 0 #GenericBatchGenerator
# 
# def eval_split(split, dp, model, params, misc, **kwargs):
#   """ evaluate performance on a given split """
#   # allow kwargs to override what is inside params
#   eval_batch_size = kwargs.get('eval_batch_size', params.get('eval_batch_size',100))
#   eval_max_images = kwargs.get('eval_max_images', params.get('eval_max_images', -1))
#   BatchGenerator = decodeGenerator(params)
#   wordtoix = misc['wordtoix']
# 
#   print 'evaluating %s performance in batches of %d' % (split, eval_batch_size)
#   logppl = 0
#   logppln = 0
#   nsent = 0
#   for batch in dp.iterImageSentencePairBatch(split = split, max_batch_size = eval_batch_size, max_images = eval_max_images):
#     Ys, gen_caches = BatchGenerator.forward(batch, model, params, misc, predict_mode = True)
# 
#     for i,pair in enumerate(batch):
#       gtix = [ wordtoix[w] for w in pair['sentence']['tokens'] if w in wordtoix ]
#       gtix.append(0) # we expect END token at the end
#       Y = Ys[i]
#       maxes = np.amax(Y, axis=1, keepdims=True)
#       e = np.exp(Y - maxes) # for numerical stability shift into good numerical range
#       P = e / np.sum(e, axis=1, keepdims=True)
#       logppl += - np.sum(np.log2(1e-20 + P[range(len(gtix)),gtix])) # also accumulate log2 perplexities
#       logppln += len(gtix)
#       nsent += 1
# 
#   ppl2 = 2 ** (logppl / logppln) 
#   print 'evaluated %d sentences and got perplexity = %f' % (nsent, ppl2)
#   return ppl2 # return the perplexity
# 
# def eval_split_theano(split, dp, model, params, misc, gen_fprop, **kwargs):
#   """ evaluate performance on a given split """
#   # allow kwargs to override what is inside params
#   eval_batch_size = kwargs.get('eval_batch_size', params.get('eval_batch_size',100))
#   eval_max_images = kwargs.get('eval_max_images', params.get('eval_max_images', -1))
#   wordtoix = misc['wordtoix']
# 
#   print 'evaluating %s performance in batches of %d' % (split, eval_batch_size)
#   logppl = 0
#   logppln = 0
#   nsent = 0
#   for batch in dp.iterImageSentencePairBatch(split = split, max_batch_size = eval_batch_size, max_images = eval_max_images):
#     inp_list, lenS = prepare_data(batch,wordtoix, rev_sents=params['reverse_sentence'])
#     
#     if params.get('sched_sampling_mode',None) != None:
#     # This is making sure we don't sample from prediction path for evaluation
#         inp_list.append(0.0)
#     cost = gen_fprop(*inp_list)
#     logppl += cost[1] 
#     logppln += lenS 
#     nsent += eval_batch_size
# 
#   ppl2 = 2 ** (logppl / logppln) 
#   print 'evaluated %d sentences and got perplexity = %f' % (nsent, ppl2)
#   return ppl2 # return the perplexity


import argparse
import json
import os
import random
import scipy.io
import codecs
import numpy as np
import cPickle as pickle
import math
from collections import defaultdict
from nltk.tokenize import word_tokenize
from imagernn.data_provider import getDataProvider
from imagernn.imagernn_utils import decodeGenerator, eval_split, eval_split_theano
from nltk.align.bleu import BLEU
    # invoke the perl script to get BLEU scores
    print 'invoking eval/multi-bleu.perl script...'
    bleus = get_bleu_scores(all_candidates, all_references)
    res_struct['FinalBleu'] = bleus
    print bleus
  
    print 'saving result struct to %s' % (params['result_struct_filename'], )
    json.dump(res_struct, open(params['result_struct_filename'], 'w'))


def hold_comittee_discussion(params, com_dataset):
    
    n_memb = com_dataset['n_memb']
    n_sent = com_dataset['n_sent']
    n_imgs = len(com_dataset['images'])

    eval_array = np.zeros((n_memb,n_imgs*n_sent))
    model_id = 0  
    for mod in com_dataset['members_model']:
        checkpoint = pickle.load(open(mod, 'rb'))
        checkpoint_params = checkpoint['params']
        dataset = checkpoint_params['dataset']
        model_npy = checkpoint['model']

        checkpoint_params['use_theano'] = 1

        if 'image_feat_size' not in  checkpoint_params:
          checkpoint_params['image_feat_size'] = 4096 

        checkpoint_params['data_file'] = params['jsonFname'].rsplit('/')[-1]

# Path: imagernn/data_provider.py
# def getDataProvider(params):
#   """ we could intercept a special dataset and return different data providers """
#   assert params['dataset'] in ['flickr8k', 'flickr30k', 'coco', 'lsmdc2015'], 'dataset %s unknown' % (dataset, )
#   return BasicDataProvider(params)
# 
# Path: imagernn/imagernn_utils.py
# def decodeGenerator(params):
#   """ 
#   in the future we may want to have different classes
#   and options for them. For now there is this one generator
#   implemented and simply returned here.
#   """ 
#   if params.get('generator','lstm') == 'lstm':
#     return LSTMGenerator(params)
#   else:
#     return 0 #GenericBatchGenerator
# 
# def eval_split(split, dp, model, params, misc, **kwargs):
#   """ evaluate performance on a given split """
#   # allow kwargs to override what is inside params
#   eval_batch_size = kwargs.get('eval_batch_size', params.get('eval_batch_size',100))
#   eval_max_images = kwargs.get('eval_max_images', params.get('eval_max_images', -1))
#   BatchGenerator = decodeGenerator(params)
#   wordtoix = misc['wordtoix']
# 
#   print 'evaluating %s performance in batches of %d' % (split, eval_batch_size)
#   logppl = 0
#   logppln = 0
#   nsent = 0
#   for batch in dp.iterImageSentencePairBatch(split = split, max_batch_size = eval_batch_size, max_images = eval_max_images):
#     Ys, gen_caches = BatchGenerator.forward(batch, model, params, misc, predict_mode = True)
# 
#     for i,pair in enumerate(batch):
#       gtix = [ wordtoix[w] for w in pair['sentence']['tokens'] if w in wordtoix ]
#       gtix.append(0) # we expect END token at the end
#       Y = Ys[i]
#       maxes = np.amax(Y, axis=1, keepdims=True)
#       e = np.exp(Y - maxes) # for numerical stability shift into good numerical range
#       P = e / np.sum(e, axis=1, keepdims=True)
#       logppl += - np.sum(np.log2(1e-20 + P[range(len(gtix)),gtix])) # also accumulate log2 perplexities
#       logppln += len(gtix)
#       nsent += 1
# 
#   ppl2 = 2 ** (logppl / logppln) 
#   print 'evaluated %d sentences and got perplexity = %f' % (nsent, ppl2)
#   return ppl2 # return the perplexity
# 
# def eval_split_theano(split, dp, model, params, misc, gen_fprop, **kwargs):
#   """ evaluate performance on a given split """
#   # allow kwargs to override what is inside params
#   eval_batch_size = kwargs.get('eval_batch_size', params.get('eval_batch_size',100))
#   eval_max_images = kwargs.get('eval_max_images', params.get('eval_max_images', -1))
#   wordtoix = misc['wordtoix']
# 
#   print 'evaluating %s performance in batches of %d' % (split, eval_batch_size)
#   logppl = 0
#   logppln = 0
#   nsent = 0
#   for batch in dp.iterImageSentencePairBatch(split = split, max_batch_size = eval_batch_size, max_images = eval_max_images):
#     inp_list, lenS = prepare_data(batch,wordtoix, rev_sents=params['reverse_sentence'])
#     
#     if params.get('sched_sampling_mode',None) != None:
#     # This is making sure we don't sample from prediction path for evaluation
#         inp_list.append(0.0)
#     cost = gen_fprop(*inp_list)
#     logppl += cost[1] 
#     logppln += lenS 
#     nsent += eval_batch_size
# 
#   ppl2 = 2 ** (logppl / logppln) 
#   print 'evaluated %d sentences and got perplexity = %f' % (nsent, ppl2)
#   return ppl2 # return the perplexity


# Path: build_committee_dataset.py
import argparse
import json
import os
import random
import scipy.io
import codecs
import numpy as np
import cPickle as pickle
import math
from collections import defaultdict
from nltk.tokenize import word_tokenize
from imagernn.data_provider import getDataProvider
from imagernn.imagernn_utils import decodeGenerator, eval_split, eval_split_theano
from nltk.align.bleu import BLEU

    # invoke the perl script to get BLEU scores
    print 'invoking eval/multi-bleu.perl script...'
    bleus = get_bleu_scores(all_candidates, all_references)
    res_struct['FinalBleu'] = bleus
    print bleus
  
    print 'saving result struct to %s' % (params['result_struct_filename'], )
    json.dump(res_struct, open(params['result_struct_filename'], 'w'))


def hold_comittee_discussion(params, com_dataset):
    
    n_memb = com_dataset['n_memb']
    n_sent = com_dataset['n_sent']
    n_imgs = len(com_dataset['images'])

    eval_array = np.zeros((n_memb,n_imgs*n_sent))
    model_id = 0  
    for mod in com_dataset['members_model']:
        checkpoint = pickle.load(open(mod, 'rb'))
        checkpoint_params = checkpoint['params']
        dataset = checkpoint_params['dataset']
        model_npy = checkpoint['model']

        checkpoint_params['use_theano'] = 1

        if 'image_feat_size' not in  checkpoint_params:
          checkpoint_params['image_feat_size'] = 4096 

        checkpoint_params['data_file'] = params['jsonFname'].rsplit('/')[-1]

        dp = getDataProvider(checkpoint_params)