Coverage for larch/wxmap/maptomopanel.py: 16%

378 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-10-16 21:04 +0000

1#!/usr/bin/env python 

2""" 

3GUI for displaying maps from HDF5 files 

4 

5""" 

6 

7VERSION = '10 (14-March-2018)' 

8 

9import os 

10import platform 

11import sys 

12import time 

13import json 

14import socket 

15import datetime 

16from functools import partial 

17from threading import Thread 

18 

19import wx 

20import wx.lib.scrolledpanel as scrolled 

21import wx.lib.mixins.inspection 

22try: 

23 from wx._core import PyDeadObjectError 

24except: 

25 PyDeadObjectError = Exception 

26 

27HAS_tomopy = False 

28try: 

29 import tomopy 

30 HAS_tomopy = True 

31except ImportError: 

32 pass 

33 

34import numpy as np 

35import scipy.stats as stats 

36from wxmplot import PlotFrame 

37from ..wxlib import (EditableListBox, SimpleText, 

38 FloatCtrl, Font, pack, Popup, Button, MenuItem, 

39 Choice, Check, GridPanel, FileSave, HLine) 

40from ..wxlib.plotter import _plot 

41from ..utils.strutils import bytes2str, version_ge 

42from ..math.tomography import TOMOPY_ALG, TOMOPY_FILT, center_score 

43 

44from ..xrmmap import GSEXRM_MapFile, GSEXRM_FileStatus, h5str, ensure_subgroup 

45 

46 

47CEN = wx.ALIGN_CENTER 

48LEFT = wx.ALIGN_LEFT 

49RIGHT = wx.ALIGN_RIGHT 

50ALL_CEN = wx.ALL|CEN 

51ALL_LEFT = wx.ALL|LEFT 

52ALL_RIGHT = wx.ALL|RIGHT 

53 

54PLOT_TYPES = ('Single ROI Map', 'Three ROI Map', 'Correlation Plot') 

55PLOT_OPERS = ('/', '*', '-', '+') 

56CONTRAST_CHOICES = ('None', 

57 '0.01', '0.02', '0.05', 

58 '0.1', '0.2', '0.5', 

59 '1', '2', '5') 

60 

61CWID = 150 

62WWID = 100 + CWID*4 

63 

64class TomographyPanel(GridPanel): 

65 '''Panel of Controls for reconstructing a tomographic slice''' 

66 label = 'Tomography Tools' 

67 def __init__(self, parent, owner=None, **kws): 

68 

69 self.owner = owner 

70 self.cfile,self.xrmmap = None,None 

71 self.npts = None 

72 self.resave = False 

73 

74 GridPanel.__init__(self, parent, nrows=8, ncols=6, **kws) 

75 

76 self.plot_choice = Choice(self, choices=PLOT_TYPES[:-1], size=(CWID, -1)) 

77 self.plot_choice.Bind(wx.EVT_CHOICE, self.plotSELECT) 

78 

79 self.det_choice = [Choice(self, size=(CWID, -1)), 

80 Choice(self, size=(CWID, -1)), 

81 Choice(self, size=(CWID, -1)), 

82 Choice(self, size=(CWID, -1))] 

83 self.roi_choice = [Choice(self, size=(CWID, -1)), 

84 Choice(self, size=(CWID, -1)), 

85 Choice(self, size=(CWID, -1)), 

86 Choice(self, size=(CWID, -1))] 

87 

88 fopts = dict(minval=0, precision=2, size=(110, -1)) 

89 self.iminvals = [FloatCtrl(self, value=0, **fopts), 

90 FloatCtrl(self, value=0, **fopts), 

91 FloatCtrl(self, value=0, **fopts)] 

92 self.imaxvals = [FloatCtrl(self, value=0, **fopts), 

93 FloatCtrl(self, value=0, **fopts), 

94 FloatCtrl(self, value=0, **fopts)] 

95 self.icontrast = [Choice(self, choices=CONTRAST_CHOICES, default=4, size=(CWID, -1)), 

96 Choice(self, choices=CONTRAST_CHOICES, default=4, size=(CWID, -1)), 

97 Choice(self, choices=CONTRAST_CHOICES, default=4, size=(CWID, -1))] 

98 

99 for i, d in enumerate(self.icontrast): 

100 d.Bind(wx.EVT_CHOICE, partial(self.roiContrast, i)) 

101 

102 for i,det_chc in enumerate(self.det_choice): 

103 det_chc.Bind(wx.EVT_CHOICE, partial(self.detSELECT,i)) 

