# Caller script for executing a simulation with JEMRIS (prior installation required)
# Gehua Tong, April 2020




from seq2xml import seq2xml
from sim2xml import sim2xml
from recon_jemris import read_jemris_output
from coil2xml import coil2xml
import subprocess
import tkinter as tk
from tkinter.filedialog import askopenfilename

#from virtualscanner.core import constants
import h5py
import os

# Paths
#PY2JEMRIS_SIM_PATH = constants.SERVER_SIM_BLOCH_PY2JEMRIS_PATH / 'sim'
from scipy.io import savemat
import time

def ask_for_sim_files():
    """Helper function for sim_jemris;
       Asks the user for simulation files through file system selection

    Returns
    -------
    files_list : list
        A dictionary indicating paths to the files required to construct simu.xml

    """
    files_list = {}
    names = ['seq_xml', 'pht_h5', 'tx_xml', 'rx_xml']
    prompt_list = ['sequence file (.xml)', 'phantom file (.h5)','Tx file (.xml)', 'Rx file (.xml)']

    for u in range(len(prompt_list)-1):
        print(f"Pick your {prompt_list[u]}.")
        tk.Tk().withdraw()
        filename = askopenfilename()
        files_list[names[u]] = filename

    return files_list



def run_jemris(working_folder = None):
    """Runs JEMRIS simulation on system command line
       Assumes that the working folder contains all required files and
               that JEMRIS is installed and added to PATH on the operating system
       Simply, the command "jemris simu.xml" is run and the path to signals.h5 is returned

    Inputs
    ------
    working_folder : str
        Working folder where the simulation is performed

    Returns
    -------
    signal path : str or pathlib Path object
        Path to JEMRIS simulation output data file (this file is always called signals.h5)

    """
    print("Simulating using JEMRIS ...")
    # Always run from the py2jemris/sim directory
    if working_folder is None:
        working_folder = 'sim'
    original_wd = os.getcwd()
    os.chdir(working_folder)
    print(os.system('dir'))
    out = os.system('jemris simu.xml')
    print(out)
    os.chdir(original_wd)
    # Find signal.h5
    if isinstance(working_folder, str):
        signal_path = working_folder + '/signals.h5'
    else:
        signal_path = working_folder / 'signals.h5' # Return the absolute signal path here


    return signal_path

def sim_jemris(list_sim_files=None, working_folder=None):
    """Runs a JEMRIS MR simulation using given .xml and .h5 files
              based on custom file inputs. Returns complex signal data.
    Inputs
    ------
    list_sim_files : dict
        Dictionary of paths to relevant simulation files
    working_folder : str
        Working folder where the simulation is performed


    Returns
    -------
    output : dict
        Complex signal data with 3 fields
        'Mxy' : Complex representation of transverse magnetization
        'M_vec' : 3D representation of magnetization (Mx, My, Mz)
        'T' : Timing of readout points

    """

    # Use interactive option if there is no dictionary input
    all_files_exist = False
    while not all_files_exist:
        try:
            seq_xml = list_sim_files['seq_xml']
            pht_h5 = list_sim_files['pht_h5']
            tx_xml = list_sim_files['tx_xml']
            rx_xml = list_sim_files['rx_xml']

            all_files_exist = True
        except:
            list_sim_files = ask_for_sim_files()

    # Extract sequence and phantom name
    seq_name = seq_xml[seq_xml.rfind('/')+1:seq_xml.rfind('.xml')]
    pht_name = pht_h5[pht_h5.rfind('/')+1:pht_h5.rfind('.h5')]

    # Make simu.xml
    sim2xml(sim_name='simu', seq=seq_xml, phantom=pht_h5, Tx=tx_xml, Rx=rx_xml,
                        seq_name=seq_name, sample_name=pht_name, out_folder_name=str(working_folder))
    # Rum JEMRIS on command line
    signal_path = run_jemris(working_folder)
    print(signal_path)

    file_discovered = False
    print((os.path.abspath(signal_path)))
    while not file_discovered:
        file_discovered = os.path.exists(os.path.abspath(signal_path))
        print(file_discovered)
        time.sleep(2)

    Mxy_out, M_vec_out, times_out = read_jemris_output(signal_path)
    output = {'Mxy': Mxy_out, "M_vec": M_vec_out, 'T': times_out}

    return output



from recon_jemris import *



if __name__ == '__main__':

    # JEMRIS seq.h5
    #T   = h5read('seq.h5','/seqdiag/T');           % temporal sampling points
    #RXP = h5read('seq.h5','/seqdiag/RXP');         % RF Receiver phase; unit: radiants; if negative, the TPOI was not an ADC
    #TXM = h5read('seq.h5','/seqdiag/TXM');         % RF Transmitter magnitude
    #TXP = h5read('seq.h5','/seqdiag/TXP');         % RF Transmitter phase; unit: radiants
    #GX  = h5read('seq.h5','/seqdiag/GX');          % physical X-Gradient
    #GY  = h5read('seq.h5','/seqdiag/GY');          % physical Y-Gradient
    #GZ  = h5read('seq.h5','/seqdiag/GZ');          % physical Z-Gradient


    #['seq_xml', 'pht_h5', 'tx_xml', 'rx_xml', 'working_path'
    #output = sim_jemris()
  #  print(output)
   # sim2xml(seq="gre.xml", phantom="sample.h5", Tx="uniform.xml", Rx="uniform.xml",
  #        seq_name="Sequence", sample_name="Sample", out_folder_name="sim")


    # "Sim test" April 17 for seq2xml

    # First, sim using original gre
    list_sim_orig = {'seq_xml': 'gre32.xml', 'pht_h5': 'cylindrical.h5', 'tx_xml':'uniform.xml',
                       'rx_xml': 'uniform.xml'}
    out = sim_jemris(list_sim_orig, working_folder = 'sim/test0504')
    savemat('sim/test0504/data32_orig.mat',out)



    # Second, use twice converted (.xml output of seq2xml)
    list_sim_twice = {'seq_xml': 'gre32_twice.xml', 'pht_h5': 'cylindrical.h5', 'tx_xml':'uniform.xml',
                      'rx_xml': 'uniform.xml'}
   # out = sim_jemris(list_sim_twice, working_folder = 'sim/test0504')
   # savemat('sim/test0504/data32_twice.mat',out)

