# -*- coding: utf-8 -*-
"""
Created on Mon Mar 18 11:38:59 2024

@author: zilya
"""
from types import SimpleNamespace
from math import ceil, pi


def param_hardware():
    hardware = SimpleNamespace()
    hardware.gamma = 42.576e6                   # Hz/T    Гиромагнитное отношение водорода
    G_amp_max = 37.8                            # mT/m.   Максимальный градиент
    hardware.G_amp_max = G_amp_max*1e-3*hardware.gamma   # Hz/m.   Максимальный градиент
    G_slew_max = 121                            # T/m/s.  Максимальная скорость нарастания
    hardware.G_slew_max = G_slew_max*hardware.gamma      # Hz/m/s. Максимальная скорость нарастания
    hardware.rf_raster_time = 1e-6              # s.      Растр РЧ импульса
    hardware.grad_raster_time = 10e-6           # s.      Растр градиентов
    tau_max = hardware.G_amp_max/hardware.G_slew_max              # s.      Максимальное время нарастания градиента с учетом макс скорости нарастания
    hardware.tau_max = ceil(tau_max/ hardware.grad_raster_time)*hardware.grad_raster_time
    hardware.B0 = 1.5
    hardware.fat_ppm = -3.5
    
    hardware.rf_ringdown_time=20e-6
    hardware.rf_dead_time=100e-6
    hardware.adc_dead_time=10e-6
    return hardware
    
def param_rf_SE(sl_thkn):
    gamma = 42.576e6 
    G_amp_max = 37.8                            
    G_amp_max = G_amp_max*1e-3*gamma  
    
    rf_SE = SimpleNamespace()
 
    rf_SE.t_BW_product_ex1 = 3.8
    rf_SE.t_BW_product_ref1 = 4.2
    rf_SE.t_BW_product_ex2 = 3.55
    rf_SE.t_BW_product_ref2 = 3.55

    rf_SE.t_ex1 = 2.05e-3
    rf_SE.t_ref1 = 2.56e-3
    rf_SE.t_ex2 = 3.10e-3
    rf_SE.t_ref2 = 3.88e-3

    if sl_thkn > rf_SE.t_BW_product_ex1/(rf_SE.t_ex1*G_amp_max):  
       rf_SE.t_BW_product_ex = rf_SE.t_BW_product_ex1
       rf_SE.t_BW_product_ref = rf_SE.t_BW_product_ref1
    else:
       rf_SE.t_BW_product_ex = rf_SE.t_BW_product_ex2
       rf_SE.t_BW_product_ref = rf_SE.t_BW_product_ref2
        
    if sl_thkn > rf_SE.t_BW_product_ex2/(rf_SE.t_ex1*G_amp_max):
       rf_SE.t_ex = rf_SE.t_ex1
       rf_SE.t_ref = rf_SE.t_ref1 
    else:
       rf_SE.t_ex = rf_SE.t_ex2
       rf_SE.t_ref = rf_SE.t_ref2
    
    rf_SE.apodization = 0.27
    return rf_SE

def param_rf_HASTE(sl_thkn):
    gamma = 42.576e6 
    G_amp_max = 37.8                            
    G_amp_max = G_amp_max*1e-3*gamma
    
    rf_HASTE = SimpleNamespace()
    
    rf_HASTE.t_BW_product_ex1 = 3.55
    rf_HASTE.t_BW_product_ref1 = 3.55
    rf_HASTE.t_BW_product_ex2 = 3.55
    rf_HASTE.t_BW_product_ref2 = 3.55
    
     
    rf_HASTE.t_ex1 = 1.02e-3
    rf_HASTE.t_ref1 = 1.28e-3
    rf_HASTE.t_ex2 = 1.28e-3
    rf_HASTE.t_ref2 = 1.79e-3
    
    if sl_thkn > rf_HASTE.t_BW_product_ex1/(rf_HASTE.t_ex1*G_amp_max):
        rf_HASTE.t_ex = rf_HASTE.t_ex1
        rf_HASTE.t_ref = rf_HASTE.t_ref1 
    else:
        rf_HASTE.t_ex = rf_HASTE.t_ex2
        rf_HASTE.t_ref = rf_HASTE.t_ref2
        
    rf_HASTE.t_BW_product_ex = rf_HASTE.t_BW_product_ex1
    rf_HASTE.t_BW_product_ref = rf_HASTE.t_BW_product_ref1
     
    rf_HASTE.apodization = 0.27
    return rf_HASTE
    
def param_rf_GRE():
    rf_GRE = SimpleNamespace()
    
    rf_GRE.t_ex = 0.510e-3                      
    rf_GRE.t_BW_product_ex = 2.13               
    rf_GRE.apodization = 0.3
    return rf_GRE

def param_rf_TONE():
    rf_TONE = SimpleNamespace()
    
    rf_TONE.t_ex = 1.020e-3                       
    rf_TONE.t_BW_product_ex = 5               
    rf_TONE.apodization = 0.3
    return rf_TONE
    