104 

105 for i,roi_chc in enumerate(self.roi_choice): 

106 roi_chc.Bind(wx.EVT_CHOICE, partial(self.roiSELECT,i)) 

107 

108 self.det_label = [SimpleText(self,'Intensity'), 

109 SimpleText(self,''), 

110 SimpleText(self,''), 

111 SimpleText(self,'Normalization')] 

112 self.roi_label = [SimpleText(self,''), 

113 SimpleText(self,''), 

114 SimpleText(self,''), 

115 SimpleText(self,'')] 

116 

117 self.use_dtcorr = Check(self, default=True, 

118 label='Correct for Detector Deadtime', 

119 action=self.onDTCorrect) 

120 self.use_hotcols = Check(self, default=False, 

121 label='Remove First and Last columns', 

122 action=self.onHotCols) 

123 self.i1trans = Check(self, default=True, 

124 label='Scalar "i1" is transmission data') 

125 

126 self.tomo_show = [Button(self, 'Show New Map', size=(CWID, -1), 

127 action=partial(self.onShowTomograph, new=True)), 

128 Button(self, 'Replace Last Map', size=(CWID, -1), 

129 action=partial(self.onShowTomograph, new=False)), 

130 Button(self, 'Show Centering Data', size=(CWID, -1), 

131 action=self.onShowCentering)] 

132 

133 self.tomo_algo = Choice(self, choices=TOMOPY_ALG, size=(CWID, -1), 

134 action=self.onALGchoice) 

135 self.tomo_filt = Choice(self, choices=TOMOPY_FILT, size=(CWID, -1)) 

136 self.tomo_niter = wx.SpinCtrl(self, min=1, max=500, initial=1, 

137 size=(CWID, -1), 

138 style=wx.SP_VERTICAL|wx.SP_ARROW_KEYS|wx.SP_WRAP) 

139 

140 self.center_value = wx.SpinCtrlDouble(self, inc=0.25, size=(100, -1), 

141 style=wx.SP_VERTICAL|wx.SP_ARROW_KEYS|wx.SP_WRAP) 

142 self.center_value.SetIncrement(0.25) 

143 self.center_value.SetDigits(2) 

144 self.refine_center = wx.CheckBox(self, label='Refine') 

145 self.refine_center.SetValue(False) 

146 

147 self.sino_data = Choice(self, size=(200, -1)) 

148 self.tomo_save = Button(self, 'Save reconstruction', size=(150, -1), 

149 action=self.onSaveTomograph) 

150 

151 

152 ################################################################################# 

153 

154 self.Add(SimpleText(self, 'Display Virtual Slices: Plot Type:'), dcol=2, 

155 style=LEFT, newrow=True) 

156 

157 self.Add(self.plot_choice, dcol=1, style=LEFT) 

158 self.Add(self.i1trans, dcol=2, style=LEFT) 

159 self.Add(SimpleText(self,'Options:'), dcol=1, style=LEFT, newrow=True) 

160 self.Add(self.use_dtcorr, dcol=2, style=LEFT) 

161 self.Add(self.use_hotcols, dcol=2, style=LEFT) 

162 

163 self.AddMany((SimpleText(self,''), self.det_label[0], 

164 self.det_label[1], self.det_label[2], self.det_label[3]), 

165 style=LEFT, newrow=True) 

166 

167 self.AddMany((SimpleText(self,'Detector:'), self.det_choice[0], 

168 self.det_choice[1], self.det_choice[2], self.det_choice[3]), 

169 style=LEFT, newrow=True) 

170 

171 self.AddMany((SimpleText(self,'ROI:'), self.roi_choice[0], 

172 self.roi_choice[1], self.roi_choice[2], self.roi_choice[3]), 

173 style=LEFT, newrow=True) 

174 

175 self.AddMany((SimpleText(self,''), self.roi_label[0], 

176 self.roi_label[1], self.roi_label[2], 

177 self.roi_label[3]), style=LEFT, newrow=True) 

178 

179 self.AddMany((SimpleText(self,'I Min:'), self.iminvals[0], 

180 self.iminvals[1], self.iminvals[2]), style=LEFT, 

181 newrow=True) 

182 

183 self.AddMany((SimpleText(self,'I Max:'), self.imaxvals[0], 

184 self.imaxvals[1], self.imaxvals[2]), style=LEFT, 

185 newrow=True) 

186 

187 self.AddMany((SimpleText(self,'I contrast %:'), self.icontrast[0], 

188 self.icontrast[1], self.icontrast[2]), style=LEFT, 

189 newrow=True) 

