| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- # -*- coding: utf-8 -*-
- """
- @author: petrm
- """
- import os
- import sys
- import numpy as np
- # need to add the project dir with the utilities folder to path:
- project_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
- sys.path.append(project_dir)
- from utilities.magn_prep.IR_block import IR_block
- def create_params_prep_field(params):
- if params['IR']:
- params['inv_prep'] = 'IR'
-
- return params
- def magn_prep_calc(params, scanner_parameters, split_dur = False, calc_offsets = True):
-
- params = create_params_prep_field(params)
- prep_calc = ()
- prep_dur = 0
- IR_dur = 0
- contr_prep_dur = 0
-
- # start with IR
-
- IR_calc_list = []
- try: # using try because match case for some reason doesn't work
- functions = {
- 'IR' : IR_block, # inv_prep functions listed in the dictionary
- }
- func = functions.get(params['inv_prep']) # choosing one of them according to params.
- if calc_offsets:
-
- IR_geom_offsets = (np.linspace(0, params['sl_nb']-1, np.int16(params['sl_nb'])) \
- - 0.5*(np.double(params['sl_nb'])-1)) \
- * (params['sl_thkn']*(100+params['sl_gap'])/100)
- params['inv_thkn'] = params['sl_thkn'] # selective inversion of the slice
-
- else:
-
- IR_geom_offsets = [0]
-
- if 'FoV_ss' in params:
- params['inv_thkn'] = params['FoV_ss'] # selective inversion of the whole FoV, e.g. in 3D
- else:
- print(' ')
- print('!!! WARNING !!!')
- print('Check the parameter of the inversion slab thickness!')
- print("Using the default value params['inv_thkn'] = 0.45 m")
- params['inv_thkn'] = 0.45
-
- for IR_geom_offset in IR_geom_offsets:
- IR_calc, IR_dur = func(params, scanner_parameters, IR_geom_offset)
- IR_calc_list.append(IR_calc) # list of the IR objects differing only in freq_offsets
-
- prep_calc = prep_calc + (IR_calc_list,)
- prep_dur += IR_dur
-
- except:
- prep_calc = prep_calc + (None,) # NoneType in the first postion == no IR
-
- # contr_prep functions:
-
- return prep_calc, prep_dur # all calculated objects and timings stored here
- def magn_prep_add(prep_calc, seq, curr_slice = None, only_one = None):
- # function to add magn_prep objects.
- # prep_calc contains all objects calculated in magn_prep_calc
- # seq is provided from the main code
- # curr_slice is provided from the main code
- # only_one can be:
- # 'inv_prep' – if you need to add only inversion options at the place
- # where the function is called
- # 'contr_prep' – if you need only contrast preparations at
- # the place where the function is called
-
- if prep_calc == (None, None):
- return seq
-
- # prep_calc is a tuple where all calculated inv_prep and contr_prep stuff is stored.
- # The first element of this tuple contains the Standard Inversion objects. It is a list.
- # The length of this list is defined by the number of inversion slices (= Ex slices in 2D)
- # If this list has only one element, it means that we have 1 inversion slice
- # (e.g. a huge inversion slab for 3D)
- #
- # Lets choose one piece of inversion data from this list, corresponding to curr_slice:
- # IR_objects_curr_slice = prep_calc[0][curr_slice]
- #
- # This itself is a tuple.
- # Each element of this tuple is a list of IR objects that we need to add to
- # the sequence simultaneously, i.e. inversion pulse and inversion gradient.
- # These elements (blocks) are added in a loop over IR_objects_curr_slice
- # one after another.
-
-
- if not (prep_calc[0] is None): # if IR was calculated
-
- if not (curr_slice is None):
- # function is called from the slice loop.
- IR_objects_curr_slice = prep_calc[0][curr_slice]
- else:
- # function is called outside the slice loop
- IR_objects_curr_slice = prep_calc[0][0]
-
- for blocks in IR_objects_curr_slice:
- seq.add_block(*blocks) # add the list-stored blocks of IR objects of the current slice
-
- return seq
|