Coverage for /Users/Newville/Codes/xraylarch/larch/wxmap/maptomopanel.py: 17%

380 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-09 10:08 -0600

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 ..io import nativepath 

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

44 

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

46 

47 

48CEN = wx.ALIGN_CENTER 

49LEFT = wx.ALIGN_LEFT 

50RIGHT = wx.ALIGN_RIGHT 

51ALL_CEN = wx.ALL|CEN 

52ALL_LEFT = wx.ALL|LEFT 

53ALL_RIGHT = wx.ALL|RIGHT 

54 

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

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

57CONTRAST_CHOICES = ('None', 

58 '0.01', '0.02', '0.05', 

59 '0.1', '0.2', '0.5', 

60 '1', '2', '5') 

61 

62CWID = 150 

63WWID = 100 + CWID*4 

64 

65class TomographyPanel(GridPanel): 

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

67 label = 'Tomography Tools' 

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

69 

70 self.owner = owner 

71 self.cfile,self.xrmmap = None,None 

72 self.npts = None 

73 self.resave = False 

74 

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

76 

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

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

79 

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

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

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

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

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

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

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

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

88 

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

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

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

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

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

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

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

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

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

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

99 

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

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

102 

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

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

105 

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

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

108 

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

110 SimpleText(self,''), 

111 SimpleText(self,''), 

112 SimpleText(self,'Normalization')] 

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

114 SimpleText(self,''), 

115 SimpleText(self,''), 

116 SimpleText(self,'')] 

117 

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

119 label='Correct for Detector Deadtime', 

120 action=self.onDTCorrect) 

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

122 label='Remove First and Last columns', 

123 action=self.onHotCols) 

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

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

126 

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

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

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

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

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

132 action=self.onShowCentering)] 

133 

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

135 action=self.onALGchoice) 

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

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

138 size=(CWID, -1), 

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

140 

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

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

143 self.center_value.SetIncrement(0.25) 

144 self.center_value.SetDigits(2) 

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

146 self.refine_center.SetValue(False) 

147 

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

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

150 action=self.onSaveTomograph) 

151 

152 

153 ################################################################################# 

154 

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

156 style=LEFT, newrow=True) 

157 

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

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

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

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

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

163 

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

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

166 style=LEFT, newrow=True) 

167 

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

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

170 style=LEFT, newrow=True) 

171 

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

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

174 style=LEFT, newrow=True) 

175 

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

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

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

179 

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

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

182 newrow=True) 

183 

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

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

186 newrow=True) 

187 

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

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

190 newrow=True) 

191 

192 

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

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

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

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

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

198 

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

200 

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

202 

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

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

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

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

207 

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

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

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

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

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

213 

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

215 

216 

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

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

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

220 

221 ################################################################################# 

222 self.pack() 

223 

224 def onDTCorrect(self, event=None): 

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

226 

227 def onHotCols(self, event=None): 

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

229 

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

231 

232 if xrmfile is None: 

233 xrmfile = self.owner.current_file 

234 

235 self.cfile = xrmfile 

236 self.xrmmap = self.cfile.xrmmap 

237 

238 

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

240 self.center_value.SetValue(0) 

241 return 

242 

243 self.set_det_choices() 

244 

245 try: 

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

247 except: 

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

249 

250 center = self.cfile.get_tomography_center() 

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

252 self.center_value.SetValue(center) 

253 

254 self.plotSELECT() 

255 

256 

257 def onALGchoice(self,event=None): 

258 

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

260 enable_filter = False 

261 enable_niter = False 

262 

263 if alg.startswith('gridrec'): 

264 enable_filter = True 

265 else: 

266 enable_niter = True 

267 

268 self.tomo_niter.Enable(enable_niter) 

269 self.tomo_filt.Enable(enable_filter) 

270 

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

272 self.set_roi_choices(idet=idet) 

273 

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

275 if iroi > 2: 

276 return 

277 try: 

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

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

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

281 except: 

282 return 

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

284 contrast = 0.0 

285 contrast = float(contrast) 

286 try: 

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

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

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

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

291 except: 

292 pass 

293 

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

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

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

297 try: 

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

299 except: 

300 contrast = 0.0 

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

302 contrast = 0.0 

303 contrast = float(contrast) 

304 

305 

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

307 try: 

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

309 limits = roi['limits'][:] 

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

311 if units == '1/A': 

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

313 else: 

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

315 except: 

316 roistr = '' 

317 try: 

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

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

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

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

322 except: 

323 pass 

324 else: 

325 try: 

326 roi = self.cfile.xrmmap[detname] 

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

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

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

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

331 except: 

332 roistr = '' 

333 

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

335 

336 def plotSELECT(self,event=None): 

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

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

339 if 'single' in plot_type: 

340 for i in (1,2): 

341 self.det_choice[i].Disable() 

342 self.roi_choice[i].Disable() 

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

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

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

346 elif 'three' in plot_type: 

347 for i in (1,2): 

348 self.det_choice[i].Enable() 

349 self.roi_choice[i].Enable() 

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

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

352 self.set_roi_choices() 

353 

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

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

356 ny, nx = xrmfile.get_shape() 

357 indices = [] 

358 for idx in selected: 

359 iy, ix = divmod(idx, ny) 

360 indices.append((ix, iy)) 

