Coverage for yaptide/converter/converter/shieldhit/detect.py: 98%

56 statements  

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

1from dataclasses import dataclass, field 

2from typing import Optional 

3from converter.shieldhit.detectors import ScoringDetector, ScoringCylinder, ScoringMesh 

4 

5 

6@dataclass 

7class ScoringFilter: 

8 """Dataclass storing information about simulation output. Used in DetectConfig dataclass.""" 

9 

10 uuid: str 

11 

12 name: str 

13 rules: list[tuple[str, str, int]] 

14 

15 rule_template: str = """ 

16 {0} {1} {2}""" 

17 

18 template: str = """Filter 

19 Name {name}{rules}""" 

20 

21 def __str__(self) -> str: 

22 return self.template.format(name=self.name, 

23 rules=''.join([self.rule_template.format(*rule) for rule in self.rules])) 

24 

25 

26@dataclass 

27class QuantitySettings: 

28 """Dataclass storing information about quantity settings.""" 

29 

30 name: str 

31 rescale: Optional[float] = None 

32 offset: Optional[float] = None 

33 primaries: Optional[int] = None 

34 material: Optional[int] = None 

35 medium: Optional[str] = None 

36 

37 settings_dict = { 

38 "name": "\n Name {name}", 

39 "rescale": "\n Rescale {rescale}", 

40 "offset": "\n Offset {offset}", 

41 "primaries": "\n Primaries {primaries}", 

42 "material": "\n Medium {material}", 

43 "medium": "\n NKMedium {medium}", 

44 } 

45 

46 def __str__(self) -> str: 

47 return "Settings"+''.join([ 

48 self.settings_dict[key].format(**{key: value}) for key, value in self.__dict__.items() if value is not None 

49 ]) 

50 

51 

52@dataclass 

53class OutputQuantity: 

54 """Class for storing output quantities used in detect.""" 

55 

56 name: str 

57 detector_type: str 

58 filter_name: str = "" 

59 diff1: Optional[tuple[float, float, float, str]] = None 

60 diff1_t: Optional[str] = None 

61 diff2: Optional[tuple[float, float, float, str]] = None 

62 diff2_t: Optional[str] = None 

63 

64 quantity_template: str = """ 

65 Quantity {detector_type} {filter_name} {settings_name}""" 

66 diff_template = """ 

67 Diff{0} {d[0]} {d[1]} {d[2]} {log} 

68 Diff{0}Type {diff_t}""" 

69 

70 settings: Optional[QuantitySettings] = None 

71 

72 def __str__(self) -> str: 

73 return ''.join([ 

74 self.quantity_template.format(detector_type=self.detector_type, filter_name=self.filter_name, 

75 settings_name=self.settings.name if self.settings else ''), 

76 self.diff_template.format(1, d=self.diff1, diff_t=self.diff1_t, log=("log" if self.diff1[3] else "")) 

77 if self.diff1 else "", 

78 self.diff_template.format(2, d=self.diff2, diff_t=self.diff2_t) if self.diff2 else "", 

79 ]) 

80 

81 

82@dataclass 

83class ScoringOutput: 

84 """Dataclass storing information about shieldhit scoring outputs.""" 

85 

86 filename: Optional[str] = None 

87 fileformat: Optional[str] = None 

88 geometry: Optional[str] = None 

89 quantities: list[OutputQuantity] = field(default_factory=lambda: []) 

90 

91 filename_str_template: str = """ 

92 Filename {filename}""" 

93 fileformat_str_template: str = """ 

94 Fileformat {fileformat}""" 

95 geometry_str_template: str = """ 

96 Geo {geometry}""" 

97 

98 template: str = """Output{fields}""" 

99 

100 def __str__(self) -> str: 

101 return self.template.format(fields=''.join([ 

102 self.filename_str_template.format(filename=self.filename) if self.filename else "", 

103 self.fileformat_str_template.format(fileformat=self.fileformat) if self.fileformat else "", 

104 self.geometry_str_template.format(geometry=self.geometry) if self.geometry else "", 

105 ''.join([str(quantity) for quantity in self.quantities]), 

106 '\n' 

107 ])) 

108 

109 

110@dataclass 

111class DetectConfig: 

112 """Class mapping of the detect.dat config file.""" 

113 

114 detectors: list[ScoringDetector] = field(default_factory=lambda: [ 

115 ScoringCylinder(""), 

116 ScoringMesh(""), 

117 ]) 

118 

119 filters: list[ScoringFilter] = field(default_factory=lambda: []) 

120 

121 outputs: list[ScoringOutput] = field(default_factory=lambda: [ 

122 ScoringOutput("cylz.bdo", geometry="CylZ_Mesh", quantities=[OutputQuantity("CylDose", "DoseGy")]), 

123 ScoringOutput("yzmsh.bdo", geometry="YZ_Mesh", quantities=[OutputQuantity("MeshDose", "DoseGy")]), 

124 ]) 

125 

126 def __str__(self): 

127 return '\n'.join([ 

128 "\n".join([str(geom) for geom in self.detectors]), 

129 "\n".join([str(filter) for filter in self.filters]), 

130 "\n".join([str(quantity.settings) 

131 for output in self.outputs for quantity in output.quantities if quantity.settings]), 

132 "\n".join([str(output) for output in self.outputs]), 

133 ])