PYME-extra 1.0.4.post0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. PYMEcs/Acquire/Actions/__init__.py +0 -0
  2. PYMEcs/Acquire/Actions/custom.py +167 -0
  3. PYMEcs/Acquire/Hardware/LPthreadedSimple.py +248 -0
  4. PYMEcs/Acquire/Hardware/LPthreadedSimpleSim.py +246 -0
  5. PYMEcs/Acquire/Hardware/NikonTiFlaskServer.py +45 -0
  6. PYMEcs/Acquire/Hardware/NikonTiFlaskServerT.py +59 -0
  7. PYMEcs/Acquire/Hardware/NikonTiRESTClient.py +73 -0
  8. PYMEcs/Acquire/Hardware/NikonTiSim.py +35 -0
  9. PYMEcs/Acquire/Hardware/__init__.py +0 -0
  10. PYMEcs/Acquire/Hardware/driftTrackGUI.py +329 -0
  11. PYMEcs/Acquire/Hardware/driftTrackGUI_n.py +472 -0
  12. PYMEcs/Acquire/Hardware/driftTracking.py +424 -0
  13. PYMEcs/Acquire/Hardware/driftTracking_n.py +433 -0
  14. PYMEcs/Acquire/Hardware/fakeCamX.py +15 -0
  15. PYMEcs/Acquire/Hardware/offsetPiezoRESTCorrelLog.py +38 -0
  16. PYMEcs/Acquire/__init__.py +0 -0
  17. PYMEcs/Analysis/MBMcollection.py +552 -0
  18. PYMEcs/Analysis/MINFLUX.py +280 -0
  19. PYMEcs/Analysis/MapUtils.py +77 -0
  20. PYMEcs/Analysis/NPC.py +1176 -0
  21. PYMEcs/Analysis/Paraflux.py +218 -0
  22. PYMEcs/Analysis/Simpler.py +81 -0
  23. PYMEcs/Analysis/Sofi.py +140 -0
  24. PYMEcs/Analysis/__init__.py +0 -0
  25. PYMEcs/Analysis/decSofi.py +211 -0
  26. PYMEcs/Analysis/eventProperties.py +50 -0
  27. PYMEcs/Analysis/fitDarkTimes.py +569 -0
  28. PYMEcs/Analysis/objectVolumes.py +20 -0
  29. PYMEcs/Analysis/offlineTracker.py +130 -0
  30. PYMEcs/Analysis/stackTracker.py +180 -0
  31. PYMEcs/Analysis/timeSeries.py +63 -0
  32. PYMEcs/Analysis/trackFiducials.py +186 -0
  33. PYMEcs/Analysis/zerocross.py +91 -0
  34. PYMEcs/IO/MINFLUX.py +851 -0
  35. PYMEcs/IO/NPC.py +117 -0
  36. PYMEcs/IO/__init__.py +0 -0
  37. PYMEcs/IO/darkTimes.py +19 -0
  38. PYMEcs/IO/picasso.py +219 -0
  39. PYMEcs/IO/tabular.py +11 -0
  40. PYMEcs/__init__.py +0 -0
  41. PYMEcs/experimental/CalcZfactor.py +51 -0
  42. PYMEcs/experimental/FRC.py +338 -0
  43. PYMEcs/experimental/ImageJROItools.py +49 -0
  44. PYMEcs/experimental/MINFLUX.py +1537 -0
  45. PYMEcs/experimental/NPCcalcLM.py +560 -0
  46. PYMEcs/experimental/Simpler.py +369 -0
  47. PYMEcs/experimental/Sofi.py +78 -0
  48. PYMEcs/experimental/__init__.py +0 -0
  49. PYMEcs/experimental/binEventProperty.py +187 -0
  50. PYMEcs/experimental/chaining.py +23 -0
  51. PYMEcs/experimental/clusterTrack.py +179 -0
  52. PYMEcs/experimental/combine_maps.py +104 -0
  53. PYMEcs/experimental/eventProcessing.py +93 -0
  54. PYMEcs/experimental/fiducials.py +323 -0
  55. PYMEcs/experimental/fiducialsNew.py +402 -0
  56. PYMEcs/experimental/mapTools.py +271 -0
  57. PYMEcs/experimental/meas2DplotDh5view.py +107 -0
  58. PYMEcs/experimental/mortensen.py +131 -0
  59. PYMEcs/experimental/ncsDenoise.py +158 -0
  60. PYMEcs/experimental/onTimes.py +295 -0
  61. PYMEcs/experimental/procPoints.py +77 -0
  62. PYMEcs/experimental/pyme2caml.py +73 -0
  63. PYMEcs/experimental/qPAINT.py +965 -0
  64. PYMEcs/experimental/randMap.py +188 -0
  65. PYMEcs/experimental/regExtraCmaps.py +11 -0
  66. PYMEcs/experimental/selectROIfilterTable.py +72 -0
  67. PYMEcs/experimental/showErrs.py +51 -0
  68. PYMEcs/experimental/showErrsDh5view.py +58 -0
  69. PYMEcs/experimental/showShiftMap.py +56 -0
  70. PYMEcs/experimental/snrEvents.py +188 -0
  71. PYMEcs/experimental/specLabeling.py +51 -0
  72. PYMEcs/experimental/splitRender.py +246 -0
  73. PYMEcs/experimental/testChannelByName.py +36 -0
  74. PYMEcs/experimental/timedSpecies.py +28 -0
  75. PYMEcs/experimental/utils.py +31 -0
  76. PYMEcs/misc/ExtraCmaps.py +177 -0
  77. PYMEcs/misc/__init__.py +0 -0
  78. PYMEcs/misc/configUtils.py +169 -0
  79. PYMEcs/misc/guiMsgBoxes.py +27 -0
  80. PYMEcs/misc/mapUtils.py +230 -0
  81. PYMEcs/misc/matplotlib.py +136 -0
  82. PYMEcs/misc/rectsFromSVG.py +182 -0
  83. PYMEcs/misc/shellutils.py +1110 -0
  84. PYMEcs/misc/utils.py +205 -0
  85. PYMEcs/misc/versionCheck.py +20 -0
  86. PYMEcs/misc/zcInfo.py +90 -0
  87. PYMEcs/pyme_warnings.py +4 -0
  88. PYMEcs/recipes/__init__.py +0 -0
  89. PYMEcs/recipes/base.py +75 -0
  90. PYMEcs/recipes/localisations.py +2380 -0
  91. PYMEcs/recipes/manipulate_yaml.py +83 -0
  92. PYMEcs/recipes/output.py +177 -0
  93. PYMEcs/recipes/processing.py +247 -0
  94. PYMEcs/recipes/simpler.py +290 -0
  95. PYMEcs/version.py +2 -0
  96. pyme_extra-1.0.4.post0.dist-info/METADATA +114 -0
  97. pyme_extra-1.0.4.post0.dist-info/RECORD +101 -0
  98. pyme_extra-1.0.4.post0.dist-info/WHEEL +5 -0
  99. pyme_extra-1.0.4.post0.dist-info/entry_points.txt +3 -0
  100. pyme_extra-1.0.4.post0.dist-info/licenses/LICENSE +674 -0
  101. pyme_extra-1.0.4.post0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,338 @@