190 

191 

192 self.Add((5, 5), dcol=1, style=LEFT, newrow=True) 

193 self.Add((5, 5), dcol=1, style=LEFT, newrow=True) 

194 self.Add(self.tomo_show[0], dcol=1, style=LEFT) 

195 self.Add(self.tomo_show[1], dcol=1, style=LEFT) 

196 self.Add(self.tomo_show[2], dcol=1, style=LEFT) 

197 

198 self.Add(HLine(self, size=(WWID, 5)), dcol=8, style=LEFT, newrow=True) 

199 

200 self.Add(SimpleText(self,'Reconstruction '), dcol=2, style=LEFT, newrow=True) 

201 

202 self.Add(SimpleText(self,'Algorithm:'), dcol=1, style=LEFT, newrow=True) 

203 self.Add(self.tomo_algo, dcol=1, style=LEFT) 

204 self.Add(SimpleText(self,'Filter: '), dcol=1, style=LEFT) 

205 self.Add(self.tomo_filt, dcol=1, style=LEFT) 

206 

207 self.Add(SimpleText(self,'# Iterations'), dcol=1, style=LEFT, newrow=True) 

208 self.Add(self.tomo_niter, dcol=1, style=LEFT) 

209 self.Add(SimpleText(self,'Center Pixel:'), dcol=1, style=LEFT) 

210 self.Add(self.center_value, dcol=1, style=LEFT) 

211 self.Add(self.refine_center, dcol=1, style=LEFT) 

212 

213 self.Add(HLine(self, size=(WWID, 5)), dcol=8, style=LEFT, newrow=True) 

214 

215 

216 self.Add(SimpleText(self,'Data:'), dcol=1, style=LEFT, newrow=True) 

217 self.Add(self.sino_data, dcol=2, style=LEFT) 

218 self.Add(self.tomo_save, dcol=2, style=LEFT) 

219 

220 ################################################################################# 

221 self.pack() 

222 

223 def onDTCorrect(self, event=None): 

224 self.owner.current_file.dtcorrect = self.use_dtcorr.IsChecked() 

225 

226 def onHotCols(self, event=None): 

227 self.owner.current_file.hotcols = self.use_hotcols.IsChecked() 

228 

229 def update_xrmmap(self, xrmfile=None, set_detectors=None): 

230 

231 if xrmfile is None: 

232 xrmfile = self.owner.current_file 

233 

234 self.cfile = xrmfile 

235 self.xrmmap = self.cfile.xrmmap 

236 

237 

238 if self.cfile.get_rotation_axis() is None: 

239 self.center_value.SetValue(0) 

240 return 

241 

242 self.set_det_choices() 

243 

244 try: 

245 self.npts = len(self.cfile.get_pos(0, mean=True)) 

246 except: 

247 self.npts = len(self.cfile.get_pos('x', mean=True)) 

248 

249 center = self.cfile.get_tomography_center() 

250 self.center_value.SetRange(-0.5*self.npts,1.5*self.npts) 

251 self.center_value.SetValue(center) 

252 

253 self.plotSELECT() 

254 

255 

256 def onALGchoice(self,event=None): 

257 

258 alg = self.tomo_algo.GetStringSelection().lower() 

259 enable_filter = False 

260 enable_niter = False 

261 

262 if alg.startswith('gridrec'): 

263 enable_filter = True 

264 else: 

265 enable_niter = True 

266 

267 self.tomo_niter.Enable(enable_niter) 

268 self.tomo_filt.Enable(enable_filter) 

269 

270 def detSELECT(self, idet, event=None): 

271 self.set_roi_choices(idet=idet) 

272 

273 def roiContrast(self, iroi, event=None): 

274 if iroi > 2: 

275 return 

276 try: 

277 detname = self.det_choice[iroi].GetStringSelection() 

278 roiname = self.roi_choice[iroi].GetStringSelection() 

279 contrast = self.icontrast[iroi].GetStringSelection() 

280 except: 

281 return 

282 if contrast in ('None', None): 

283 contrast = 0.0 

284 contrast = float(contrast) 

285 try: 

286 map = self.cfile.get_roimap(roiname, det=detname) 

287 imin, imax = np.percentile(map, (contrast, 100.0-contrast)) 

288 self.iminvals[iroi].SetValue(imin) 

289 self.imaxvals[iroi].SetValue(imax) 

290 except: 

291 pass 

292 

293 def roiSELECT(self, iroi, event=None): 

