//  [python]
def main(args):
  df = pandas.read_csv(args.mos_file, skiprows=[], header=None)
  array = df.values
  if args.dataset_name == 'LIVE_VQC':
      y = array[1:,1]
      y_mos = np.array(list(y), dtype=np.float)
      # pos_inds = y >= 50
      # y[pos_inds] = 1
      # y[~pos_inds] = 0
  elif args.dataset_name == 'KONVID_1K':
      y = array[1:,1]
      y_mos = np.array(list(y), dtype=np.float)
      # pos_inds = y >= 3
      # y[pos_inds] = 1
      # y[~pos_inds] = 0
  elif args.dataset_name == 'YOUTUBE_UGC':
      y = array[1:,4]
      y_mos = np.array(list(y), dtype=np.float)
      # pos_inds = y >= 3
      # y[pos_inds] = 1
      # y[~pos_inds] = 0
  elif args.dataset_name == 'ALL_COMBINED':
      y = array[1:,1]
      y_mos = np.array(list(y), dtype=np.float)
  from sklearn.mixture import GaussianMixture
  gmm = GaussianMixture(n_components=2)
  gmm.fit(y_mos.reshape(-1, 1))
  y = gmm.predict(y_mos.reshape(-1, 1))
  gmm_means_sort = np.sort(gmm.means_.squeeze())
  y_new = np.zeros_like(y)
  for i, y_old in enumerate(y):
    if y_old == 0:
      y_new[i] = np.where(gmm_means_sort == gmm.means_.squeeze()[0])[0][0]
    elif y_old == 1:
      y_new[i] = np.where(gmm_means_sort == gmm.means_.squeeze()[1])[0][0]
  y = y_new
  y = y.astype(int)
  # print(y)
  X_mat = scipy.io.loadmat(args.feature_file)
  X = np.asarray(X_mat['feats_mat'], dtype=np.float)

  '''57 grayscale videos in YOUTUBE_UGC dataset, we do not consider them for fair comparison'''
  if args.color_only and args.dataset_name == 'YOUTUBE_UGC':
      gray_indices = [3,6,10,22,23,46,51,52,68,74,77,99,103,122,136,141,158,173,368,426,467,477,506,563,594,\
      639,654,657,666,670,671,681,690,697,702,703,710,726,736,764,768,777,786,796,977,990,1012,\
      1015,1023,1091,1118,1205,1282,1312,1336,1344,1380]
      gray_indices = [idx - 1 for idx in gray_indices]
      X = np.delete(X, gray_indices, axis=0)
      y = np.delete(y, gray_indices, axis=0)
  ## preprocessing
  X[np.isinf(X)] = np.nan
  imp = SimpleImputer(missing_values=np.nan, strategy='mean').fit(X)
  X = imp.transform(X)

  all_iterations = []
  t_overall_start = time.time()
  # 100 times random train-test splits
  if args.use_parallel is True:
    evaluate_bvqa_one_split_partial = functools.partial(
       evaluate_bvqa_one_split, X=X, y=y, log_short=args.log_short)
    with futures.ThreadPoolExecutor(max_workers=args.max_thread_count) as executor:
      iters_future = [
          executor.submit(evaluate_bvqa_one_split_partial, i)
          for i in range(1, args.num_iterations)]
      for future in futures.as_completed(iters_future):
        best_params, metrics_train, metrics_test = future.result()
        all_iterations.append(metrics_train + metrics_test)
  else:
    for i in range(1, args.num_iterations):
      best_params, metrics_train, metrics_test = evaluate_bvqa_one_split(
          i, X, y, args.log_short)
      all_iterations.append(metrics_train + metrics_test)

  # formatted print overall iterations
  final_avg(all_iterations)
  print('Overall {} secs lapsed..'.format(time.time() - t_overall_start))
  # save figures
  dir_path = os.path.dirname(args.out_file)
  if not os.path.exists(dir_path):
    os.makedirs(dir_path)
  scipy.io.savemat(args.out_file, 
      mdict={'all_iterations': np.asarray(all_iterations,dtype=np.float)})