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
PYMEcs/IO/NPC.py ADDED
@@ -0,0 +1,117 @@
1
+ from PYMEcs.pyme_warnings import warn
2
+ import pickle
3
+ from pathlib import Path
4
+ import logging
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+ def load_NPC_set(fname, ts=None, foreshortening=None, version=None):
9
+ with open(fname,'rb') as fi:
10
+ npcs=pickle.load(fi)
11
+ fpath = Path(fname)
12
+ if ts is not None and ts not in fpath.stem:
13
+ warn("MINFLUX time stamp not in NPC dataset filename; check correct filename chosen: %s vs %s" %
14
+ (ts,fpath.stem))
15
+
16
+ if foreshortening is not None:
17
+ try:
18
+ npc_foreshortening = npcs.foreshortening
19
+ except AttributeError:
20
+ npc_foreshortening = 1.0
21
+
22
+ if abs(npc_foreshortening-foreshortening) >= 0.01:
23
+ warn("NPC foreshortening is %.2f while dataset foreshortening is %.2f, check this is compatible" %
24
+ (npc_foreshortening,foreshortening))
25
+
26
+
27
+ if version is not None:
28
+ pass # here add version checking logic
29
+
30
+ return npcs
31
+
32
+ def save_NPC_set(npcs,fname):
33
+ with open(fname, "wb") as file:
34
+ pickle.dump(npcs,file)
35
+
36
+ def findNPCset(pipeline,return_mod=False,warnings=True):
37
+ from PYMEcs.recipes.localisations import NPCAnalysisInput
38
+ # note a "manually" created or loaded NPCset in pipeline.npcs attribute takes precedence over loaded via NPCAnalysisInput module
39
+ if pipeline is not None and 'npcs' in dir(pipeline) and pipeline.npcs is not None and not return_mod:
40
+ return pipeline.npcs
41
+ if pipeline is None:
42
+ return None
43
+ dsname = None
44
+ hideNPC = False
45
+ # search/check for instance
46
+ for mod in pipeline.recipe.modules:
47
+ if isinstance(mod,NPCAnalysisInput):
48
+ dsname = mod.output
49
+ hideNPC = mod.NPC_hide
50
+ module = mod
51
+ break
52
+ if hideNPC: # the module is deliberately hiding the NPCset associated with it
53
+ if warnings:
54
+ warn("NPCset has been marked as hidden in NPCAnalysisInput output, assuming this is deliberate")
55
+ return None
56
+ if dsname is None:
57
+ if warnings:
58
+ warn("we rely on npc analysis being present in a datasource generated by the NPCAnalysisInput module. Can't find such a datasource, aborting...")
59
+ return None
60
+ logger.debug("found NPCAnalysisInput module")
61
+ if return_mod:
62
+ return module
63
+ npc_set_container = pipeline.dataSources[dsname].mdh.get('Processing.NPCAnalysisInput.npcs_filtered')
64
+ if not mod.filter_npcs or npc_set_container is None: # if not filtering or no filtered set available try the unfiltered npc set
65
+ npc_set_container = pipeline.dataSources[dsname].mdh.get('Processing.NPCAnalysisInput.npcs')
66
+ logger.debug("trying to retrieve unfiltered NPCSet")
67
+ else:
68
+ logger.debug("found filtered NPCSet")
69
+ if npc_set_container is None: # we get here if there is still no npc set available
70
+ # this warning cannot be masked as this case should not happen unless something is broken (either bug or not used as intended)
71
+ warn(("found no NPCset container in metadata of datasource '%s' generated by NPCAnalysisInput module.\n\n" % dsname)
72
+ + "Did you already load a pickled NPC analysis file with the module?\n\naborting..." )
73
+ return None
74
+
75
+ return npc_set_container.get_npcset()
76
+
77
+ from packaging.version import Version # this allows us to do simpler comparisons
78
+ def check_npcset_version(npcset,target_version,mode='minimum version'):
79
+ version = None
80
+ try:
81
+ version = npcset.version()
82
+ except AttributeError:
83
+ pass
84
+ if version is None: # older version, use some heuristics
85
+ if 'n_bysegments' not in dir (npcset):
86
+ version = Version('0.1')
87
+ elif npcset.n_bysegments() is None: # this can also happen with newer version when not yet fitted, but then we should not have loaded this as a saved object
88
+ version = Version('0.1')
89
+ else:
90
+ version = Version('0.9')
91
+
92
+ if mode == 'return_version':
93
+ return version
94
+
95
+ if not isinstance(version,Version):
96
+ try:
97
+ version = Version(version)
98
+ except:
99
+ warn("cannot convert version expression '%s' to Version object, giving up and returning True, perhaps tell CS" % version)
100
+ return True
101
+
102
+ if not isinstance(target_version,Version):
103
+ try:
104
+ target_version = Version(target_version)
105
+ except:
106
+ warn("cannot convert version expression '%s' to Version object, giving up and returning True, perhaps tell CS" % target_version)
107
+ return True
108
+
109
+ if mode == 'minimum version':
110
+ return version >= target_version
111
+ elif mode == 'exact version':
112
+ return version == target_version
113
+ else: # we have checked for mode return_version above, so should be ok by not testing here
114
+ raise RuntimeError("unknown mode %s requested" % (mode))
115
+
116
+
117
+
PYMEcs/IO/__init__.py ADDED
File without changes
PYMEcs/IO/darkTimes.py ADDED
@@ -0,0 +1,19 @@
1
+ import csv
2
+ import numpy as np
3
+
4
+ def saveDarkTimesCSV(objectIDs,dts,filename):
5
+ with open( filename, 'w') as outfile:
6
+ writer = csv.writer( outfile )
7
+ for id, darktimes in zip(objectIDs,dts):
8
+ writer.writerow([id]+darktimes.tolist())
9
+
10
+ def readDarkTimesCSV(filename):
11
+ with open( filename, 'r') as infile:
12
+ reader = csv.reader( infile )
13
+ objectIDs = []
14
+ dts = []
15
+ for row in reader:
16
+ objectIDs.append(int(row[0]))
17
+ dt = np.array(row[1:],dtype='f')
18
+ dts.append(dt)
19
+ return (objectIDs,dts)
PYMEcs/IO/picasso.py ADDED
@@ -0,0 +1,219 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+ import yaml
4
+ import math
5
+ import os
6
+
7
+ def picasso2pyme(locs,mdh):
8
+ try:
9
+ nmperpix = mdh['Camera.Pixelsize']
10
+ except KeyError:
11
+ nmperpix = mdh['Pixelsize']
12
+
13
+ pyme = {}
14
+ pyme['x'] = locs['x']*nmperpix
15
+ pyme['y'] = locs['y']*nmperpix
16
+ pyme['sig'] = locs['sx']*nmperpix
17
+ pyme['nPhotons'] = locs['photons']
18
+ pyme['error_x'] = locs['lpx']*nmperpix
19
+ pyme['error_y'] = locs['lpy']*nmperpix
20
+ pyme['t'] = locs['frame']
21
+ pyme['A'] = locs['photons']/(2*math.pi)/(locs['sx']**2) # this is from the PYME kinmodels formula - check
22
+ if 'z' in locs.keys():
23
+ pyme['z'] = locs['z'] # from astigmatoc data z should already be scaled to nm?
24
+ return pyme
25
+
26
+ def struc_from_mdh(mdh):
27
+ if mdh is None or 'Structure.HandleStruct' not in mdh.keys():
28
+ return None
29
+ struc = {}
30
+ nmperpix = float(mdh['Camera.Pixelsize'])
31
+ npixels = float(mdh['Camera.Image Size'])
32
+ for key in ('HandleStruct','HandleEx'):
33
+ struc[key] = np.array([float(i) for i in mdh["Structure.%s" % key].split(',')],dtype='i')
34
+ offshalfpix = 0.5 # half a pixel offset seems to be required (origin in middle of pixel?)
35
+ for key in ['HandleX']:
36
+ struc[key] = np.array([(float(i)-offshalfpix)*nmperpix for i in mdh["Structure.%s" % key].split(',')])
37
+ # for a reason not quite clear to me yet the Y coordinates need mirroring
38
+ for key in ['HandleY']:
39
+ struc[key] = np.array([(npixels-float(i)-offshalfpix)*nmperpix for i in mdh["Structure.%s" % key].split(',')])
40
+ return struc
41
+
42
+ def parse_dicts(dicts):
43
+ import re
44
+ mdh = None
45
+ strucmdh = None
46
+ for d in dicts:
47
+ if any (re.match('pixelsize',key,re.I) for key in d.keys()):
48
+ mdh = d
49
+ for d in dicts:
50
+ if any (re.match('Structure',key,re.I) for key in d.keys()):
51
+ strucmdh = d
52
+ return (mdh,strucmdh)
53
+
54
+ def read_picasso_hdf(name):
55
+ locs = pd.read_hdf(name,'locs')
56
+ basename, file_extension = os.path.splitext(name)
57
+ with open(basename+'.yaml') as file:
58
+ finf = list(yaml.load_all(file, Loader=yaml.FullLoader))
59
+ mdh, strucmdh = parse_dicts(finf)
60
+ pymedf = pd.DataFrame(picasso2pyme(locs,mdh))
61
+ struc = struc_from_mdh(strucmdh)
62
+ return pymedf, mdh, struc
63
+
64
+ def pymedf2csv(pymedf,filename):
65
+ cols = ['A','x','y','t','sig','error_x','error_y','nPhotons']
66
+ pymedf.to_csv(filename,columns=cols,index=False)
67
+
68
+ def pymedf2ds(pymedf):
69
+ from PYME.IO.tabular import DictSource
70
+ pymedict={}
71
+ for key in pymedf.keys():
72
+ pymedict[key] = pymedf[key].values
73
+ ds = DictSource(pymedict)
74
+ return ds
75
+
76
+ import skimage.morphology as morph
77
+ from PYME.IO.image import ImageStack
78
+ #from PYME.IO.MetaDataHandler import NestedClassMDHandler
79
+
80
+ def picasso_structure_mask(inputim,struc,dilations=2,
81
+ dilationselem=np.ones((5,5),dtype='float32')):
82
+ ox = inputim.mdh['Origin.x']
83
+ oy = inputim.mdh['Origin.y']
84
+ vxsz = 1e3*inputim.mdh['voxelsize.x']
85
+
86
+ mask0 = np.zeros(inputim.data.shape[0:2],dtype='float32')
87
+ labels = []
88
+ nsites = []
89
+ cxa = []
90
+ cya = []
91
+
92
+ for label in range(0,int(struc['HandleStruct'].max()+1)):
93
+ strucn = struc['HandleStruct'] == label
94
+ newim = np.zeros(inputim.data.shape[0:2],dtype='float32')
95
+ strucx = ((struc['HandleX'][strucn]) - ox) / vxsz
96
+ strucy = ((struc['HandleY'][strucn]) - oy) / vxsz
97
+ cx = struc['HandleX'][strucn].mean()
98
+ cy = struc['HandleY'][strucn].mean()
99
+ cxi = np.rint(strucx.mean()).astype('int') # integer centroid x
100
+ cyi = np.rint(strucy.mean()).astype('int') # integer centroid y
101
+ labels.append(label+1)
102
+ nsites.append(strucx.size)
103
+ cxa.append(cx)
104
+ cya.append(cy)
105
+ ind = (strucx < newim.shape[0])*(strucy < newim.shape[1])*(strucx >= 0)*(strucy >= 0)
106
+ if np.any(ind):
107
+ newim[strucx[ind].astype('i'),strucy[ind].astype('i')] = 1.0
108
+ newim2 = morph.convex_hull_image(newim)
109
+ for i in range(dilations):
110
+ newim2 = morph.binary_dilation(newim2,selem=dilationselem)
111
+ mask0[newim2 > 0.5] = label+1
112
+
113
+ sitesdf = pd.DataFrame(list(zip(labels, nsites, cxa, cya)),
114
+ columns =['Label', 'NSites', 'CentroidX', 'CentroidY'])
115
+ return ImageStack(mask0, mdh=inputim.mdh), sitesdf
116
+
117
+ # same as the routine above but everything is done in a small ROI that is then inserted into the
118
+ # full size image; this speeds everything up considerably, mostly as hoped
119
+ def picasso_structure_mask_roi(inputim,struc,dilations=2,
120
+ dilationselem=np.ones((5,5),dtype='float32'),roisize=20):
121
+ ox = inputim.mdh['Origin.x']
122
+ oy = inputim.mdh['Origin.y']
123
+ vxsz = 1e3*inputim.mdh['voxelsize.x']
124
+
125
+ mask0 = np.zeros(inputim.data.shape[0:2],dtype='float32')
126
+ labels = []
127
+ nsites = []
128
+ cxa = []
129
+ cya = []
130
+
131
+ rszh = roisize
132
+ xroi = np.arange(0,2*rszh+1,dtype='int')
133
+ yroi = np.arange(0,2*rszh+1,dtype='int')
134
+ xroi2 = np.outer(xroi,np.ones(2*rszh+1,dtype='i'))
135
+ yroi2 = np.outer(np.ones(2*rszh+1,dtype='i'),yroi)
136
+
137
+ for label in range(0,int(struc['HandleStruct'].max()+1)):
138
+ strucn = struc['HandleStruct'] == label
139
+ strucx = ((struc['HandleX'][strucn]) - ox) / vxsz
140
+ strucy = ((struc['HandleY'][strucn]) - oy) / vxsz
141
+ cx = struc['HandleX'][strucn].mean()
142
+ cy = struc['HandleY'][strucn].mean()
143
+ cxi = np.rint(strucx.mean()).astype('int') # integer centroid x
144
+ cyi = np.rint(strucy.mean()).astype('int') # integer centroid y
145
+ labels.append(label+1)
146
+ nsites.append(strucx.size)
147
+ cxa.append(cx)
148
+ cya.append(cy)
149
+ # make empty small ROI
150
+ roinew = np.zeros((2*rszh+1,2*rszh+1),dtype='f')
151
+ # transform coordinates to the ROI coordinate system
152
+ # the ROI is centered on the structure centroid (cxi,cyi)
153
+ roisx = strucx - (cxi-rszh)
154
+ roisy = strucy - (cyi-rszh)
155
+ # set pixels corresponding to structure to 1
156
+ roinew[roisx.astype('i'),roisy.astype('i')] = 1.0
157
+ # convex hull of structure + dilations
158
+ roi2 = morph.convex_hull_image(roinew)
159
+ for i in range(dilations):
160
+ roi2 = morph.binary_dilation(roi2,selem=dilationselem)
161
+ # transform ROI coordinates to full image coordiante system
162
+ x2 = xroi2 + (cxi-rszh)
163
+ y2 = yroi2 + (cyi-rszh)
164
+ # restrict to non-zero pixels
165
+ mask = roi2 > 0.5
166
+ x2m = x2[mask]
167
+ y2m = y2[mask]
168
+ # check which of these non-zero pixels are within the full image bounds
169
+ valid = (x2m < mask0.shape[0])*(y2m < mask0.shape[1])*(x2m >= 0)*(y2m >= 0)
170
+ if np.any(valid):
171
+ mask0[x2[mask][valid],y2[mask][valid]] = label+1 # set to label of that structure
172
+
173
+ sitesdf = pd.DataFrame(list(zip(labels, nsites, cxa, cya)),
174
+ columns =['Label', 'NSites', 'CentroidX', 'CentroidY'])
175
+ return ImageStack(mask0, mdh=inputim.mdh), sitesdf
176
+
177
+ # import skimage.morphology as morph
178
+
179
+ # dilations=2
180
+ # dilationselem=np.ones((5,5),dtype='i')
181
+
182
+ # strucx = np.array([200,210,220,200,210])
183
+ # strucy = np.array([100,100,100,110,110])
184
+
185
+ # cx = np.round(strucx.mean()).astype('i')
186
+ # cy = np.round(strucy.mean()).astype('i')
187
+
188
+ # mask0 = np.zeros((256,256),dtype='f')
189
+
190
+ # rszh = 20
191
+
192
+ # # initialisation
193
+ # xroi = np.arange(0,2*rszh+1,dtype='int')
194
+ # yroi = np.arange(0,2*rszh+1,dtype='int')
195
+ # xroi2 = np.outer(xroi,np.ones(2*rszh+1,dtype='i'))
196
+ # yroi2 = np.outer(np.ones(2*rszh+1,dtype='i'),yroi)
197
+
198
+ # # this is done in each loop
199
+ # roinew = np.zeros((2*rszh+1,2*rszh+1),dtype='f')
200
+
201
+ # roisx = strucx - (cx-rszh)
202
+ # roisy = strucy - (cy-rszh)
203
+
204
+ # roinew[roisx.astype('i'),roisy.astype('i')] = 1.0
205
+ # roi2 = morph.convex_hull_image(roinew)
206
+ # for i in range(dilations):
207
+ # roi2 = morph.binary_dilation(roi2,selem=dilationselem)
208
+
209
+ # x2 = xroi2 + (cx-rszh)
210
+ # y2 = yroi2 + (cy-rszh)
211
+
212
+ # mask = roi2 > 0.5
213
+
214
+ # x2m = x2[mask]
215
+ # y2m = y2[mask]
216
+
217
+ # valid = (x2m < mask0.shape[0])*(y2m < mask0.shape[1])*(x2m >= 0)*(y2m >= 0)
218
+
219
+ # mask0[x2[mask][valid],y2[mask][valid]] = roi2[xroi2[mask][valid],yroi2[mask][valid]]
PYMEcs/IO/tabular.py ADDED
@@ -0,0 +1,11 @@
1
+ from PYMEcs.Analysis.fitDarkTimes import TabularRecArrayWrap
2
+ import pandas as pd
3
+ import numpy as np
4
+
5
+ # we should probably add this to a module like PYMEcs.IO.tabular
6
+ def tabularFromCSV(csvname):
7
+ df = pd.DataFrame.from_csv(csvname)
8
+ rec = df.to_records()
9
+ tb = TabularRecArrayWrap(rec)
10
+ return tb
11
+
PYMEcs/__init__.py ADDED
File without changes
@@ -0,0 +1,51 @@
1
+ import PYMEcs.Analysis.stackTracker as st
2
+ from PYMEcs.misc.guiMsgBoxes import Warn
3
+
4
+ from traits.api import HasTraits, Str, Int, CStr, List, Enum, Float, Bool
5
+
6
+ class CalcZfConfig(HasTraits):
7
+ offsetFromCenter = Int(0)
8
+ planesToUse = Int(11)
9
+
10
+ from PYME.DSView.modules._base import Plugin
11
+ class CalcZf(Plugin):
12
+ def __init__(self, dsviewer):
13
+ Plugin.__init__(self, dsviewer)
14
+ self.czfconf = CalcZfConfig()
15
+
16
+ dsviewer.AddMenuItem('Experimental', "Calculate z-factor", self.OnCalcZf)
17
+ dsviewer.AddMenuItem('Experimental', "z-factor calculation settings", self.OnCalcZfSettings)
18
+
19
+ def OnCalcZfSettings(self, event):
20
+ self.czfconf.configure_traits(kind='modal')
21
+
22
+ def OnCalcZf(self, event):
23
+ # first a few checks that the data set is suitable
24
+ # do we need further checks?
25
+ from math import isclose
26
+ if not isclose(self.dsviewer.image.voxelsize_nm.z,50.0,abs_tol=1.0):
27
+ Warn(self.dsviewer,'z voxelsize needs to be 50 nm, is %.1f nm' % self.dsviewer.image.voxelsize_nm.z)
28
+ return
29
+
30
+ use_zszh = self.czfconf.planesToUse // 2
31
+ offset = self.czfconf.offsetFromCenter
32
+ need_planes = 2*use_zszh+1 + abs(offset)
33
+
34
+ zsz = self.dsviewer.image.data_xyztc.shape[2]
35
+ zszh = zsz // 2
36
+ if 2*zszh+1 != zsz:
37
+ Warn(self.dsviewer,'z dimension size should be odd number, is %d' % zsz)
38
+ return
39
+ if zsz < need_planes:
40
+ Warn(self.dsviewer,'need at least %d planes, stack has %d planes' % (need_planes,zsz))
41
+ return
42
+
43
+ dataset = self.dsviewer.image.data_xyztc[:,:,zszh+offset-use_zszh:zszh+offset+use_zszh+1,0,0].squeeze()
44
+
45
+ tstack = st.initialise_data(dataset,4,self.dsviewer.image.voxelsize_nm)
46
+ dxnm,dynm,dznm = st.get_shifts_from_stackobject(tstack)
47
+
48
+ st.fit_and_plot_zf(dxnm,dynm,dznm,tstack)
49
+
50
+ def Plug(dsviewer):
51
+ return CalcZf(dsviewer)