Coverage for yaptide/converter/converter/fluka/helper_parsers/figure_parser.py: 74%

82 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-07-01 12:55 +0000

1from dataclasses import dataclass, field 

2from converter import solid_figures 

3from converter.solid_figures import BoxFigure, CylinderFigure, SolidFigure, SphereFigure 

4from converter.common import rotate 

5 

6 

7@dataclass(frozen=False) 

8class FlukaFigure: 

9 """Abstract class representing Fluka figure""" 

10 

11 figure_type: str = '' 

12 name: str = '' 

13 uuid: str = '' 

14 

15 

16@dataclass(frozen=False) 

17class FlukaBox(FlukaFigure): 

18 """Class representing Fluka box""" 

19 

20 figure_type: str = 'RPP' 

21 x_min: float = 0 

22 x_max: float = 0 

23 y_min: float = 0 

24 y_max: float = 0 

25 z_min: float = 0 

26 z_max: float = 0 

27 

28 

29@dataclass(frozen=False) 

30class FlukaCylinder(FlukaFigure): 

31 """Class representing Fluka cylinder""" 

32 

33 figure_type: str = 'RCC' 

34 coordinates: list[float] = field(default_factory=lambda: (0, 0, 0)) 

35 height_vector: list[float] = field(default_factory=lambda: (0, 0, 0)) 

36 radius: float = 0 

37 rotation: list[float] = field(default_factory=lambda: (0, 0, 0)) 

38 height: float = 0 

39 

40 

41@dataclass(frozen=False) 

42class FlukaSphere(FlukaFigure): 

43 """Class representing Fluka sphere""" 

44 

45 figure_type: str = 'SPH' 

46 coordinates: list[float] = field(default_factory=lambda: (0, 0, 0)) 

47 radius: float = 0 

48 

49 

50def parse_box(box: BoxFigure) -> FlukaBox: 

51 """ 

52 Parse box to Fluka RPP. 

53 RPP is a parallelepiped with sides parallel to the coordinate axes. 

54 In case the box to parse has rotation applied, we throw an error. 

55 """ 

56 if (box.rotation[0] != 0 or box.rotation[1] != 0 or box.rotation[2] != 0): 

57 raise ValueError('Rotation of box is not supported for Fluka') 

58 

59 fluka_box = FlukaBox() 

60 fluka_box.uuid = box.uuid 

61 fluka_box.x_min = box.position[0] - box.x_edge_length / 2 

62 fluka_box.x_max = box.position[0] + box.x_edge_length / 2 

63 fluka_box.y_min = box.position[1] - box.y_edge_length / 2 

64 fluka_box.y_max = box.position[1] + box.y_edge_length / 2 

65 fluka_box.z_min = box.position[2] - box.z_edge_length / 2 

66 fluka_box.z_max = box.position[2] + box.z_edge_length / 2 

67 

68 return fluka_box 

69 

70 

71def parse_cylinder(cylinder: CylinderFigure) -> FlukaCylinder: 

72 """Parse cylinder to Fluka cylinder""" 

73 height_vector = rotate((0, 0, cylinder.height), cylinder.rotation) 

74 

75 fluka_cylinder = FlukaCylinder() 

76 fluka_cylinder.coordinates = ( 

77 cylinder.position[0] - height_vector[0] / 2, 

78 cylinder.position[1] - height_vector[1] / 2, 

79 cylinder.position[2] - height_vector[2] / 2, 

80 ) 

81 fluka_cylinder.height_vector = height_vector 

82 fluka_cylinder.radius = cylinder.radius_top 

83 fluka_cylinder.uuid = cylinder.uuid 

84 fluka_cylinder.rotation = cylinder.rotation 

85 fluka_cylinder.height = cylinder.height 

86 

87 return fluka_cylinder 

88 

89 

90def parse_sphere(sphere: SphereFigure) -> FlukaSphere: 

91 """Parse sphere to Fluka sphere""" 

92 fluka_sphere = FlukaSphere() 

93 fluka_sphere.radius = sphere.radius 

94 fluka_sphere.coordinates = (sphere.position[0], sphere.position[1], sphere.position[2]) 

95 fluka_sphere.uuid = sphere.uuid 

96 return fluka_sphere 

97 

98 

99def parse_fluka_figure(figure: SolidFigure) -> FlukaFigure: 

100 """Parse any SolidFigure to FlukaFigure""" 

101 if type(figure) is BoxFigure: 

102 fluka_figure = parse_box(figure) 

103 elif type(figure) is CylinderFigure: 

104 fluka_figure = parse_cylinder(figure) 

105 elif type(figure) is SphereFigure: 

106 fluka_figure = parse_sphere(figure) 

107 else: 

108 raise ValueError(f'Unexpected solid figure type: {figure}') 

109 

110 return fluka_figure 

111 

112 

113def parse_figures(figures_json) -> list[FlukaFigure]: 

114 """Parse figures data from JSON to figures data used by Fluka""" 

115 raw_figures = [solid_figures.parse_figure(figure_dict) for figure_dict in figures_json] 

116 

117 fluka_figures = [] 

118 figure_name = 'fig{}' 

119 

120 for idx, figure in enumerate(raw_figures): 

121 fluka_figure = parse_fluka_figure(figure) 

122 fluka_figure.name = figure_name.format(idx) 

123 fluka_figures.append(fluka_figure) 

124 

125 return fluka_figures 

126 

127 

128def get_figure_name_by_uuid(figures_list: list[FlukaFigure], uuid: str) -> str: 

129 """Helper function which returns name of figure with provided uuid""" 

130 for figure in figures_list: 

131 if figure.uuid == uuid: 

132 return figure.name 

133 return None