#!/bin/python2
# python2 script
# Generate crossmodal bag-of-words (XBOW) for the AVEC 2018 Cross-cultural Emotion Sub-Challenge (CES)
# Put the scripts into a subfolder of the AVEC2018_CES package, e.g., AVEC2018_CES/scripts_CES/
# Output: csv files with features generated by openXBOW

import os
import fnmatch
from read_csv import load_features
from write_csv import save_features

# Folders with feature files
folder_audio_features  = '../audio_features_mfcc/'
folder_visual_features = '../visual_features/'
folder_boaw            = '../audio_features_xbow/'
folder_bovw            = '../visual_features_xbow/'

temporary_folder = 'work/'  # To store codebook files

# Window size
jar_openxbow = 'openXBOW.jar'  # https://github.com/openXBOW/openXBOW
window_size  = 4.0

# Do NOT modify
hop_size = 0.1  # hop size of the labels

openxbow_options_audio           = '-attributes nt1[39] -writeName -writeTimeStamp -t ' + str(window_size) + ' ' + str(hop_size)
openxbow_options_visual          = '-attributes nt1[18] -writeName -writeTimeStamp -t ' + str(window_size) + ' ' + str(hop_size)
openxbow_options_codebook_audio  = '-size 100 -a 1 -log -standardizeInput'
openxbow_options_codebook_visual = '-size 100 -a 1 -log'

# Get all files
files_train = fnmatch.filter(os.listdir(folder_audio_features), 'Train_*')  # filenames are the same for all modalities
files_devel = fnmatch.filter(os.listdir(folder_audio_features), 'Devel_*')
files_test  = fnmatch.filter(os.listdir(folder_audio_features), 'Test_*')
files_train.sort()
files_devel.sort()
files_test.sort()

# Create folder, remove existing files
if not os.path.exists(temporary_folder):
    os.mkdir(temporary_folder)
if not os.path.exists(folder_boaw):
    os.mkdir(folder_boaw)
if not os.path.exists(folder_bovw):
    os.mkdir(folder_bovw)

for fn in ['Train_audio.csv', 'Train_visual.csv', 'Codebook_audio.txt', 'Codebook_visual.txt']:
    if os.path.exists(temporary_folder + fn):
        os.remove(temporary_folder + fn)

# Create codebooks
print('Concatenating training feature files ...')
codebook_audio  = temporary_folder + 'Codebook_audio.txt'
codebook_visual = temporary_folder + 'Codebook_visual.txt'

for fn in files_train:
    features = load_features(folder_audio_features + fn)
    save_features(temporary_folder + 'Train_audio.csv',  features, append=True, instname=fn)
    features = load_features(folder_visual_features + fn)
    save_features(temporary_folder + 'Train_visual.csv', features, append=True, instname=fn)

print('Generating codebook file ' + codebook_audio)
os.system('java -jar ' + jar_openxbow + ' -B ' + codebook_audio  + ' -i ' + temporary_folder + 'Train_audio.csv'  + ' ' + openxbow_options_audio  + ' ' + openxbow_options_codebook_audio)
print('Generating codebook file ' + codebook_visual)
os.system('java -jar ' + jar_openxbow + ' -B ' + codebook_visual + ' -i ' + temporary_folder + 'Train_visual.csv' + ' ' + openxbow_options_visual + ' ' + openxbow_options_codebook_visual)

# Generate XBOW files for train/devel/test and audio/video
print('Generating BoAW and BoVW feature files for Train/Devel/Test and audio/video ...')
for fn in files_train:
    print('Generating BoAW and BoVW for file ' + fn + ' ...')
    os.system('java -jar ' + jar_openxbow + ' -b ' + codebook_audio  + ' -i ' + folder_audio_features  + fn + ' -o ' + folder_boaw + fn + ' ' + openxbow_options_audio)
    os.system('java -jar ' + jar_openxbow + ' -b ' + codebook_visual + ' -i ' + folder_visual_features + fn + ' -o ' + folder_bovw + fn + ' ' + openxbow_options_visual)
for fn in files_devel:
    print('Generating BoAW and BoVW for file ' + fn + ' ...')
    os.system('java -jar ' + jar_openxbow + ' -b ' + codebook_audio  + ' -i ' + folder_audio_features  + fn + ' -o ' + folder_boaw + fn + ' ' + openxbow_options_audio)
    os.system('java -jar ' + jar_openxbow + ' -b ' + codebook_visual + ' -i ' + folder_visual_features + fn + ' -o ' + folder_bovw + fn + ' ' + openxbow_options_visual)
for fn in files_test:
    print('Generating BoAW and BoVW for file ' + fn + ' ...')
    os.system('java -jar ' + jar_openxbow + ' -b ' + codebook_audio  + ' -i ' + folder_audio_features  + fn + ' -o ' + folder_boaw + fn + ' ' + openxbow_options_audio)
    os.system('java -jar ' + jar_openxbow + ' -b ' + codebook_visual + ' -i ' + folder_visual_features + fn + ' -o ' + folder_bovw + fn + ' ' + openxbow_options_visual)

