|
@@ -11,11 +11,11 @@ from pulseq_fixed import sequence_fixed as puls_fix
|
|
|
def output_seq(dict):
|
|
|
"""
|
|
|
The interpretation from pypulseq format of sequence to the files needed to analog part of MRI
|
|
|
-
|
|
|
+ Интерпретация последовательности из формата pypulseq в файлы, необходимые для аналоговой части МРТ.
|
|
|
:param dict: Dictionary of the impulse sequence pypulseq provided
|
|
|
-
|
|
|
+ Словарь импульсных последовательностей, предоставленный pypulseq
|
|
|
:return: files in "data_output_seq/" directory of every type of amplitudes and time points
|
|
|
-
|
|
|
+ Запись в файлы в директории "data_output_seq/" амплитуд и времени для всех типов
|
|
|
"""
|
|
|
loc_t_adc = dict['t_adc']
|
|
|
loc_t_rf = dict['t_rf']
|
|
@@ -70,9 +70,11 @@ def output_seq(dict):
|
|
|
def adc_correction():
|
|
|
"""
|
|
|
Helper function that rise times for correction of ADC events
|
|
|
-
|
|
|
+ Вспомогательная функция получения времён для коррекции АЦП событий
|
|
|
:return: rise_time: float, stores in pulseq, related to exact type of gradient events
|
|
|
+ хранится в pulseq, связан с конкретным типом градиентного события
|
|
|
fall_time: float, same as rise_time
|
|
|
+ аналогично rise_time
|
|
|
"""
|
|
|
rise_time, fall_time = None, None
|
|
|
is_adc_inside = False
|
|
@@ -90,9 +92,11 @@ def adc_correction():
|
|
|
def adc_event_edges(local_gate_adc):
|
|
|
"""
|
|
|
Helper function that rise numbers of blocks of border correction of ADC events
|
|
|
-
|
|
|
+ Вспомогательная функция для получения номеров блоков границ коррекции АЦП событий
|
|
|
:return: num_begin_l: int, number of time block when adc event starts
|
|
|
+ номер временного блока начала АЦП события
|
|
|
num_finish_l: int, same but ends
|
|
|
+ то же, но для окончания
|
|
|
"""
|
|
|
num_begin_l = 0
|
|
|
flag_begin = False
|
|
@@ -110,20 +114,24 @@ def adc_event_edges(local_gate_adc):
|
|
|
|
|
|
def synchronization(N_samples):
|
|
|
### MAIN LOOP ###
|
|
|
+ ### ОСНОВНОЙ ЦИКЛ###
|
|
|
for i in range(N_samples):
|
|
|
# delaying of RF event for time period of local delay
|
|
|
+ # задержка RF события на период времени локальной задержки
|
|
|
if RF_assintant[0] - RF_raster < time_sample[i] < RF_assintant[0] + RF_raster:
|
|
|
RF_stop = int(RF_assintant[1] / time_step)
|
|
|
gate_rf[i:RF_stop] = 1.0
|
|
|
var = 1
|
|
|
|
|
|
# mandatory disabling of RF gate due to ADC work same time
|
|
|
+ # принудительное отключение RF-шлюза из-за одновременной работы АЦП
|
|
|
gate_rf_2 = map(lambda x: time_sample[i] - ADC_raster < x < time_sample[i] + ADC_raster and 1 or 0,
|
|
|
seq_output_dict['t_adc'])
|
|
|
if np.any(np.array(list(gate_rf_2)) > 0):
|
|
|
gate_rf[i] = 0.0
|
|
|
|
|
|
# TR switch with own delay before ADC turning
|
|
|
+ # TR перключение с собственной задержкой перед включением АЦП
|
|
|
gate_tr_1 = map(lambda x: time_sample[i] - ADC_raster < x < time_sample[i] + ADC_raster and 1 or 0,
|
|
|
seq_output_dict['t_adc'])
|
|
|
if np.any(np.array(list(gate_tr_1)) > 0):
|
|
@@ -131,13 +139,16 @@ def synchronization(N_samples):
|
|
|
gate_tr_switch[i - block_delay_tr:i + 1] = 0.0
|
|
|
|
|
|
# first step of ADC gate - enabling
|
|
|
+ # первый шак АЦП шлюза - включение
|
|
|
gate_adc_1 = map(lambda x: time_sample[i] - ADC_raster < x < time_sample[i] + ADC_raster and 1 or 0,
|
|
|
seq_output_dict['t_adc'])
|
|
|
if np.any(np.array(list(gate_adc_1)) > 0):
|
|
|
gate_adc[i] = 1.0
|
|
|
|
|
|
# adc correction sue to rise and fall time of gradient
|
|
|
+ # АЦП коррекция в зависимости от времени нарастания или спада градиента
|
|
|
# defining time that ADC need to be disabled during of
|
|
|
+ # определение премени, когда АЦП необходимо отключить
|
|
|
rise_time_loc, fall_time_loc = adc_correction()
|
|
|
num_beg, num_fin = adc_event_edges(gate_adc)
|
|
|
rise_time_tick = int(rise_time_loc / time_step)
|
|
@@ -164,6 +175,7 @@ if __name__ == '__main__':
|
|
|
seq_output_dict = seq_input.waveforms_export(time_range=(0, 3))
|
|
|
|
|
|
# artificial delays due to construction of the MRI
|
|
|
+ # искусственные задержки из-за тех. особенностей МРТ
|
|
|
RF_dtime = 100 * 1e-6
|
|
|
TR_dtime = 100 * 1e-6
|
|
|
|
|
@@ -175,9 +187,11 @@ if __name__ == '__main__':
|
|
|
time_sample = np.linspace(0, time_dur, N_samples)
|
|
|
|
|
|
# output interpretation. all formats of files defined in method
|
|
|
+ # интерпретация выхода. Все форматы файлов определены в методе
|
|
|
output_seq(seq_output_dict)
|
|
|
|
|
|
# defining constants of the sequence
|
|
|
+ # определение констант последовательности
|
|
|
local_definitions = seq_input.definitions
|
|
|
ADC_raster = local_definitions['AdcRasterTime']
|
|
|
RF_raster = local_definitions['RadiofrequencyRasterTime']
|
|
@@ -198,6 +212,7 @@ if __name__ == '__main__':
|
|
|
synchronization(N_samples)
|
|
|
|
|
|
# testing plots for synchronization
|
|
|
+ # графики тестов синхрозации
|
|
|
plt.plot(seq_output_dict['t_gx'][:int(N_samples)], seq_output_dict['gx'][:int(N_samples)])
|
|
|
plt.plot(seq_output_dict['t_gy'][:int(N_samples)], seq_output_dict['gy'][:int(N_samples)])
|
|
|
plt.plot(seq_output_dict['t_gz'][:int(N_samples)], seq_output_dict['gz'][:int(N_samples)])
|