1
+ import numpy as np
2
+ from scipy import signal
3
+ from scipy import stats
4
+ import wx
5
+ from PYMEcs.pyme_warnings import warn
6
+
7
+ ##################
8
+ # FRC.py
9
+ #
10
+ # Copyright Christian Soeller, 2018
11
+ # c.soeller@gmail.com
12
+ #
13
+ # This program is free software: you can redistribute it and/or modify
14
+ # it under the terms of the GNU General Public License as published by
15
+ # the Free Software Foundation, either version 3 of the License, or
16
+ # (at your option) any later version.
17
+ #
18
+ # This program is distributed in the hope that it will be useful,
19
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
+ # GNU General Public License for more details.
22
+ #
23
+ # You should have received a copy of the GNU General Public License
24
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
+ #
26
+ ##################
27
+
28
+ # in this implementation we follow the principles as coded in the Fiji FRC plugin coded by Alex Herbert
29
+ # the source code is at https://c4science.ch/source/ijp-frc/browse/master/src/main/java/ch/epfl/biop/frc/FRC.java
30
+ # it was crucial to have some implementation to look at since not all details of the FRC approach are made
31
+ # clear in the FRC papers, for example that the real part of F(i0)*conj(F(i1)) is being used (although it turns out
32
+ # that F(i0)*conj(F(i1)) should be real given the symmetry of the Fourier Transform of real valued function)
33
+
34
+ # also the use of a tukey window is reproduced (described already in the
35
+ # Nieuwenhuizen et al 2013 paper)
36
+
37
+ # the half-bit line formula was copied although
38
+ # it would be nice to figure out how the constants where arrived at
39
+ # Note there is some formula in the Nat Meth paper supplementary by
40
+ # Nieuwenhuizen et al 2013, but that is more general and we need to
41
+ # figure out if this one is a version of the general formula with
42
+ # specific parameter settings
43
+
44
+ def sigmaline(L):
45
+ thresh = (0.2071 * np.sqrt(L) + 1.9102) / (1.2071 * np.sqrt(L) + 0.9102)
46
+ return np.minimum(thresh,1)
47
+
48
+ def tukey2d(shape,fraction=0.5):
49
+ try:
50
+ from scipy.signal import tukey
51
+ except ImportError:
52
+ from scipy.signal.windows import tukey # from some version onwards only available from the scipy.signal.windows namespace
53
+
54
+ tx = tukey(shape[0],fraction)
55
+ ty = tukey(shape[1],fraction)
56
+
57
+ #tY, tX = np.meshgrid(ty,tx)
58
+ #return tY*tX
59
+
60
+ return np.outer(tx,ty)
61
+
62
+ def spectrum_mean_over_R(pspec,vszx,vszy,binwidth=None, debug = False):
63
+
64
+ # get size N and M of x and y dims
65
+ N, M = pspec.shape[0:2]
66
+
67
+ # set up spatial frequency coordinates in x and y [make sure we get the sequence of the two axes right]
68
+ # put on meshgrid and get muR from this
69
+ mux = (np.arange(N) - N/2)/float(N*vszx)
70
+ muy = (np.arange(M) - M/2)/float(M*vszy)
71
+
72
+ muY, muX = np.meshgrid(muy,mux)
73
+
74
+ if debug:
75
+ print(N,M)
76
+ print(muX.shape)
77
+
78
+ muR = np.sqrt(muX*muX+muY*muY)
79
+
80
+ # calculate bins using the specified binwidth (with suitable default)
81
+ # note that it makes sense to specify binwidth in multiples of dmu
82
+ # with minimum of 1*dmu (i.e. min of allowed binwidth is 1)
83
+ K = min(N,M)
84
+ mumult = max(int(binwidth),1)
85
+ bins = mumult*np.arange(K/2/mumult)/float(K*vszx) # there would be an issue if vszx ne vszy
86
+
87
+ # calculate binned_statistics over spectrum
88
+ # the spectrum must be realvalued, either powerspec or real/imaginary part
89
+ means, binedges, bnum = stats.binned_statistic(muR.ravel(),pspec.ravel(),statistic='sum', bins=bins)
90
+ # return bincenters and means for each bin
91
+ binctrs = 0.5*(binedges[1:]+binedges[:-1])
92
+ return (binctrs,means)
93
+
94
+ import statsmodels.api as sm
95
+ lowess = sm.nonparametric.lowess
96
+
97
+ def padsquare(image,newsize=None):
98
+ N, M = image.shape[0:2]
99
+ if newsize is None:
100
+ newsize = max(N,M)
101
+ K = newsize # less typing
102
+
103
+ if N != newsize or M != newsize:
104
+ if N>newsize or M>newsize:
105
+ raise RuntimeError('trying to embed image (%d,%d) into smaller container (%d,%d)' % (N,M,newsize,newsize))
106
+
107
+ newim = np.zeros((K,K))
108
+ # note that these divisions need to be integer divisons as we do index arithmetic
109
+ startn = (K-N) // 2
110
+ startm = (K-M) // 2
111
+ newim[startn:startn+N,startm:startm+M] = image
112
+ return newim
113
+ else:
114
+ return image
115
+
116
+ def frc(i0,i1,vszx,vszy,muwidth = 2, zeropad = False, lowessFraction = 1/20.0):
117
+
118
+ t2d = tukey2d(i0.shape,0.25)
119
+
120
+ if zeropad:
121
+ im0 = padsquare(i0*t2d)
122
+ im1 = padsquare(i1*t2d)
123
+ else:
124
+ im0 = i0*t2d
125
+ im1 = i1*t2d
126
+
127
+ I0 = np.fft.fftshift(np.fft.fftn(im0))
128
+ I1 = np.fft.fftshift(np.fft.fftn(im1))
129
+
130
+ CC = np.real(I0 * np.conj(I1))
131
+ PS0 = np.abs(I0)**2
132
+ PS1 = np.abs(I1)**2
133
+
134
+ bcc, mcc = spectrum_mean_over_R(CC,vszx,vszy,binwidth=muwidth)
135
+ b0, mi0 = spectrum_mean_over_R(PS0,vszx,vszy,binwidth=muwidth)
136
+ b1, mi1 = spectrum_mean_over_R(PS1,vszx,vszy,binwidth=muwidth)
137
+ # count the number of pixels contributing to each ring
138
+ b2, L = spectrum_mean_over_R(np.ones(PS1.shape),vszx,vszy,binwidth=muwidth)
139
+
140
+ # in principle should check that bcc, b0, b1 have the same bin locations
141
+ frcv = mcc/np.sqrt(mi0*mi1)
142
+
143
+ smoothed = lowess(frcv, bcc, frac=lowessFraction, it=3, delta=0.0,
144
+ is_sorted=False, missing='drop', return_sorted=False)
145
+
146
+ return (bcc,frcv,smoothed,L)
147
+
148
+ def frc_from_image(image,channels,muwidth=2,zeropad=True,lowessFraction=5.0*0.01):
149
+ im0 = image.data_xytc[:,:,:,channels[0]].squeeze()
150
+ im1 = image.data_xytc[:,:,:,channels[1]].squeeze()
151
+
152
+ mdh = image.mdh
153
+ vx = 1e3*mdh['voxelsize.x']
154
+ vy = 1e3*mdh['voxelsize.y']
155
+ freqs,frc1,smoothed,L = frc(im0,im1,vx,vy,muwidth=2,zeropad=True,
156
+ lowessFraction=lowessFraction)
157
+ halfbit = sigmaline(L)
158
+ fhb = zc.zerocross1d(freqs,smoothed-halfbit)
159
+ f7= zc.zerocross1d(freqs,smoothed-1.0/7.0)
160
+
161
+ return (freqs,frc1,smoothed,fhb,f7,halfbit)
162
+
163
+ def frc_plot(freqs,frc1,smoothed,fhb,f7,halfbit,chanNames=['block0','block1'],
164
+ showGrid=True,showHalfbitThreshold=False):
165
+ import matplotlib.pyplot as plt
166
+
167
+ from mpl_toolkits.axes_grid1 import host_subplot
168
+ import mpl_toolkits.axisartist as AA
169
+
170
+ plt.figure()
171
+ ax = host_subplot(111, axes_class=AA.Axes)
172
+ ax.plot(freqs,frc1)
173
+ ax.plot(freqs,smoothed)
174
+ if showHalfbitThreshold:
175
+ ax.plot(freqs,halfbit)
176
+ ax.plot(freqs,1/7.0*np.ones(freqs.shape))
177
+
178
+ if len(f7) > 0:
179
+ ax.plot([f7[0],f7[0]],[0,1],'--')
180
+ ax.text(0.55, 0.8,'res-1/7 = %3.1f nm' % (1.0/f7[0]),horizontalalignment='left',
181
+ verticalalignment='center', transform=plt.gca().transAxes)
182
+ else:
183
+ ax.text(0.55, 0.8,'res-1/7 - no intercept',horizontalalignment='left',
184
+ verticalalignment='center', transform=plt.gca().transAxes)
185
+
186
+ if showHalfbitThreshold:
187
+ if len(fhb) > 0:
188
+ ax.plot([fhb[0],fhb[0]],[0,1],'--')
189
+ ax.text(0.55, 0.9,'res-halfbit = %3.1f nm' % (1.0/fhb[0]),horizontalalignment='left',
190
+ verticalalignment='center', transform=plt.gca().transAxes)
191
+ else:
192
+ ax.text(0.55, 0.9,'res-halfbit - no intercept',horizontalalignment='left',
193
+ verticalalignment='center', transform=plt.gca().transAxes)
194
+
195
+ ax.plot(freqs,np.zeros(freqs.shape),'--')
196
+ ax.set_xlim(0,freqs[-1])
197
+ ax.set_xlabel('spatial frequency (nm^-1)')
198
+ ax.set_ylabel('FRC values')
199
+ xt = np.array([10., 15, 20, 30, 40, 50, 75, 150])
200
+ ft = 1.0 / xt
201
+
202
+ ax2 = ax.twin() # ax2 is responsible for "top" axis and "right" axis
203
+ ax2.set_xticks(ft[::-1])
204
+ ax2.set_xticklabels(['%d' % xi for xi in xt[::-1]],rotation=90)
205
+ ax2.set_xlabel('resolution (nm)')
206
+ if showGrid:
207
+ ax2.grid(True)
208
+
209
+ ax2.axis["right"].major_ticklabels.set_visible(False)
210
+ ax2.axis["top"].major_ticklabels.set_visible(True)
211
+
212
+ plt.title("FRC for channels %s and %s" % (chanNames[0],chanNames[1]), y=1.08)
213
+ plt.show()
214
+
215
+
216
+ def save_vol_mrc(data, grid_spacing, outfilename, origin=None, overwrite=False):
217
+ import mrcfile # will bomb unless this is installed
218
+
219
+ data = data.astype('float32')
220
+ with mrcfile.new(outfilename, overwrite=overwrite) as mrc:
221
+ mrc.set_data(data)
222
+ mrc.voxel_size = grid_spacing
223
+ if origin is not None:
224
+ mrc.header.origin = origin
225
+ mrc.update_header_from_data()
226
+ mrc.update_header_stats()
227
+
228
+ import PYMEcs.Analysis.zerocross as zc
229
+ from traits.api import HasTraits, Str, Int, CStr, List, Enum, Float, Bool
230
+
231
+ class FRCsettings(HasTraits):
232
+ ZeroPadding = Bool(True)
233
+ ShowHalfbitThreshold = Bool(False)
234
+ ShowGrid = Bool(True)
235
+ LowessSmoothingPercentage = Float(5.0)
236
+
237
+ class FRCplotter:
238
+ def __init__(self, dsviewer):
239
+ self.dsviewer = dsviewer
240
+ dsviewer.AddMenuItem('Experimental>Analysis', 'FRC of image pair', self.OnFRC)
241
+ dsviewer.AddMenuItem('Experimental>Analysis', 'save last FRC curves', self.OnFRCSave)
242
+ dsviewer.AddMenuItem('Experimental>Analysis', 'adjust FRC settings', self.OnFRCSettings)
243
+ dsviewer.AddMenuItem('Experimental>Analysis', 'save MRC volumes for FSC', self.OnFSCsave_as_MRC)
244
+
245
+ self.frcSettings = FRCsettings()
246
+ self.lastFRC = None
247
+
248
+ def OnFRCSettings(self, event=None):
249
+ if self.frcSettings.configure_traits(kind='modal'):
250
+ pass
251
+
252
+ def OnFRC(self, event=None):
253
+ from PYME.DSView.modules.coloc import ColocSettingsDialog
254
+ image = self.dsviewer.image
255
+ voxelsize = image.voxelsize
256
+
257
+ try:
258
+ names = image.mdh.getEntry('ChannelNames')
259
+ except:
260
+ names = ['Channel %d' % n for n in range(image.data_xytc.shape[3])]
261
+
262
+ with ColocSettingsDialog(self.dsviewer, voxelsize[0], names, show_bins=False) as dlg:
263
+ if dlg.ShowModal() != wx.ID_OK:
264
+ return
265
+ chans = dlg.GetChans()
266
+
267
+ chanNames = [names[chans[0]],names[chans[1]]]
268
+
269
+ freqs,frc1,smoothed,fhb,f7,halfbit = frc_from_image(image,chans,muwidth=2,
270
+ zeropad=self.frcSettings.ZeroPadding,
271
+ lowessFraction=self.frcSettings.LowessSmoothingPercentage*0.01)
272
+ frc_plot(freqs,frc1,smoothed,fhb,f7,halfbit,chanNames,
273
+ showHalfbitThreshold=self.frcSettings.ShowHalfbitThreshold,
274
+ showGrid=self.frcSettings.ShowGrid)
275
+
276
+ self.lastFRC = dict(frequencies=freqs,frc_curve=frc1,frc_smoothed=smoothed,frchbval=fhb,frcval=f7,frc_halfbit=halfbit)
277
+
278
+ def OnFRCSave(self, event=None):
279
+ if self.lastFRC is None:
280
+ warn("could not find data from prior FRC Plot; cannot scave, please plot first")
281
+ return
282
+ with wx.FileDialog(self.dsviewer, 'Save FRC data as ...',
283
+ wildcard='CSV (*.csv)|*.csv',
284
+ style=wx.FD_SAVE) as fdialog:
285
+ if fdialog.ShowModal() != wx.ID_OK:
286
+ return
287
+ else:
288
+ fpath = fdialog.GetPath()
289
+
290
+ lfrc = self.lastFRC
291
+ import pandas as pd
292
+ df = pd.DataFrame.from_dict(dict(freqs=lfrc['frequencies'],frc=lfrc['frc_curve'],frcsmooth=lfrc['frc_smoothed']))
293
+ df.to_csv(fpath,index=False)
294
+
295
+ def OnFSCsave_as_MRC(self, event=None):
296
+ from PYME.DSView.modules.coloc import ColocSettingsDialog
297
+ im = self.dsviewer.image
298
+ try:
299
+ names = im.mdh.getEntry('ChannelNames')
300
+ except:
301
+ names = ['Channel %d' % n for n in range(im.data_xyztc.shape[4])]
302
+
303
+ with ColocSettingsDialog(self.dsviewer, im.mdh.voxelsize.x, names, show_bins=False) as dlg:
304
+ if dlg.ShowModal() != wx.ID_OK:
305
+ return
306
+ chans = dlg.GetChans()
307
+
308
+ chanNames = [names[chans[0]],names[chans[1]]]
309
+
310
+ vol1 = im.data_xyztc[:,:,:,0,chans[0]].squeeze()
311
+ vol2 = im.data_xyztc[:,:,:,0,chans[1]].squeeze()
312
+
313
+ MINFLUXts = im.mdh.get('Source.MINFLUX.TimeStamp')
314
+ if MINFLUXts is not None:
315
+ defaultFiles = ["%s-%s.mrc" % (MINFLUXts,names[chans[0]]),
316
+ "%s-%s.mrc" % (MINFLUXts,names[chans[1]])]
317
+ else:
318
+ defaultFiles = ['','']
319
+
320
+ for i,vol in enumerate([vol1,vol2]):
321
+ with wx.FileDialog(self.dsviewer, 'Save channel %d as ...' % i,
322
+ wildcard='MRC (*.mrc)|*.mrc',
323
+ defaultFile=defaultFiles[i],
324
+ style=wx.FD_SAVE) as fdialog:
325
+ if fdialog.ShowModal() != wx.ID_OK:
326
+ return
327
+ fpath = fdialog.GetPath()
328
+ save_vol_mrc(vol.T,im.mdh.voxelsize_nm.x,fpath)
329
+
330
+ # we also write a JSON file of the metadata so that we can be sure about voxelsizes etc
331
+ # currently just the stem of the second MRC file name with json extension
332
+ from pathlib import Path
333
+ p = Path(fpath)
334
+ p.with_suffix('.json').write_text(im.mdh.to_JSON())
335
+
336
+ def Plug(dsviewer):
337
+ """Plugs this module into the gui"""
338
+ dsviewer.frcplt = FRCplotter(dsviewer)
@@ -0,0 +1,49 @@
1
+ import logging
2
+ logger = logging.getLogger(__file__)
3
+ import wx
4
+ import numpy as np
5
+ import roifile as rf # new dependency on roifile (available from pypi)
6
+ import skimage as ski
7
+
8
+ from PYME.DSView import ViewIm3D
9
+ from PYME.IO.image import ImageStack
10
+
11
+ class ImageJROItools:
12
+
13
+ def __init__(self, dsviewer):
14
+ self.dsviewer = dsviewer
15
+ dsviewer.AddMenuItem('Experimental>ROIs',
16
+ 'Generate ROI mask from Fiji ROISet',
17
+ self.OnROISet,
18
+ helpText='Load at FIJI ROISet (e.g. ROISet.zip) and construct a ROI mask from it')
19
+
20
+ def OnROISet(self, event=None):
21
+ roi_filename = wx.FileSelector('Load ROI set...',
22
+ wildcard="ROISet files (*.zip)|*.zip|ROI files (*.roi)|*.roi",
23
+ flags = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
24
+ rois = rf.ImagejRoi.fromfile(roi_filename)
25
+ roimask = np.zeros(self.dsviewer.image.data_xytc.shape[0:2],dtype='int')
26
+ roiszx,roiszy = roimask.shape
27
+ counter = 1
28
+ for roi in rois:
29
+ if roi.roitype in [rf.ROI_TYPE.RECT,
30
+ rf.ROI_TYPE.OVAL,
31
+ rf.ROI_TYPE.POLYGON,
32
+ rf.ROI_TYPE.FREEHAND]: # this needs to be relaxed pretty soonish!
33
+ coords = np.round(roi.coordinates()).astype('int')
34
+ r = coords[:,0]
35
+ c = coords[:,1]
36
+ rr, cc = ski.draw.polygon(r, c)
37
+ roimask[np.clip(cc,0,roiszx-1),np.clip(rr,0,roiszy-1)] = counter
38
+ counter += 1
39
+ ROImaskImg = ImageStack(roimask, titleStub = 'ROI region mask')
40
+ ROImaskImg.mdh.copyEntriesFrom(self.dsviewer.image.mdh)
41
+ # add entries for the mask
42
+ ROImaskImg.mdh['ROISet'] = roi_filename
43
+
44
+ ViewIm3D(ROImaskImg, mode='visGUI', title='ROI mask',
45
+ glCanvas=self.dsviewer.glCanvas, parent=self.dsviewer)
46
+
47
+ def Plug(dsviewer):
48
+ """Plugs this module into the gui"""
49
+ ImageJROItools(dsviewer)