coil2xml.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # Take user inputs and convert them into either coil2xml or
  2. import xml.etree.ElementTree as ET
  3. import h5py
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. def coil2xml(b1maps=None, coil_design=None, fov=256, name='coils', out_folder=''):
  7. """
  8. Inputs
  9. ------
  10. b1maps : list, optional
  11. List of np.ndarray (dtype='complex') maps for all channels
  12. coil_design : dict, optional
  13. Dictionary containing information on coil design (see documentation)
  14. fov : float
  15. Field-of-view of coil in mm
  16. name : str, optional
  17. Name of generated .xml file
  18. out_folder : str, optional
  19. Path to directory where the output .h5 is stored
  20. Returns
  21. -------
  22. None
  23. """
  24. if b1maps is None and coil_design is None:
  25. raise ValueError("One of b1map and coil_design must be provided")
  26. # b1 map case
  27. if b1maps is not None:
  28. root = ET.Element('CoilArray')
  29. for ch in range(len(b1maps)): # for each channel
  30. # Check dimensions
  31. if len(b1maps[ch].shape) < 2 or len(b1maps[ch].shape) > 3 \
  32. or max(b1maps[ch].shape) != min(b1maps[ch].shape):
  33. raise ValueError("b1map must be a 2D square or 3D cubic array: \
  34. all sides must be equal")
  35. N = b1maps[ch].shape[0]
  36. dim = len(b1maps[ch].shape)
  37. b1_magnitude = np.absolute(b1maps[ch])
  38. b1_phase = np.angle(b1maps[ch])
  39. # Make h5 file
  40. coil_h5_path = name + f'_ch{ch+1}.h5'
  41. coil = h5py.File(out_folder + '/' + coil_h5_path, 'a')
  42. if 'maps' in coil.keys():
  43. del coil['maps']
  44. maps = coil.create_group('maps')
  45. magnitude = maps.create_dataset('magnitude',b1_magnitude.shape,dtype='f')
  46. phase = maps.create_dataset('phase',b1_phase.shape,dtype='f')
  47. # Set h5 file contents
  48. if dim == 2:
  49. magnitude[:,:] = b1_magnitude
  50. phase[:,:] = b1_phase
  51. elif dim == 3:
  52. print('3d!')
  53. magnitude[:,:,:] = b1_magnitude
  54. phase[:,:,:] = b1_phase
  55. coil.close()
  56. # Add corresponding coil to .xml tree
  57. externalcoil = ET.SubElement(root, "EXTERNALCOIL")
  58. externalcoil.set("Points",str(N))
  59. externalcoil.set("Name",f"C{ch+1}")
  60. externalcoil.set("Filename",coil_h5_path)
  61. externalcoil.set("Extent",str(fov)) # fov is in mm
  62. externalcoil.set("Dim",str(dim))
  63. coil_tree = ET.ElementTree(root)
  64. coil_tree.write(out_folder + '/' + name + '.xml')
  65. if __name__ == '__main__':
  66. # a = h5py.File('coil2xml/sensmaps.h5','a')
  67. # print(a['maps'].keys())
  68. # print(a['maps']['magnitude'].keys())
  69. # map_mag = a['maps']['magnitude']
  70. # map_phase = a['maps']['phase']
  71. #
  72. #
  73. # plt.figure(1)
  74. #
  75. # for ch in range(8):
  76. # plt.subplot(2,8,ch+1)
  77. # plt.imshow(map_mag[f'0{ch}'][()])
  78. # plt.subplot(2,8,ch+9)
  79. # plt.imshow(map_phase[f'0{ch}'][()])
  80. #
  81. # plt.show()
  82. b1 = np.ones((32,32))
  83. XY = np.meshgrid(np.linspace(0,1,32), np.linspace(0,1,32))
  84. X = XY[0]
  85. Y = XY[1]
  86. b1 = np.sqrt(X**2 + Y**2)
  87. plt.imshow(b1)
  88. plt.show()
  89. coil2xml(b1maps=[b1], fov=200, name='test_coil', out_folder='coil2xml')