Coverage for /opt/conda/envs/apienv/lib/python3.10/site-packages/daiquiri/implementors/tomo/fullfieldscan.py: 0%

69 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-14 02:13 +0000

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3 

4from __future__ import annotations 

5 

6import gevent 

7import logging 

8from marshmallow import fields, validate 

9 

10from tomo.fulltomo import FullFieldTomo 

11from . import tomo_helper 

12 

13from daiquiri.core.schema.validators import OneOf 

14from daiquiri.core.components import ( 

15 ComponentActor, 

16 ComponentActorSchema, 

17 ComponentActorKilled, 

18) 

19 

20 

21_logger = logging.getLogger(__name__) 

22 

23 

24class FullfieldscanSchema(ComponentActorSchema): 

25 sampleid = fields.Int( 

26 required=True, 

27 metadata={"title": "Collection"}, 

28 ) 

29 dataset_name = fields.Str( 

30 required=True, 

31 metadata={"title": "Dataset"}, 

32 ) 

33 scan_type = OneOf( 

34 ["Continuous", "Step"], 

35 dump_default="Continuous", 

36 metadata={"title": "Scan type"}, 

37 ) 

38 start_pos = fields.Float( 

39 dump_default=0, 

40 metadata={"title": "Start angle", "unit": "deg"}, 

41 ) 

42 end_pos = fields.Float( 

43 dump_default=360, 

44 metadata={"title": "End angle", "unit": "deg"}, 

45 ) 

46 tomo_n = fields.Int( 

47 dump_default=360, 

48 validate=validate.Range(min=1, max=999999), 

49 metadata={"title": "Nb steps"}, 

50 ) 

51 n_dark = fields.Int( 

52 dump_default=1, 

53 validate=validate.Range(min=0, max=999999), 

54 metadata={"title": "Nb darks"}, 

55 ) 

56 n_flat = fields.Int( 

57 dump_default=1, 

58 validate=validate.Range(min=0, max=999999), 

59 metadata={"title": "Nb flats"}, 

60 ) 

61 expo_time = fields.Float( 

62 validate=validate.Range(min=0.001, max=10), 

63 dump_default=None, 

64 metadata={"title": "Exposure time", "unit": "s"}, 

65 ) 

66 use_sinogram = fields.Bool( 

67 dump_default=True, 

68 metadata={ 

69 "title": "Sinogram", 

70 "description": "Generate or not a sinogram during the scan", 

71 }, 

72 ) 

73 axis_displacement = fields.Int( 

74 dump_default=0, 

75 validate=validate.Range(min=-300, max=300), 

76 metadata={ 

77 "title": "Axis displacement", 

78 "unit": "%", 

79 "description": "0% = centered, 100% = half detector width", 

80 }, 

81 ) 

82 comment = fields.Str( 

83 dump_default="", 

84 metadata={ 

85 "title": "Comment", 

86 }, 

87 ) 

88 enqueue = fields.Bool( 

89 dump_default=True, 

90 metadata={ 

91 "title": "Queue Scan", 

92 }, 

93 ) 

94 

95 class Meta: 

96 uiorder = [ 

97 "sampleid", 

98 "dataset_name", 

99 "scan_type", 

100 "expo_time", 

101 "start_pos", 

102 "end_pos", 

103 "tomo_n", 

104 "use_sinogram", 

105 "n_dark", 

106 "n_flat", 

107 "axis_displacement", 

108 "comment", 

109 "enqueue", 

110 ] 

111 uigroups = [ 

112 { 

113 "Data policy": [ 

114 "sampleid", 

115 "dataset_name", 

116 ], 

117 "ui:minwidth": 12, 

118 }, 

119 "scan_type", 

120 { 

121 "Main": ["expo_time", "start_pos", "end_pos", "tomo_n"], 

122 "ui:minwidth": 12, 

123 }, 

124 { 

125 "Options": ["use_sinogram", "n_dark", "n_flat"], 

126 "ui:minwidth": 12, 

127 }, 

128 { 

129 "Half acquisition": ["axis_displacement"], 

130 "ui:minwidth": 12, 

131 }, 

132 "comment", 

133 "enqueue", 

134 ] 

135 uischema = { 

136 "sampleid": {"ui:widget": "SampleId"}, 

137 "dataset_name": {"ui:widget": "DatasetName"}, 

138 "comment": {"ui:widget": "textarea", "ui:options": {"rows": 3}}, 

139 "enqueue": {"classNames": "hidden-row", "ui:widget": "hidden"}, 

140 } 

141 

142 @tomo_helper.patch_actor_validator 

143 def calculated(self, expo_time: float | None = None, **kwargs): 

144 """Returns the calculated values 

145 

146 Arguments: 

147 data: Dictionary containing the actual parameters of the form 

148 """ 

149 result = {} 

150 

151 if expo_time is None: 

152 # Trick to feed the initial expo time based on the tomo imaging device 

153 tomo_config = tomo_helper.get_active_tomo_config() 

154 if tomo_config is None: 

155 raise RuntimeError("No ACTIVE_TOMOCONFIG selected") 

156 imaging = tomo_config.tomo_imaging 

157 if imaging is not None: 

158 result["expo_time"] = imaging.exposure_time 

159 else: 

160 result["expo_time"] = 1.0 

161 

162 return result 

163 

164 

165class FullfieldscanActor(ComponentActor): 

166 schema = FullfieldscanSchema 

167 name = "[tomo] full tomo scan" 

168 

169 metatype = "tomo" 

170 saving_args = {"dataset": "{dataset_name}"} 

171 

172 def method( 

173 self, 

174 scan_type: str, 

175 dataset_name: str, 

176 start_pos: float, 

177 end_pos: float, 

178 tomo_n: int, 

179 expo_time: float, 

180 use_sinogram: bool, 

181 n_dark: int, 

182 n_flat: int, 

183 axis_displacement: float, 

184 comment: str, 

185 before_scan_starts, 

186 update_datacollection, 

187 **kwargs, 

188 ): 

189 if len(kwargs): 

190 print("Unused params", kwargs) 

191 

192 tomo_config = tomo_helper.get_active_tomo_config() 

193 if tomo_config is None: 

194 raise RuntimeError("No ACTIVE_TOMOCONFIG selected") 

195 

196 actor_config = self.get_config() 

197 fullfield_object_names = actor_config.get("fullfield_object") 

198 if fullfield_object_names is None: 

199 raise RuntimeError( 

200 "'fullfield_name' config field was not setup in this samplescan actor description" 

201 ) 

202 

203 fulltomo = tomo_helper.get_sequence_from_name( 

204 tomo_config, fullfield_object_names, FullFieldTomo 

205 ) 

206 

207 mg = tomo_helper.create_mg(tomo_config) 

208 mg.set_active() 

209 

210 tomo_helper.setup_main_pars( 

211 fulltomo, 

212 scan_type=scan_type, 

213 use_sinogram=use_sinogram, 

214 n_dark=n_dark, 

215 n_flat=n_flat, 

216 axis_displacement=axis_displacement, 

217 comment=comment, 

218 ) 

219 

220 scan_info = tomo_helper.create_daiquiri_scan_info( 

221 self, share_data_collection=True 

222 ) 

223 

224 before_scan_starts(self) 

225 

226 def run(): 

227 fulltomo.basic_scan( 

228 start_pos, end_pos, tomo_n, expo_time, scan_info=scan_info 

229 ) 

230 

231 greenlet = gevent.spawn(run) 

232 try: 

233 greenlet.join() 

234 except ComponentActorKilled: 

235 greenlet.kill() 

236 raise 

237 

238 greenlet.get()