Skip to content

Commit 43b9d1e

Browse files
authored
Merge pull request #39 from AllenInstitute/automate
Automate
2 parents 6cf96a7 + 1101420 commit 43b9d1e

File tree

9 files changed

+502
-270
lines changed

9 files changed

+502
-270
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from cmath import phase
2+
from acpreprocessing.utils import io
3+
import argschema
4+
from argschema.fields import Str
5+
import os
6+
import matplotlib.pyplot as plt
7+
import numpy as np
8+
9+
example_input = {
10+
"stitchDir": "/ACdata/processed/iSPIM2/MN8_S10_220211_high_res/stitch-s3/iter0",
11+
"filename": "pairwise-stitched.json",
12+
"d_name": "MN8_S10_220211_high_res",
13+
"save_dir": "/ACdata/processed/iSPIM2/MN8_S10_220211_high_res/stitch-s3/stitching_eval/"
14+
}
15+
16+
def normalize(data):
17+
norm_data = []
18+
dmin, dmax = min(data), max(data)
19+
for i, val in enumerate(data):
20+
norm_data.append((val-dmin) / (dmax-dmin))
21+
return norm_data
22+
23+
class GraphStitchCorr(argschema.ArgSchema):
24+
stitchDir = Str(required=True, description='stitch iter directory')
25+
filename = Str(required=False, default="pairwise-stitched.json", description='which json file to grab stitch data from')
26+
d_name = Str(required=True, description='dataset name')
27+
28+
class GraphStitchCorr(argschema.ArgSchemaParser):
29+
default_schema = GraphStitchCorr
30+
31+
def run(self):
32+
pairwise = io.read_json(os.path.join(self.args['stitchDir'], self.args["filename"]))
33+
n_pairs= len(pairwise)
34+
labels = []
35+
corrs = []
36+
variances = []
37+
displacement_z = []
38+
# displacement_x = []
39+
# displacement_y = []
40+
# phase_corrs = []
41+
for pair in pairwise:
42+
pair_label="{}&{}".format(pair[0]["tilePair"]["tilePair"][0]["index"],pair[0]["tilePair"]["tilePair"][1]["index"])
43+
labels.append(pair_label)
44+
variances.append(pair[0]["variance"])
45+
corrs.append(pair[0]["crossCorrelation"])
46+
# displacement_x.append(abs(pair[0]["displacement"][0]))
47+
# displacement_y.append(abs(pair[0]["displacement"][1]))
48+
displacement_z.append(abs(pair[0]["displacement"][2]))
49+
# phase_corrs.append(pair[0]["phaseCorrelation"])
50+
51+
52+
norm_var = normalize(variances)
53+
# norm_displ_x = normalize(displacement_x)
54+
# norm_displ_y = normalize(displacement_y)
55+
norm_displ_z = normalize(displacement_z)
56+
# norm_phase = normalize(phase_corrs)
57+
58+
plt.plot(labels, corrs, linestyle='--', marker='x', label="cross correlation")
59+
plt.legend(loc="upper left")
60+
plt.xticks(rotation = 90)
61+
plt.xlabel("Tile Pair")
62+
plt.ylabel("Cross Correlation")
63+
plt.title("Cross correlation for {}".format(self.args['d_name']))
64+
plt.savefig(self.args["save_dir"]+'crossCorr.png', bbox_inches = "tight")
65+
66+
plt.figure(2)
67+
plt.plot(labels, corrs, linestyle='--', marker='x', label="cross correlation")
68+
# plt.plot(labels, norm_displ_x, linestyle='--', marker='+', label="norm displacement x")
69+
# plt.plot(labels, norm_displ_y, linestyle='--', marker='+', label="norm displacement y")
70+
plt.plot(labels, norm_displ_z, linestyle='--', marker='+', label="norm displacement z")
71+
plt.legend(loc="upper left")
72+
plt.xticks(rotation = 90)
73+
plt.xlabel("Tile Pair")
74+
plt.ylabel("Values 0-1")
75+
plt.title("Cross correlation and Z Normalized Displacements for {}".format(self.args['d_name']))
76+
plt.savefig(self.args["save_dir"]+'with_z_displ.png', bbox_inches = "tight")
77+
78+
plt.figure(3)
79+
plt.plot(labels, corrs, linestyle='--', marker='x', label="cross correlation")
80+
plt.plot(labels, norm_var, linestyle='--', marker='.', label="norm variance")
81+
plt.legend(loc="lower left")
82+
plt.xticks(rotation = 90)
83+
plt.xlabel("Tile Pair")
84+
plt.ylabel("Values 0-1")
85+
plt.title("Cross correlation and Normalized Variance for {}".format(self.args['d_name']))
86+
plt.savefig(self.args["save_dir"]+'with_norm_vars.png', bbox_inches = "tight")
87+
88+
# plt.figure(4)
89+
# plt.plot(labels, corrs, linestyle='--', marker='x', label="cross correlation")
90+
# plt.plot(labels, phase_corrs, linestyle='--', marker='.', label="phase correlation")
91+
# plt.legend(loc="upper left")
92+
# plt.xticks(rotation = 90)
93+
# plt.xlabel("Tile Pair")
94+
# plt.ylabel("Values 0-1")
95+
# plt.title("Cross correlation and Phase Correlation for {}".format(self.args['d_name']))
96+
# plt.savefig(self.args["save_dir"]+'with_norm_phase.png', bbox_inches = "tight")
97+
98+
99+
if __name__ == '__main__':
100+
mod = GraphStitchCorr(example_input)
101+
mod.run()