294 detname = self.det_choice[iroi].GetStringSelection() 

295 roiname = self.roi_choice[iroi].GetStringSelection() 

296 try: 

297 contrast = self.icontrast[iroi].GetStringSelection() 

298 except: 

299 contrast = 0.0 

300 if contrast in ('None', None): 

301 contrast = 0.0 

302 contrast = float(contrast) 

303 

304 

305 if version_ge(self.cfile.version, '2.0.0'): 

306 try: 

307 roi = self.cfile.xrmmap['roimap'][detname][roiname] 

308 limits = roi['limits'][:] 

309 units = bytes2str(roi['limits'].attrs.get('units','')) 

310 if units == '1/A': 

311 roistr = '[%0.2f to %0.2f %s]' % (limits[0],limits[1],units) 

312 else: 

313 roistr = '[%0.1f to %0.1f %s]' % (limits[0],limits[1],units) 

314 except: 

315 roistr = '' 

316 try: 

317 map = self.cfile.get_roimap(roiname, det=detname) 

318 imin, imax = np.percentile(map, (contrast, 100.0-contrast)) 

319 self.iminvals[iroi].SetValue(imin) 

320 self.imaxvals[iroi].SetValue(imax) 

321 except: 

322 pass 

323 else: 

324 try: 

325 roi = self.cfile.xrmmap[detname] 

326 en = list(roi['energy'][:]) 

327 index = list(roi['roi_name'][:]).index(roiname) 

328 limits = list(roi['roi_limits'][:][index]) 

329 roistr = '[%0.1f to %0.1f keV]' % (en[limits[0]],en[limits[1]]) 

330 except: 

331 roistr = '' 

332 

333 self.roi_label[iroi].SetLabel(roistr) 

334 

335 def plotSELECT(self,event=None): 

336 if len(self.owner.filemap) > 0: 

337 plot_type = self.plot_choice.GetStringSelection().lower() 

338 if 'single' in plot_type: 

339 for i in (1,2): 

340 self.det_choice[i].Disable() 

341 self.roi_choice[i].Disable() 

342 self.roi_label[i].SetLabel('') 

343 for i,label in enumerate(['Intensity', ' ', ' ']): 

344 self.det_label[i].SetLabel(label) 

345 elif 'three' in plot_type: 

346 for i in (1,2): 

347 self.det_choice[i].Enable() 

348 self.roi_choice[i].Enable() 

349 for i,label in enumerate(['Red', 'Green', 'Blue']): 

350 self.det_label[i].SetLabel(label) 

351 self.set_roi_choices() 

352 

353 def onLasso(self, selected=None, mask=None, data=None, xrmfile=None, **kws): 

354 if xrmfile is None: xrmfile = self.owner.current_file 

355 ny, nx = xrmfile.get_shape() 

356 indices = [] 

357 for idx in selected: 

358 iy, ix = divmod(idx, ny) 

359 indices.append((ix, iy)) 

360 

361 

362 def onClose(self): 

363 for p in self.plotframes: 

364 try: 

365 p.Destroy() 

366 except: 

367 pass 

368 

369 def calculateSinogram(self,xrmfile=None): 

370 ''' 

371 returns slice as [slices, x, 2th] 

372 ''' 

373 subtitles = None 

374 plt3 = 'three' in self.plot_choice.GetStringSelection().lower() 

375 

376 det_name = ['mcasum']*4 

377 roi_name = ['']*4 

378 plt_name = ['']*4 

379 minvals = [0]*4 

380 maxvals = [np.inf]*4 

381 for i in range(4): 

382 det_name[i] = self.det_choice[i].GetStringSelection() 

383 roi_name[i] = self.roi_choice[i].GetStringSelection() 

384 if det_name[i] == 'scalars': 

385 plt_name[i] = '%s' % roi_name[i] 

386 else: 

387 plt_name[i] = '%s(%s)' % (roi_name[i],det_name[i]) 

388 if i < 3: 

389 minvals[i] = self.iminvals[i].GetValue() 

390 maxvals[i] = self.imaxvals[i].GetValue() 

391 

392 if plt3: 

393 flagxrd = False 

394 for det in det_name: 

395 if det.startswith('xrd'): flagxrd = True 

396 else: 

397 flagxrd = True if det_name[0].startswith('xrd') else False 

398 

399 if xrmfile is None: 

400 xrmfile = self.owner.current_file 

401 

402 args={'trim_sino' : flagxrd, 

403 'hotcols' : False, 

404 'dtcorrect' : self.owner.dtcor} 

