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,59 @@
1
+ from flask import Flask, request, jsonify, make_response
2
+ from http import HTTPStatus
3
+ import logging
4
+
5
+ def create_app(mode='simulated'):
6
+ # create and configure the app
7
+ app = Flask(__name__)
8
+
9
+ if mode == 'simulated':
10
+ from PYMEcs.Acquire.Hardware.LPthreadedSimpleSim import LPThread
11
+ else:
12
+ from PYMEcs.Acquire.Hardware.LPthreadedSimple import LPThread
13
+
14
+ # so that we can see which thread processes the various messages, commands
15
+ logging.basicConfig(level=logging.DEBUG,
16
+ format='(%(threadName)-9s) %(message)s',)
17
+
18
+ lpt = LPThread(name='NikonTiThread')
19
+ lpt.start()
20
+
21
+ @app.get("/names")
22
+ def get_names():
23
+ status, names = lpt.run_command('GetNames')
24
+ return jsonify(names)
25
+
26
+ @app.get("/port")
27
+ def get_port():
28
+ status, port = lpt.run_command('GetPort')
29
+ response = make_response(port, status)
30
+ response.mimetype = "text/plain"
31
+ return response
32
+
33
+ @app.put("/port")
34
+ def set_port():
35
+ port = request.get_data().decode("utf-8")
36
+ status = lpt.run_command('SetPort',port)
37
+ return port, status
38
+
39
+ @app.get("/position")
40
+ def get_position():
41
+ status, pos = lpt.run_command('GetPosition')
42
+ response = make_response(str(pos), status)
43
+ response.mimetype = "text/plain"
44
+ return response
45
+
46
+ @app.put("/position")
47
+ def set_position():
48
+ pos = int(request.get_data().decode("utf-8"))
49
+ status = lpt.run_command('SetPosition',pos)
50
+ return str(pos), status
51
+
52
+ return app
53
+
54
+ if __name__ == '__main__':
55
+ app.run(threaded=False, processes=1)
56
+
57
+ # invoke from the command line as, for example:
58
+ #
59
+ # flask --app 'PYMEcs.Acquire.Hardware.NikonTiFlaskServerT:create_app(mode="production")' --debug run
@@ -0,0 +1,73 @@
1
+ import requests
2
+ from urllib.parse import urljoin
3
+ import logging
4
+ from http import HTTPStatus
5
+ from PYMEcs.Acquire.Hardware.NikonTiSim import LightPath as TiLightPath
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ # by basing it on the simulator we inherit the "generic" methods, i.e.
10
+ # ProvideMetadata, OnChange and Poll
11
+ # which are required for the functional object when used with
12
+ # PYMEAcquire
13
+ class LPClient(TiLightPath):
14
+ def __init__(self, url="http://127.0.0.1:5000", timeout=15):
15
+ self.url = url
16
+ self.timeout = timeout
17
+ self.wantChangeNotification = []
18
+
19
+ self.names = self.GetNames() # execute the method once and then keep the values cached
20
+ self.lastPosition = self.GetPosition() # initialise here as later used in Poll method
21
+
22
+ def GetPosition(self):
23
+ response = requests.get(urljoin(self.url,'position'),timeout=self.timeout)
24
+ if response.status_code == HTTPStatus.OK:
25
+ position = int(response.content.decode())
26
+ return position
27
+ else:
28
+ logger.warn("HTTP response error: got status %d" % response.status_code)
29
+ return None
30
+
31
+ def SetPosition(self,position):
32
+ response = requests.put(urljoin(self.url,'position'),data=str(position),timeout=self.timeout)
33
+ if response.status_code == HTTPStatus.OK:
34
+ newpos = int(response.content.decode())
35
+ if newpos != position:
36
+ logger.warn("asked for position '%d' but got position '%s'" % (newpos,position))
37
+ self.lastPosition = newpos # update so that OnChange works ok
38
+ self.OnChange()
39
+ else:
40
+ logger.warn("HTTP response error: got status %d" % response.status_code)
41
+
42
+ def GetPort(self):
43
+ response = requests.get(urljoin(self.url,'port'),timeout=self.timeout)
44
+ if response.status_code == HTTPStatus.OK:
45
+ port = response.content.decode()
46
+ return port
47
+ else:
48
+ logger.warn("HTTP response error: got status %d" % response.status_code)
49
+ return None
50
+
51
+ def SetPort(self,port):
52
+ if port in self.names:
53
+ response = requests.put(urljoin(self.url,'port'),data=port,timeout=self.timeout)
54
+ if response.status_code == HTTPStatus.OK:
55
+ newport = response.content.decode()
56
+ if newport != port:
57
+ logger.warn("asked for port '%s' but got port '%s'" % (newport,port))
58
+ self.lastPosition = self.GetPosition() # update so that OnChange works ok
59
+ self.OnChange()
60
+ else:
61
+ logger.warn("HTTP response error: got status %d" % response.status_code)
62
+ else:
63
+ logger.warn("Asking for unknown port '%s', ignoring" % port)
64
+
65
+ def GetNames(self):
66
+ response = requests.get(urljoin(self.url,"names"),timeout=self.timeout)
67
+ if response.status_code == HTTPStatus.OK:
68
+ names = response.json()
69
+ return names
70
+ else:
71
+ logger.warn("HTTP response error: got status %d" % response.status_code)
72
+ return None
73
+
@@ -0,0 +1,35 @@
1
+ class LightPath:
2
+ def __init__(self, names = ['EYE', 'L100', 'R100', 'L80']):
3
+ self.simulatedPosition = 1
4
+ self.names = names
5
+ self.wantChangeNotification = []
6
+
7
+ self.lastPosition = self.GetPosition()
8
+
9
+ def SetPosition(self, pos):
10
+ self.simulatedPosition = (pos + 1)
11
+ self.lastPosition = pos
12
+ self.OnChange()
13
+
14
+ def GetPosition(self):
15
+ return int(self.simulatedPosition) - 1
16
+
17
+ def SetPort(self, port):
18
+ self.SetPosition(self.names.index(port))
19
+ self.OnChange()
20
+
21
+ def GetPort(self):
22
+ return self.names[self.GetPosition()]
23
+
24
+ def ProvideMetadata(self,mdh):
25
+ mdh.setEntry('NikonTi.LightPath', self.GetPort())
26
+
27
+ def OnChange(self):
28
+ for a in self.wantChangeNotification:
29
+ a()
30
+
31
+ def Poll(self):
32
+ pos = self.GetPosition()
33
+ if not self.lastPosition == pos:
34
+ self.lastPosition = pos
35
+ self.OnChange()
File without changes
@@ -0,0 +1,329 @@
1
+ #!/usr/bin/python
2
+
3
+ ##################
4
+ # <filename>.py
5
+ #
6
+ # Copyright David Baddeley, 2012
7
+ # d.baddeley@auckland.ac.nz
8
+ #
9
+ # This file may NOT be distributed without express permision from David Baddeley
10
+ #
11
+ ##################
12
+ import wx
13
+
14
+ import numpy as np
15
+ from PYME.contrib.wxPlotPanel import PlotPanel
16
+ from PYME.IO import MetaDataHandler
17
+ from PYME.DSView import dsviewer as dsviewer
18
+ import PYME.IO.image as im
19
+
20
+ from PYMEcs.misc.guiMsgBoxes import Info, Warn
21
+
22
+ import os
23
+
24
+ import logging
25
+ logger = logging.getLogger(__name__)
26
+
27
+ class TrackerPlotPanel(PlotPanel):
28
+ # import matplotlib.pyplot as plt # not needed if we use object based method for tight_layout
29
+ def __init__(self, parent, driftTracker, *args, **kwargs):
30
+ self.dt = driftTracker
31
+ PlotPanel.__init__(self, parent, *args, **kwargs)
32
+
33
+ # add 5th suplot
34
+ # replace 4th plot with offset and
35
+ # new 5th subplot for z-pos (how calculated, z-nominal + dz?, remove offset)
36
+ def draw(self):
37
+ if self.IsShownOnScreen():
38
+ if not hasattr( self, 'subplotxy' ):
39
+ self.subplotxy = self.figure.add_subplot( 411 )
40
+ self.subplotz = self.figure.add_subplot( 412 )
41
+ self.subploto = self.figure.add_subplot( 413 )
42
+ self.subplotc = self.figure.add_subplot(414)
43
+ # hopefully this sets it always for this fig, see https://matplotlib.org/stable/tutorials/intermediate/tight_layout_guide.html
44
+ self.figure.set_tight_layout(True)
45
+ # plt.tight_layout() # can we call as object oriented? do we need to call each time plotted?
46
+
47
+ try:
48
+ t, dx, dy, dz, corr, corrmax, poffset, pos = np.array(self.dt.get_history(1000)).T
49
+ except ValueError:
50
+ do_plot = False
51
+ else:
52
+ do_plot = True
53
+
54
+ if do_plot:
55
+ # note: we now assume that all history values that are distances are provided in nm
56
+ # this SHOULD match the conventions in driftTracking.py
57
+
58
+ # a few reused variables
59
+ tolnm = 1e3*self.dt.get_focus_tolerance()
60
+ tdelta = t - self.dt.historyStartTime
61
+ trange = [tdelta.min(), tdelta.max()]
62
+
63
+ self.subplotxy.cla()
64
+ self.subplotxy.plot(tdelta, dx, 'r')
65
+ self.subplotxy.plot(tdelta, dy, 'g')
66
+ self.subplotxy.set_ylabel('dx/dy (r/g) [nm]')
67
+ self.subplotxy.set_xlim(*trange)
68
+
69
+ self.subplotz.cla()
70
+ self.subplotz.plot(tdelta, dz, 'b')
71
+ self.subplotz.plot([tdelta[0],tdelta[-1]],[tolnm,tolnm], 'g--')
72
+ self.subplotz.plot([tdelta[0],tdelta[-1]],[-tolnm,-tolnm], 'g--')
73
+ self.subplotz.set_ylabel('dz [nm]')
74
+ self.subplotz.set_xlim(*trange)
75
+
76
+ self.subploto.cla()
77
+ self.subploto.plot(tdelta, poffset, 'm')
78
+ self.subploto.set_ylabel('offs [nm]')
79
+ self.subploto.set_xlim(*trange)
80
+
81
+ self.subplotc.cla()
82
+ self.subplotc.plot(tdelta, corr/corrmax, 'r')
83
+ self.subplotc.set_ylabel('C/C_m')
84
+ self.subplotc.set_xlim(*trange)
85
+ self.subplotc.set_xlabel('Time (s)')
86
+
87
+
88
+
89
+ #except:
90
+ # pass
91
+
92
+ #self.subplot.set_xlim(0, 512)
93
+ #self.subplot.set_ylim(0, 256)
94
+
95
+ self.canvas.draw()
96
+
97
+
98
+
99
+ # add controls for lastAdjustment
100
+ class DriftTrackingControl(wx.Panel):
101
+ def __init__(self, parent, driftTracker, winid=-1, showPlots=True):
102
+ # begin wxGlade: MyFrame1.__init__
103
+ #kwds["style"] = wx.DEFAULT_FRAME_STYLE
104
+ wx.Panel.__init__(self, parent, winid)
105
+ self.dt = driftTracker
106
+ self.plotInterval = 10
107
+ self.showPlots = showPlots
108
+
109
+ sizer_1 = wx.BoxSizer(wx.VERTICAL)
110
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
111
+
112
+ self.cbTrack = wx.CheckBox(self, -1, 'Track')
113
+ hsizer.Add(self.cbTrack, 0, wx.ALL, 2)
114
+ self.cbTrack.Bind(wx.EVT_CHECKBOX, self.OnCBTrack)
115
+ self.cbLock = wx.CheckBox(self, -1, 'Lock')
116
+ self.cbLock.Bind(wx.EVT_CHECKBOX, self.OnCBLock)
117
+ hsizer.Add(self.cbLock, 0, wx.ALL, 2)
118
+ self.bSaveHist = wx.Button(self, -1, 'Save History')
119
+ hsizer.Add(self.bSaveHist, 0, wx.ALL, 2)
120
+ self.bSaveHist.Bind(wx.EVT_BUTTON, self.OnBSaveHist)
121
+ self.cbLockActive = wx.CheckBox(self, -1, 'Lock Active')
122
+ self.cbLockActive.Enable(False)
123
+ hsizer.Add(self.cbLockActive, 0, wx.ALL, 2)
124
+ sizer_1.Add(hsizer, 0, wx.EXPAND, 0)
125
+
126
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
127
+ self.bSetPostion = wx.Button(self, -1, 'Set focus to current')
128
+ hsizer.Add(self.bSetPostion, 0, wx.ALL, 2)
129
+ self.bSetPostion.Bind(wx.EVT_BUTTON, self.OnBSetPostion)
130
+ self.bSaveCalib = wx.Button(self, -1, 'Save Cal')
131
+ hsizer.Add(self.bSaveCalib, 0, wx.ALL, 2)
132
+ self.bSaveCalib.Bind(wx.EVT_BUTTON, self.OnBSaveCalib)
133
+ sizer_1.Add(hsizer, 0, wx.EXPAND, 0)
134
+
135
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
136
+ hsizer.Add(wx.StaticText(self, -1, "Calibration:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
137
+ self.gCalib = wx.Gauge(self, -1, 11)
138
+ hsizer.Add(self.gCalib, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
139
+ sizer_1.Add(hsizer, 0, wx.EXPAND, 0)
140
+
141
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
142
+ hsizer.Add(wx.StaticText(self, -1, "Tolerance [nm]:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
143
+ self.tTolerance = wx.TextCtrl(self, -1, '%3.0f'% (1e3*self.dt.get_focus_tolerance()), size=[30,-1])
144
+ hsizer.Add(self.tTolerance, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
145
+ self.bSetTolerance = wx.Button(self, -1, 'Set', style=wx.BU_EXACTFIT)
146
+ hsizer.Add(self.bSetTolerance, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
147
+ self.bSetTolerance.Bind(wx.EVT_BUTTON, self.OnBSetTolerance)
148
+ sizer_1.Add(hsizer,0, wx.EXPAND, 0)
149
+
150
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
151
+ hsizer.Add(wx.StaticText(self, -1, "Z-factor:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
152
+ self.tZfactor = wx.TextCtrl(self, -1, '%3.1f'% self.dt.Zfactor, size=[30,-1])
153
+ hsizer.Add(self.tZfactor, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
154
+ self.bSetZfactor = wx.Button(self, -1, 'Set', style=wx.BU_EXACTFIT)
155
+ hsizer.Add(self.bSetZfactor, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
156
+ self.bSetZfactor.Bind(wx.EVT_BUTTON, self.OnBSetZfactor)
157
+ sizer_1.Add(hsizer,0, wx.EXPAND, 0)
158
+
159
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
160
+ hsizer.Add(wx.StaticText(self, -1, "Correction fraction (0.1..1):"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
161
+ self.tFraction = wx.TextCtrl(self, -1, '%3.1f'% self.dt.correctionFraction, size=[30,-1])
162
+ hsizer.Add(self.tFraction, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
163
+ self.bSetFraction = wx.Button(self, -1, 'Set', style=wx.BU_EXACTFIT)
164
+ hsizer.Add(self.bSetFraction, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
165
+ self.bSetFraction.Bind(wx.EVT_BUTTON, self.OnBSetFraction)
166
+ sizer_1.Add(hsizer,0, wx.EXPAND, 0)
167
+
168
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
169
+ hsizer.Add(wx.StaticText(self, -1, "feedback delay [frames]:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
170
+ self.tMinDelay = wx.TextCtrl(self, -1, '%d' % (self.dt.minDelay), size=[30,-1])
171
+ hsizer.Add(self.tMinDelay, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
172
+ self.bSetMinDelay = wx.Button(self, -1, 'Set', style=wx.BU_EXACTFIT)
173
+ hsizer.Add(self.bSetMinDelay, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
174
+ self.bSetMinDelay.Bind(wx.EVT_BUTTON, self.OnBSetMinDelay)
175
+ sizer_1.Add(hsizer,0, wx.EXPAND, 0)
176
+
177
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
178
+ hsizer.Add(wx.StaticText(self, -1, "Plot Interval [frames]:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
179
+ self.tPlotInterval = wx.TextCtrl(self, -1, '%d' % (self.plotInterval), size=[30,-1])
180
+ hsizer.Add(self.tPlotInterval, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
181
+ self.bSetPlotInterval = wx.Button(self, -1, 'Set', style=wx.BU_EXACTFIT)
182
+ hsizer.Add(self.bSetPlotInterval, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
183
+ self.bSetPlotInterval.Bind(wx.EVT_BUTTON, self.OnBSetPlotInterval)
184
+ sizer_1.Add(hsizer,0, wx.EXPAND, 0)
185
+
186
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
187
+ self.stError = wx.StaticText(self, -1, 'Error:\n\n', size=[200,-1])
188
+ cfont = self.stError.GetFont()
189
+ font = wx.Font(cfont.GetPointSize(), wx.TELETYPE, wx.NORMAL, wx.NORMAL)
190
+ self.stError.SetFont(font)
191
+ hsizer.Add(self.stError, 0, wx.ALL, 2)
192
+ sizer_1.Add(hsizer,0, wx.EXPAND, 0)
193
+
194
+ if self.showPlots:
195
+ self.trackPlot = TrackerPlotPanel(self, self.dt, size=[300, 500])
196
+
197
+ #hsizer.Add(self.stError, 0, wx.ALL, 2)
198
+ sizer_1.Add(self.trackPlot,0, wx.EXPAND, 0)
199
+
200
+ self.SetAutoLayout(1)
201
+ self.SetSizer(sizer_1)
202
+ sizer_1.Fit(self)
203
+ sizer_1.SetSizeHints(self)
204
+ self.Layout()
205
+ # end wxGlade
206
+
207
+ self.getMdh() # we should be able to use the metadata to look up pixel sizes?
208
+ # we pass this down to the drifttracker but could also do this only in driftTrackGUI when plotting?
209
+ # but seems preferable to keep this at the lower level as we then have the nm info in the events that are stored with data
210
+ self.dt.vsznm_x = self.mdh.voxelsize_nm.x
211
+ self.dt.vsznm_y = self.mdh.voxelsize_nm.y
212
+
213
+ def OnCBTrack(self, event):
214
+ #print self.cbTrack.GetValue()
215
+ if self.cbTrack.GetValue():
216
+ self.dt.register()
217
+ else:
218
+ self.dt.deregister()
219
+
220
+ def OnBSetPostion(self, event):
221
+ self.dt.reCalibrate()
222
+
223
+ def OnBSaveCalib(self, event):
224
+ if not hasattr(self.dt, 'calibState') or (self.dt.calibState < self.dt.NCalibStates):
225
+ Warn(self,"not calibrated")
226
+ else:
227
+ self.showCalImages()
228
+
229
+ def getMdh(self):
230
+ # this methods gets us the cam metadata to check pixel sizes etc
231
+ # metadata handling
232
+ mdh = MetaDataHandler.NestedClassMDHandler()
233
+ # loop over all providers of metadata
234
+ for mdgen in MetaDataHandler.provideStartMetadata:
235
+ mdgen(mdh)
236
+
237
+ self.mdh = mdh
238
+
239
+ def showCalImages(self):
240
+ import numpy as np
241
+ import time
242
+
243
+ #metadata handling
244
+ mdh = MetaDataHandler.NestedClassMDHandler()
245
+ mdh.setEntry('StartTime', time.time())
246
+ mdh.setEntry('AcquisitionType', 'Stack')
247
+
248
+ #loop over all providers of metadata
249
+ for mdgen in MetaDataHandler.provideStartMetadata:
250
+ mdgen(mdh)
251
+ mdh.setEntry('CalibrationPositions',self.dt.calPositions)
252
+
253
+ im = dsviewer.ImageStack(data = self.dt.refImages, mdh = mdh, titleStub='Unsaved Image')
254
+ if not im.mode == 'graph':
255
+ im.mode = 'lite'
256
+
257
+ #print im.mode
258
+ dvf = dsviewer.DSViewFrame(im, mode= im.mode, size=(500, 500))
259
+ dvf.SetSize((500,500))
260
+ dvf.Show()
261
+
262
+ def OnBSaveHist(self, event):
263
+ if not hasattr(self.dt, 'history') or (len(self.dt.history) <= 0):
264
+ Warn(self,"no history")
265
+ else:
266
+ dlg = wx.FileDialog(self, message="Save file as...",
267
+ defaultFile='history.txt',
268
+ wildcard='txt File (*.txt)|*.txt',
269
+ style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
270
+
271
+ if dlg.ShowModal() == wx.ID_OK:
272
+ historyfn = dlg.GetPath()
273
+ np.savetxt(historyfn, self.dt.history, header=' '.join(self.dt.historyColNames))
274
+ # Info(self,"history saved")
275
+
276
+
277
+ def OnBSetTolerance(self, event):
278
+ self.dt.set_focus_tolerance(float(self.tTolerance.GetValue())/1e3)
279
+
280
+ def OnBSetZfactor(self, event):
281
+ self.dt.Zfactor = float(self.tZfactor.GetValue())
282
+
283
+ def OnBSetFraction(self, event):
284
+ fraction = float(self.tZfactor.GetValue())
285
+ if fraction < 0.1:
286
+ fraction = 0.1
287
+ if fraction > 1.0:
288
+ fraction = 1.0
289
+ self.dt.correctionFraction = fraction
290
+
291
+ def OnBSetMinDelay(self, event):
292
+ self.dt.minDelay = int(self.tMinDelay.GetValue())
293
+
294
+ def OnBSetPlotInterval(self, event):
295
+ self.plotInterval = int(self.tPlotInterval.GetValue())
296
+
297
+ def OnCBLock(self, event):
298
+ self.dt.set_focus_lock(self.cbLock.GetValue())
299
+
300
+ def refresh(self):
301
+ try:
302
+ calibState, NStates = self.dt.get_calibration_state()
303
+ self.gCalib.SetRange(int(NStates + 1))
304
+ self.gCalib.SetValue(int(calibState))
305
+
306
+ try:
307
+ t, dx, dy, dz, corr, corrmax,poffset,pos = self.dt.get_history(1)[-1]
308
+ posInd = self.dt.latestPosData[0]
309
+ self.stError.SetLabel(("Error: x = %s nm y = %s nm " +
310
+ "z = %s nm\nnoffs = %s nm c/cm = %4.2f posInd = %d") %
311
+ ("{:>+3.2f}".format(dx), "{:>+3.2f}".format(dy),
312
+ "{:>+3.1f}".format(dz), "{:>+6.1f}".format(poffset),
313
+ corr/corrmax, posInd))
314
+
315
+ except IndexError:
316
+ pass
317
+
318
+ self.cbLock.SetValue(self.dt.get_focus_lock())
319
+ self.cbTrack.SetValue(self.dt.is_tracking())
320
+ self.cbLockActive.SetValue(self.dt.lockActive)
321
+
322
+ if (len(self.dt.get_history(0)) > 0) and (len(self.dt.get_history(0)) % self.plotInterval == 0) and self.showPlots:
323
+ self.trackPlot.draw()
324
+ except AttributeError:
325
+ logger.exception('error in refresh')
326
+ pass
327
+ except IndexError:
328
+ logger.exception('error in refresh')
329
+ pass