acpreprocessing/utils/8bit.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
Basic script to convert existing n5 data to 8bit
3+
Used this for evaluation/experimentation of methods
4+
5+
@author: shbhas
6+
"""
7+
8+
import numpy as np
9+
import z5py
10+
11+
output_n5 = "/ACdata/processed/MN7_RH_3_9_S33_220405_high_res/MN7_RH_3_9_S33_220405_high_res.n5/"
12+
out_8bit = "/ACdata/processed/MN7_RH_3_9_S33_220405_high_res8bit/MN7_RH_3_9_S33_220405_high_res8bit.n5"
13+
fout = z5py.File(out_8bit)
14+
15+
for s in range(18,19):
16+
with z5py.File(output_n5, mode='r') as f:
17+
s0shape = f[f"setup{s}"]['timepoint0']["s5"].shape
18+
t = 4
19+
u = 9
20+
xyf = s0shape[1]/t
21+
zf = s0shape[0]/u
22+
print(s0shape)
23+
num_ints = np.iinfo(np.uint16).max + 1
24+
lut = np.uint8(np.sqrt(np.arange(num_ints)))
25+
26+
fout.create_group(f"setup{s}")
27+
fout[f"setup{s}"].create_group("timepoint0")
28+
ds = fout[f"setup{s}"]["timepoint0"].create_dataset("s5", shape=s0shape, chunks = (int(zf),int(xyf),int(xyf)), dtype='uint8')
29+
30+
for x in range(t):
31+
for y in range(t):
32+
for z in range(u):
33+
a = int(z*zf)
34+
bx = int(x*xyf)
35+
by = int(y*xyf)
36+
imvol = f[f"setup{s}"]['timepoint0']["s5"][a:int(a+zf), bx:int(bx+xyf), by:int(by+xyf)]
37+
fout[f"setup{s}"]["timepoint0"]["s5"][a:int(a+zf), bx:int(bx+xyf), by:int(by+xyf)] = lut[imvol]
38+
# print((a,int(a+zf),bx,int(bx+xyf),by,int(by+xyf)))

acpreprocessing/utils/metadata/parse_metadata.py

+11
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ def get_number_of_positions(self):
4242
"""Return number of position strips in section"""
4343
return len(self.md['positions'])
4444

45+
def get_number_of_channels(self):
46+
"""Return number of channels of data for section"""
47+
return self.md['channels']
48+
49+
def get_direction(self):
50+
"""Get direction of y direction for position strips in section"""
51+
if (self.md["positions"][0]["y_start_um"]) > (self.md["positions"][1]["y_start_um"]):
52+
return True
53+
else:
54+
return False
55+
4556
def get_size(self):
4657
"""Get tiff width, height, and number of frames in stack"""
4758
sz = [self.md['settings']['image_size_xy'][0],

acpreprocessing/utils/nglink/create_layer.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"outputDir": "/ACdata/processed/demoModules/output/",
77
"position": 2,
88
"rootDir": "/ACdata/processed/demoModules/raw/",
9-
"md_filename": "acqinfo_metadata.json"
9+
"md_filename": "acqinfo_metadata.json",
10+
"resolution": "high_res"
1011
}
1112

1213

@@ -65,6 +66,7 @@ class CreateLayerSchema(argschema.ArgSchema):
6566
reverse = Boolean(required=False,default=False, description="Whether to reverse direction of stitching or not")
6667
deskew = Int(required=False,default=0, description="deskew factor (0 if want to leave undeskewed)")
6768
channel = Int(required=True, default=1, description="channel number")
69+
resolution = Str(default="high_res", description="whether data is high_res or overview")
6870

6971
class NgLayer(argschema.ArgSchemaParser):
7072
default_schema = CreateLayerSchema
@@ -79,8 +81,10 @@ def run(self, state=None):
7981
md = parse_metadata.ParseMetadata(input_data=md_input)
8082
pr = md.get_pixel_resolution()
8183
sz = md.get_size()
82-
ypos = sz[1]-md.get_overlap() # subtract height of image by pixel overlap to get yposition
83-
84+
if self.args["resolution"] == "high_res":
85+
ypos = sz[1]-md.get_overlap() # subtract height of image by pixel overlap to get yposition
86+
elif self.args["resolution"] == "overview":
87+
ypos = sz[1]
8488
if self.args["reverse"]:
8589
layer0 = create_layer(self.args['outputDir'], self.args['position'],
8690
-1*ypos, pr, self.args['deskew'], self.args['channel'])
@@ -100,7 +104,10 @@ def run_consolidate(self, state=None):
100104
pr = md.get_pixel_resolution()
101105
sz = md.get_size()
102106
n_pos = md.get_number_of_positions()
103-
ypos = sz[1]-md.get_overlap() # subtract height of image by pixel overlap to get yposition
107+
if self.args["resolution"] == "high_res":
108+
ypos = sz[1]-md.get_overlap() # subtract height of image by pixel overlap to get yposition
109+
elif self.args["resolution"] == "overview":
110+
ypos = sz[1]
104111
# Create the layer
105112
if self.args["reverse"]:
106113
layer = create_layer(self.args['outputDir'], self.args['position'],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from acpreprocessing.utils.nglink import create_layer, create_nglink
2+
from argschema.fields import Dict
3+
import argschema
4+
import os
5+
6+
example_input = {
7+
"run_input": {
8+
"outputDir": "/ACdata/processed/demoModules/output/",
9+
"rootDir": "/ACdata/processed/demoModules/raw/",
10+
"ds_name": "MN6_2_S83_220531_high_res",
11+
"mip_level": 3,
12+
"md_filename": "/ACdata/processed/demoModules/raw/acqinfo_metadata.json",
13+
"consolidate_pos": True,
14+
"reverse_stitch": False,
15+
"deskew": False
16+
}
17+
}
18+
19+
20+
class CreateOverviewSchema(argschema.ArgSchema):
21+
run_input = argschema.fields.Dict(required=True, description='Input json for processing')
22+
23+
class Overview(argschema.ArgSchemaParser):
24+
default_schema = CreateOverviewSchema
25+
26+
def run(self, n_channels, n_pos, dirname, deskew, state=None):
27+
if not state:
28+
state = {"showDefaultAnnotations": False, "layers": []}
29+
for channel in range(n_channels):
30+
for pos in range(n_pos):
31+
if self.args["run_input"]["consolidate_pos"]:
32+
layer_input = {
33+
"position": 0,
34+
"outputDir": self.args["run_input"]['outputDir']+dirname+".n5/channel"+str(channel),
35+
"rootDir": self.args["run_input"]['rootDir'],
36+
"reverse": self.args["run_input"]["reverse_stitch"],
37+
"deskew": deskew,
38+
"channel": channel,
39+
"resolution": dirname.split("_")[-1]
40+
}
41+
create_layer.NgLayer(input_data=layer_input).run_consolidate(state)
42+
break
43+
else:
44+
layer_input = {
45+
"position": pos,
46+
"outputDir": self.args["run_input"]['outputDir']+dirname+".n5/channel"+str(channel),
47+
"rootDir": self.args["run_input"]['rootDir'],
48+
"reverse": self.args["run_input"]["reverse_stitch"],
49+
"deskew": deskew,
50+
"channel": channel,
51+
"resolution": dirname.split("_")[-1]
52+
}
53+
create_layer.NgLayer(input_data=layer_input).run(state)
54+
55+
# Create nglink from created state and estimated positions (overview link)
56+
nglink_input = {
57+
"outputDir": self.args["run_input"]['outputDir'],
58+
"fname": self.args["run_input"]["nglink_name"],
59+
"state_json": self.args["run_input"]["state_json"]
60+
}
61+
if not os.path.exists(os.path.join(nglink_input['outputDir'], nglink_input['fname'])):
62+
create_nglink.Nglink(input_data=nglink_input).run(state)
63+
else:
64+
print("nglink txt file already exists!")
65+
66+
67+
if __name__ == '__main__':
68+
mod = Overview(input_data=example_input).run()
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""
2+
Basic script to split channels of acquisition (on tiff level)
3+
Used this before channel splitting was incorporated into n5 conversion
4+
5+
@author: shbhas
6+
"""
7+
8+
import os
9+
from natsort import natsorted, ns
10+
from acpreprocessing.utils import io
11+
from acpreprocessing.utils.metadata import parse_metadata
12+
13+
def sort_files(filedir):
14+
filelist = os.listdir(filedir)
15+
return natsorted(filelist, alg=ns.IGNORECASE)
16+
17+
outputdir = "/ACdata/processed/iSPIM2/MN7_RH_3_9_S19_220606_high_res/split_channels/"
18+
inputdir = "/ispim2_data/workflow_data/iSPIM2/MN7_RH_3_9_S19_220606_high_res/"
19+
md_input = {
20+
"rootDir": "/ispim2_data/workflow_data/iSPIM2/MN7_RH_3_9_S19_220606_high_res/",
21+
"fname": "acqinfo_metadata.json"
22+
}
23+
24+
n_pos = parse_metadata.ParseMetadata(input_data=md_input).get_number_of_positions()
25+
print(n_pos)
26+
if not os.path.isdir(outputdir):
27+
os.makedirs(outputdir)
28+
29+
for s in range(n_pos):
30+
index = 0
31+
posdir = inputdir+f"high_res_Pos{s}/"
32+
for inputfile in sort_files(posdir):
33+
print(inputfile)
34+
if inputfile[0]=='.':
35+
continue
36+
I = io.get_tiff_image(posdir+inputfile)
37+
if index%2==0:
38+
chan0 = I[0::2, : , :]
39+
chan1 = I[1::2, : , :]
40+
else:
41+
chan1 = I[0::2, : , :]
42+
chan0 = I[1::2, : , :]
43+
fname0 = outputdir + f"ch0/high_res_Pos{s}/"+"{0:05d}.tif".format(index)
44+
fname1 = outputdir + f"ch1/high_res_Pos{s}/"+"{0:05d}.tif".format(index)
45+
print(fname0)
46+
io.save_tiff_image(chan0, fname0)
47+
io.save_tiff_image(chan1, fname1)
48+
index += 1

0 commit comments

Comments
 (0)