405 

406 x = xrmfile.get_translation_axis(hotcols=args['hotcols']) 

407 omega = xrmfile.get_rotation_axis(hotcols=args['hotcols']) 

408 

409 if omega is None: 

410 print('\n** Cannot compute tomography: no rotation axis specified in map. **') 

411 return 

412 

413 # check for common case of a few too many angles -- in which case, always 

414 # remove the first and last: 

415 domega = abs(np.diff(omega).mean()) 

416 # if abs(omega[-1] - omega[0]) > 360+2*domega: 

417 # if not args['hotcols']: 

418 # omega = omega[1:-1] 

419 # print("TRIMMED OMEGA ", domega, omega.shape) 

420 # args['hotcols'] = True 

421 

422 def normalize_map(xmap, normmap, roiname): 

423 # print("normalize_map ", xmap.shape, xmap.dtype, normmap.shape, normmap.dtype) 

424 xmap = xmap/(1.00*normmap) 

425 label = '' 

426 if self.i1trans.IsChecked() and roiname.lower().startswith('i1'): 

427 xmap = -np.log(xmap) 

428 label = '-log' 

429 elif isinstance(normmap, np.ndarray): 

430 xmap *= normmap.mean() 

431 return xmap, label 

432 

433 normmap = 1. 

434 if roi_name[-1] != '1': 

435 normmap, sino_order = xrmfile.get_sinogram(roi_name[-1], 

436 det=det_name[-1], **args) 

437 normmap[np.where(normmap==0)] = 1. 

438 

439 r_map, sino_order = xrmfile.get_sinogram(roi_name[0], 

440 det=det_name[0], 

441 minval=minvals[0], 

442 maxval=maxvals[0], **args) 

443 r_map, r_lab = normalize_map(r_map, normmap, roi_name[0]) 

444 if plt3: 

445 g_map, sino_order = xrmfile.get_sinogram(roi_name[1], det=det_name[1], 

446 minval=minvals[1], 

447 maxval=maxvals[1], **args) 

448 b_map, sino_order = xrmfile.get_sinogram(roi_name[2], det=det_name[2], 

449 minval=minvals[2], 

450 maxval=maxvals[2], **args) 

451 g_map, g_lab = normalize_map(g_map, normmap, roi_name[1]) 

452 b_map, b_lab = normalize_map(b_map, normmap, roi_name[2]) 

453 

454 

455 pref, fname = os.path.split(xrmfile.filename) 

456 if plt3: 

457 sino = np.array([r_map, g_map, b_map]) 

458 sino.resize(tuple(i for i in sino.shape if i!=1)) 

459 title = fname 

460 info = '' 

461 if roi_name[-1] == '1': 

462 subtitles = {'red': 'Red: %s' % plt_name[0], 

463 'green': 'Green: %s' % plt_name[1], 

464 'blue': 'Blue: %s' % plt_name[2]} 

465 else: 

466 subtitles = {'red': 'Red: %s(%s/%s)' % (r_lab, plt_name[0], plt_name[-1]), 

467 'green': 'Green: %s(%s/%s)' % (g_lab, plt_name[1], plt_name[-1]), 

468 'blue': 'Blue: %s(%s/%s)' % (b_lab, plt_name[2], plt_name[-1])} 

469 

470 else: 

471 sino = r_map 

472 if roi_name[-1] == '1': 

473 title = plt_name[0] 

474 else: 

475 title = '%s(%s/%s)' % (r_lab, plt_name[0] , plt_name[-1]) 

476 title = '%s: %s' % (fname, title) 

477 info = 'Intensity: [%g, %g]' %(sino.min(), sino.max()) 

478 subtitle = None 

479 

480 return title, subtitles, info, x, omega, sino_order, sino 

481 

482 def onSaveTomograph(self, event=None): 

483 

484 xrmfile = self.owner.current_file 

485 detpath = self.sino_data.GetStringSelection() 

486 center = self.center_value.GetValue() 

487 

488 if not self.owner.dtcor and 'scalars' in detpath: 

489 detpath = '%s_raw' % detpath 

490 

491 print('\nSaving tomographic reconstruction for %s ...' % detpath) 

492 

493 xrmfile.save_tomograph(detpath, 

494 algorithm=self.tomo_algo.GetStringSelection(), 

495 filter_name=self.tomo_filt.GetStringSelection(), 

496 num_iter=self.tomo_niter.GetValue(), 

497 center=center, dtcorrect=self.owner.dtcor, 

498 hotcols=xrmfile.hotcols) 

