-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathVolumeFinder.ipf
More file actions
201 lines (176 loc) · 5.77 KB
/
VolumeFinder.ipf
File metadata and controls
201 lines (176 loc) · 5.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#pragma TextEncoding = "MacRoman" // For details execute DisplayHelpTopic "The TextEncoding Pragma"
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
// Menu item for easy execution
Menu "Macros"
Submenu "Volume Finder"
"Find Volumes", VolumeFinder()
End
End
// Use this function to load and process TIFF stacks in one folder
// TIFFs must be binarized versions of amira segmentation files
Function VolumeFinder()
String expDiskFolderName, expDataFileName
String FileList, ThisFile, wName
Variable FileLoop, nWaves, i
NewPath/O/Q/M="Please find disk folder" ExpDiskFolder
if (V_flag!=0)
DoAlert 0, "Disk folder error"
Return -1
endif
PathInfo /S ExpDiskFolder
ExpDiskFolderName=S_path
FileList=IndexedFile(expDiskFolder,-1,".tif")
Variable nFiles=ItemsInList(FileList)
Variable /G vol
Variable /G nI
Make/O/D/N=(nFiles) volWave, volHWave
Make/O/T/N=(nFiles) fileWave
Make/O/D/N=(nFiles) nPointWave
for (FileLoop = 0; FileLoop < nFiles; FileLoop += 1)
ThisFile = StringFromList(FileLoop, FileList)
expDataFileName = ReplaceString(".tif",ThisFile,"") // get rid of .tif
expDataFileName = ReplaceString(".labels",expDataFileName,"") // get rid of .labels
ImageLoad/O/T=tiff/C=-1/LR3D/Q/P=expDiskFolder ThisFile
VolumeCalc($ThisFile)
fileWave[FileLoop] = expDataFileName
volWave[FileLoop] = vol
nPointWave[FileLoop] = nI
Wave kCloud // path of the 3D convex hull
wName = expDataFileName + "_kCloud"
Rename kCloud $wName
Wave HullWave // 1D wave of polygonarea for each 2D hull per layer
volHWave[FileLoop] = sum(HullWave)
wName = expDataFileName + "_HullWave"
Rename HullWave $wName
Wave pCloud // point cloud of all pixels over threshold
wName = expDataFileName + "_pCloud"
Rename pCloud $wName
Wave LayerWave // number of pixels over threshold per layer
wName = expDataFileName + "_LayerWave"
Rename LayerWave $wName
wName = expDataFileName + "_LDens"
MatrixOp/O $wName = LayerWave / HullWave
WaveTransform zapnans $wName
KillWaves /Z $ThisFile //should already be killed
endfor
Duplicate nPointWave densityWave
densityWave /= volWave
//Display results
DoWindow/K Results
Edit/N=Results fileWave,nPointWave,volWave,densityWave,volHWave
DoWindow/K MTvol
Display/N=MTvol nPointWave vs fileWave
ModifyGraph swapXY=1
SetAxis/A/R left
SetAxis/A/E=1/N=1 bottom
Label bottom "Point Volume"
DoWindow/K Spindlevol
Display/N=spindlevol volWave vs fileWave
ModifyGraph swapXY=1
SetAxis/A/R left
SetAxis/A/E=1/N=1 bottom
Label bottom "Hull Volume"
DoWindow/K Density
Display/N=densityvol densityWave vs fileWave
ModifyGraph swapXY=1
SetAxis/A/R left
SetAxis/A/E=1/N=1 bottom
Label bottom "Density"
DoWindow/K summaryLayout
NewLayout/N=summaryLayout
AppendLayoutObject/W=summaryLayout graph MTvol
AppendLayoutObject/W=summaryLayout graph spindlevol
AppendLayoutObject/W=summaryLayout graph densityvol
#If igorversion()>=7
LayoutPageAction size(-1)=(595, 842), margins(-1)=(18, 18, 18, 18)
#EndIf
ModifyLayout units=0
ModifyLayout frame=0,trans=1
Execute /Q "Tile"
ScaleIt(12,12,60)
End
// This function does the calculations for each dataset
/// @param m0 matrix for processing
Function VolumeCalc(m0)
Wave m0
Variable timer = startmstimer
NVAR /Z vol
NVAR /Z nI //global variables
nI = Dimsize(m0,0)
Variable nJ = Dimsize(m0,1)
Variable nK = Dimsize(m0,2)
Make/O/N=((nI*nJ*nK),3) m1 = NaN //slows code but worth it
Variable l = 0 // rows in result wave
vol = 0
Variable tempvar, V_value
Variable i, j, k
For (k = 0; k < nK; k += 1) // layers
For (j = 0; j < nJ; j += 1) // columns
For (i = 0; i < nI; i += 1) // rows
If (m0[i][j][k] != 0)
m1[l][0] = i
m1[l][1] = j
m1[l][2] = k
l += 1
EndIf
EndFor
EndFor
EndFor
MatrixOp/O w0 = sumRows(m1)
WaveTransform ZapNans w0
nI = numpnts(w0)
Duplicate/O/R=(0,nI-1) m1, pCloud
KillWaves w0, m1, m0 // also gets rid of image to free memory
Duplicate/O/R=[*][2] pCloud, pCloudZ
Redimension/N=-1 pCloudZ
Make/O/N=(nK) HullWave = 0, LayerWave = 0
// HullWave will hold the area of each convex hull per layer
// LayerWave will hold the number of pixels that are over threshold in that layer
String wName, wList
For (k = 0; k < nK; k += 1) // layers
FindValue/V=(k) /Z pCloudZ
If(V_Value > -1) // test to see if it's worth calculating this layer
Duplicate/O/R=[*][0] pCloud, pCloudX
Duplicate/O/R=[*][1] pCloud, pCloudY
Redimension/N=-1 pCloudX, pCloudY
pCloudX = (pCloudZ == k) ? pCloudX : NaN
pCloudY = (pCloudZ == k) ? pCloudY : NaN
WaveTransform zapnans pCloudX
WaveTransform zapnans pCloudY
LayerWave[k] = numpnts(pCloudX)
Convexhull /C pCloudX, pCloudY
Wave W_XHull, W_YHull
HullWave[k] = PolygonArea(W_XHull,W_YHull)
Duplicate/O W_XHull, W_ZHull
W_ZHull = k
wName = "kCloud_" + num2str(k)
Concatenate/O/KILL {W_XHull,W_YHull,W_ZHull}, $wName
EndIf
EndFor
wList=WaveList("kCloud_*",";","")
Concatenate/O/KILL/NP=0 wList, kCloud
Triangulate3D/VOL kCloud
vol = V_Value
KillWaves pCloudX, pCloudY, pCloudZ
printf "%g\r", stopmstimer(timer)/1e6
End
/// @param xnm voxel size, x dimension in nm, i.e. 12
/// @param ynm voxel size, y dimension in nm, i.e. 12
/// @param znm voxel size, z dimension in nm, i.e. 60
Function ScaleIt(xnm,ynm,znm)
Variable xnm, ynm, znm
//This will scale the points to real world values
Variable scale = (xnm * ynm * znm) / (10^9) //in µm^3
//need to scale MTs in a different way
If(xnm != ynm)
Print "xnm and ynm are not equal. Please check"
EndIf
Variable MTscale = ((1/3) * (xnm * ((PI*12.5)^2))) / (10^9)
// assumes MTs are 3 px wide and are single MTs
// scale to µm^3
Wave nPointWave, volWave
nPointWave *=MTscale
volWave *=scale
Label /W=MTvol bottom, "Point Volume (µm\S3\M)"
Label /W=spindlevol bottom, "Hull Volume (µm\S3\M)"
End