361 

362 

363 def onClose(self): 

364 for p in self.plotframes: 

365 try: 

366 p.Destroy() 

367 except: 

368 pass 

369 

370 def calculateSinogram(self,xrmfile=None): 

371 ''' 

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

373 ''' 

374 subtitles = None 

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

376 

377 det_name = ['mcasum']*4 

378 roi_name = ['']*4 

379 plt_name = ['']*4 

380 minvals = [0]*4 

381 maxvals = [np.inf]*4 

382 for i in range(4): 

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

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

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

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

387 else: 

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

389 if i < 3: 

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

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

392 

393 if plt3: 

394 flagxrd = False 

395 for det in det_name: 

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

397 else: 

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

399 

400 if xrmfile is None: 

401 xrmfile = self.owner.current_file 

402 

403 args={'trim_sino' : flagxrd, 

404 'hotcols' : False, 

405 'dtcorrect' : self.owner.dtcor} 

406 

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

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

409 

410 if omega is None: 

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

412 return 

413 

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

415 # remove the first and last: 

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

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

418 # if not args['hotcols']:  

419 # omega = omega[1:-1] 

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

421 # args['hotcols'] = True 

422 

423 def normalize_map(xmap, normmap, roiname): 

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

425 xmap = xmap/(1.00*normmap) 

426 label = '' 

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

428 xmap = -np.log(xmap) 

429 label = '-log' 

430 elif isinstance(normmap, np.ndarray): 

431 xmap *= normmap.mean() 

432 return xmap, label 

433 

434 normmap = 1. 

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

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

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

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

439 

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

441 det=det_name[0], 

442 minval=minvals[0], 

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

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

445 if plt3: 

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

447 minval=minvals[1], 

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

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

450 minval=minvals[2], 

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

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

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

454 

455 

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

457 if plt3: 

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

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

460 title = fname 

461 info = '' 

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

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

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

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

466 else: 

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

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

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

470 

471 else: 

472 sino = r_map 

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

474 title = plt_name[0] 

475 else: 

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

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

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

479 subtitle = None 

480 

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

482 

483 def onSaveTomograph(self, event=None): 

484 

485 xrmfile = self.owner.current_file 

486 detpath = self.sino_data.GetStringSelection() 

487 center = self.center_value.GetValue() 

488 

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

490 detpath = '%s_raw' % detpath 

491 

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

493 

494 xrmfile.save_tomograph(detpath, 

495 algorithm=self.tomo_algo.GetStringSelection(), 

496 filter_name=self.tomo_filt.GetStringSelection(), 

497 num_iter=self.tomo_niter.GetValue(), 

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

499 hotcols=xrmfile.hotcols) 

500 print('Saved.') 

501 

502 def onShowCentering(self, event=None): 

503 xrmfile = self.owner.current_file 

504 det = None 

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

506 algorithm = self.tomo_algo.GetStringSelection() 

507 filter_name = self.tomo_filt.GetStringSelection() 

508 niter = self.tomo_niter.GetValue() 

509 center = self.center_value.GetValue() 

510 

511 omega = np.radians(omega) 

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

513 sinogram_order=sino_order, 

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

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

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

517 imin = img.min() - ioff 

518 imax = img.max() + ioff 

519 

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

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

522 for i, cen in enumerate(centers): 

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

524 imin=imin, imax=imax) 

525 scores[i] = score 

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

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

528 

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

530 xrmfile = self.owner.current_file 

531 det = None 

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

533 

534 algorithm = self.tomo_algo.GetStringSelection() 

535 filter_name = self.tomo_filt.GetStringSelection() 

536 niter = self.tomo_niter.GetValue() 

537 center = self.center_value.GetValue() 

538 refine_center = self.refine_center.GetValue() 

539 

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

541 algorithm=algorithm, 

542 filter_name=filter_name, num_iter=niter, 

543 center=center, omega=omega, 

544 sinogram_order=sino_order, 

545 hotcols=xrmfile.hotcols) 

546 

547 # sharpness estimates: 

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

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

550 else: 

551 t = tomo/tomo.max() 

552 

553 if refine_center: 

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

555 self.refine_center.SetValue(False) 

556 

557 omeoff, xoff = 0, 0 

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

559 

560 ## for one color plot 

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

562 sino = sino[0] 

563 tomo = tomo[0] 

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

565 

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

567 iframe = self.owner.add_tomodisplay(title) 

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

569 

570 def set_center(self,cen): 

571 self.center_value.SetValue(cen) 

572 self.cfile.set_tomography_center(center=cen) 

573 

574 def set_det_choices(self): 

575 det_list = self.cfile.get_detector_list() 

576 

577 for det_ch in self.det_choice: 

578 det_ch.SetChoices(det_list) 

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

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

581 

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

583 self.sino_data.SetChoices(data_list) 

584 

585 self.set_roi_choices() 

586 

587 def set_roi_choices(self, idet=None): 

588 

589 if idet is None: 

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

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

592 rois = self.update_roi(detname) 

593 

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

595 self.roiSELECT(idet) 

596 else: 

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

598 rois = self.update_roi(detname) 

599 

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

601 self.roiSELECT(idet) 

602 

603 

604 def update_roi(self, detname): 

605 return self.cfile.get_roi_list(detname)