def param_rf_FS():
    rf_FS = SimpleNamespace()
    
    B0 = 1.5
    gamma = 42.576e6
    rf_FS.FS_sat_ppm = -3.5
    rf_FS.FS_pulse_duration = 8e-3
    rf_FS.flip_FS = 90
    #rf_FS.flip_FS = round(rf_FS.flip_FS * pi / 180, 3)
    #rf_FS.BW_sat = 100
    rf_FS.BW_sat = B0 * 1e-6 * rf_FS.FS_sat_ppm * gamma*0.8
    return rf_FS

def param_rf_inv():
    rf_inv = SimpleNamespace()
    
    rf_inv.t_inv = 2.56e-3
    rf_inv.t_BW_product_inv = 4.2
    rf_inv.inv_flip_angle = 180
    return rf_inv

def param_rf_we():
    rf_we = SimpleNamespace()
    
    rf_we.t_we_ex = 0.510e-3  
    rf_we.t_BW_product_we_ex = 2.13
    rf_we.we_tau = 2.38*10E-4
    return rf_we

def param_rf_sat():
    rf_sat = SimpleNamespace()
    
    rf_sat.t_sat = 0.510e-3                      
    rf_sat.t_BW_product_sat = 2.13                                  
    rf_sat.sat_flip_angle = 90
    rf_sat.ssp_spoil_area = [2000, 2000, 2000]
    rf_sat.ssp_spoil_dur = [0.002, 0.002, 0.002]
    return rf_sat

def param_rf_sat_TOF():
    rf_sat = SimpleNamespace()
    
    rf_sat.t_sat_TOF = 0.510e-3                      
    rf_sat.t_BW_product_sat_TOF = 2.13                                  
    rf_sat.flip_angle_sat_TOF = 90
    return rf_sat

def param_rf_PRESS():
    rf_PRESS = SimpleNamespace()
    rf_PRESS.t_ex = 2.05e-3
    rf_PRESS.t_BW_product_ex = 3.8
    rf_PRESS.t_echo1 = 2.56e-3
    rf_PRESS.t_BW_product_echo1 = 4.2
    rf_PRESS.t_echo2 = 2.56e-3
    rf_PRESS.t_BW_product_echo2 = 4.2
    return rf_PRESS

def param_rf_STEAM():
    rf_STEAM = SimpleNamespace()
    rf_STEAM.t_rf_x = 1e-3
    rf_STEAM.t_BW_product_rf_x = 2.13
    rf_STEAM.t_rf_y = 1e-3
    rf_STEAM.t_BW_product_rf_y = 2.13
    rf_STEAM.t_rf_z = 1e-3
    rf_STEAM.t_BW_product_rf_z = 2.13
    return rf_STEAM

def param_rf_CHESS():
    rf_CHESS = SimpleNamespace()
    rf_CHESS.ws_angle = 120
    rf_CHESS.gr_ws_spoiler_area = 600
    rf_CHESS.t_spectro_ws = 15e-3
    rf_CHESS.t_BW_product_ws = 2
    rf_CHESS.ws_freq_offset = 0 
    return rf_CHESS

def param_phase_cycling_sets_PRESS():
    phase_cycling_sets = {"rf_ex_phases"    : [90, 90,  90,  90,  270, 270, 270, 270],
                          "rf_echo1_phases" : [0,  90,  180, 270, 0,   90,  180, 270],
                          "rf_echo2_phases" : [90, 180, 270, 0,   0,   90,  180, 270]}
    return phase_cycling_sets

def param_phase_cycling_sets_STEAM():
    phase_cycling_sets = {"rf_x_phases" : [0, 0, 0, 0, 90, 90, 90, 90],
                          "rf_y_phases" : [0, 0, 90, 90, 0, 0, 90, 90],
                          "rf_z_phases" : [0, 90, 0, 90, 0, 90, 0, 90],
                          "adc_phases"  : [0, 90, 90, 0, 90, 0, 0, 90]}
    return phase_cycling_sets

def param_default():
    default = SimpleNamespace()
    default.sl_groups = 1
    default.sl_nb = 1
    default.sl_thkn = 10e-3
    default.sl_gap = 100
    default.slab_thkn = 100e-3
    
    default.FoV_f = 250e-3
    default.FoV_p_image = 250e-3
    default.Nf = 128
    default.Np_image = 128
    default.Nss_image = 8
    default.BW_pixel = 500
    
    default.TE = 50e-3
    default.N_TE = 1
    default.IE = 10e-3
    default.ETL = 8
    default.contrasts = 2
    default.concats = 1
    default.TR = 1000e-3
    default.TD = 0
    
    default.alpha = 90
    default.beta = 180
    default.spoil_strenght = 4
    default.RF_spoil = 117
    
    default.average = 1
    default.D_scans = 10
    default.num_dynamics = 1
    default.ph_over_phase = 0
    default.ph_over_slice = 0
    
    default.TI = 200e-3
    default.TI_extra = 200e-3
    default.phi_wing = 149
    default.N_wings = 14
    default.TEeff = 200e-3
    default.flip_SR = 40
    default.N_TI = 1
    default.b = 1000
    
    default.sat_thickness = 0.05
    default.sat_offcenter = 0.2
    
    default.AT_sync = 0.05
    default.T_sync = 0.2
    default.na_delay = 5
    default.ph_per_ds = 8
    
    default.PI_prescan_lines = 8
    default.PI_prescan_lines_ss = 8
    return default
    

    