499 print('Saved.') 

500 

501 def onShowCentering(self, event=None): 

502 xrmfile = self.owner.current_file 

503 det = None 

504 title, subtitles, info, x, omega, sino_order, sino = self.calculateSinogram() 

505 algorithm = self.tomo_algo.GetStringSelection() 

506 filter_name = self.tomo_filt.GetStringSelection() 

507 niter = self.tomo_niter.GetValue() 

508 center = self.center_value.GetValue() 

509 

510 omega = np.radians(omega) 

511 img = tomopy.recon(sino, omega, center, 

512 sinogram_order=sino_order, 

513 algorithm='gridrec', filter_name='shepp') 

514 img = tomopy.circ_mask(img, axis=0) 

515 ioff = (img.max() - img.min())/25.0 

516 imin = img.min() - ioff 

517 imax = img.max() + ioff 

518 

519 centers = int(center) + np.linspace(-10, 10, 81) 

520 scores = np.zeros(len(centers)) 

521 for i, cen in enumerate(centers): 

522 score = center_score(cen, sino, omega, sinogram_order=sino_order, 

523 imin=imin, imax=imax) 

524 scores[i] = score 

525 _plot(centers, scores, xlabel='Center(pixels)', ylabel='Blurriness', 

526 new=True, markersize=4, marker='o', title='Image Blurriness Score') 

527 

528 def onShowTomograph(self, event=None, new=True): 

529 xrmfile = self.owner.current_file 

530 det = None 

531 title, subtitles, info, x, omega, sino_order, sino = self.calculateSinogram() 

532 

533 algorithm = self.tomo_algo.GetStringSelection() 

534 filter_name = self.tomo_filt.GetStringSelection() 

535 niter = self.tomo_niter.GetValue() 

536 center = self.center_value.GetValue() 

537 refine_center = self.refine_center.GetValue() 

538 

539 tomo = xrmfile.get_tomograph(sino, refine_center=refine_center, 

540 algorithm=algorithm, 

541 filter_name=filter_name, num_iter=niter, 

542 center=center, omega=omega, 

543 sinogram_order=sino_order, 

544 hotcols=xrmfile.hotcols) 

545 

546 # sharpness estimates: 

547 if len(tomo.shape) == 3: 

548 t = tomo.sum(axis=2)/tomo.max() 

549 else: 

550 t = tomo/tomo.max() 

551 

552 if refine_center: 

553 self.set_center(xrmfile.xrmmap['tomo/center'][()]) 

554 self.refine_center.SetValue(False) 

555 

556 omeoff, xoff = 0, 0 

557 title = '%s, center=%0.1f' % (title, center) 

558 

559 ## for one color plot 

560 if sino.shape[0] == 1 and tomo.shape[0] == 1: 

561 sino = sino[0] 

562 tomo = tomo[0] 

563 det = self.det_choice[0].GetStringSelection() 

564 

565 if len(self.owner.tomo_displays) == 0 or new: 

566 iframe = self.owner.add_tomodisplay(title) 

567 self.owner.display_tomo(tomo, title=title, subtitles=subtitles, det=det) 

568 

569 def set_center(self,cen): 

570 self.center_value.SetValue(cen) 

571 self.cfile.set_tomography_center(center=cen) 

572 

573 def set_det_choices(self): 

574 det_list = self.cfile.get_detector_list() 

575 

576 for det_ch in self.det_choice: 

577 det_ch.SetChoices(det_list) 

578 if 'scalars' in det_list: ## should set 'denominator' to scalars as default 

579 self.det_choice[-1].SetStringSelection('scalars') 

580 

581 data_list = self.cfile.get_datapath_list(remove='raw') 

582 self.sino_data.SetChoices(data_list) 

583 

584 self.set_roi_choices() 

585 

586 def set_roi_choices(self, idet=None): 

587 

588 if idet is None: 

589 for idet,det_ch in enumerate(self.det_choice): 

590 detname = self.det_choice[idet].GetStringSelection() 

591 rois = self.update_roi(detname) 

592 

593 self.roi_choice[idet].SetChoices(rois) 

594 self.roiSELECT(idet) 

595 else: 

596 detname = self.det_choice[idet].GetStringSelection() 

597 rois = self.update_roi(detname) 

598 

599 self.roi_choice[idet].SetChoices(rois) 

600 self.roiSELECT(idet) 

601 

602 

603 def update_roi(self, detname): 

604 return self.cfile.get_roi_list(detname)