Skip to content

Commit c55cf26

Browse files
authored
Merge pull request #17 from templiert/multisem
review of PR #16
2 parents 2e66855 + 009b3a9 commit c55cf26

File tree

6 files changed

+68
-25
lines changed

6 files changed

+68
-25
lines changed

src/python/janelia_emrp/msem/field_of_view_layout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def __init__(self,
233233

234234
def row_and_col(self,
235235
mfov_number: int,
236-
sfov_index_name: str) -> (int, int):
236+
sfov_index_name: str) -> Tuple[int, int]:
237237
row_offset, col_offset = self.mfov_number_to_offsets[mfov_number]
238238
sfov_row, sfov_col = self.sfov_index_name_to_row_col[sfov_index_name]
239239
return sfov_row + row_offset, sfov_col + col_offset

src/python/janelia_emrp/msem/ingestion_ibeammsem/assembly.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
import numpy as np
1212
from dask import bag
1313
from distributed import Client
14-
from matplotlib.transforms import Affine2D
15-
from skimage.io import imread
16-
from skimage.transform import EuclideanTransform
17-
1814
from janelia_emrp.msem.ingestion_ibeammsem.constant import FACTOR_THUMBNAIL, N_BEAMS
1915
from janelia_emrp.msem.ingestion_ibeammsem.path import get_image_paths, get_slab_path
2016
from janelia_emrp.msem.ingestion_ibeammsem.roi import get_mfovs
2117
from janelia_emrp.msem.ingestion_ibeammsem.xdim import XDim
2218
from janelia_emrp.msem.ingestion_ibeammsem.xvar import XVar
19+
from matplotlib.transforms import Affine2D
20+
from skimage.io import imread
21+
from skimage.transform import EuclideanTransform
2322

2423
matplotlib.use("tkagg")
2524

@@ -29,6 +28,23 @@
2928
import xarray as xr
3029

3130

31+
def get_max_scans(xlog: xr.Dataset) -> int:
32+
"""Gets the maximum number of scans.
33+
34+
The xlog is conservatively over-dimensioned upfront along XDim.SCAN
35+
to accommodate all anticipated scans.
36+
37+
The prediction of the number of scans is made by IBEAM-MSEM operators
38+
considering the nominal slab thickness
39+
and the material removal thickness at every scan.
40+
41+
Note that scans with strictly negative labels exist,
42+
but they are internals of the IBEAM-MSEM process
43+
and must not be ingested.
44+
"""
45+
return 1 + xlog[XDim.SCAN].max().values.item()
46+
47+
3248
def get_slab_rotation(xlog: xr.Dataset, scan: int, slab: int) -> float:
3349
"""Returns the rotation of a slab, in degrees.
3450

src/python/janelia_emrp/msem/ingestion_ibeammsem/id.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,22 @@
1515

1616

1717
def get_all_magc_ids(xlog: xr.Dataset) -> np.ndarray:
18-
"""Gets all MagC IDs of the wafer."""
18+
"""Gets all MagC IDs of the wafer.
19+
20+
Note that MagC IDs
21+
are not guaranteed to be contiguous, e.g., [0,1,3,5]
22+
and do not necessarily start at 0.
23+
Therefore use
24+
for magc_id in get_all_magc_ids(xlog)
25+
instead of
26+
for magc_id in range(len(get_all_magc_ids(xlog)))
27+
"""
1928
return xlog[XDim.SLAB].values
2029

2130

2231
def get_serial_ids(
2332
xlog: xr.Dataset, magc_ids: list[int] | np.ndarray
24-
) -> int | None | list[int | None]:
33+
) -> list[int | None]:
2534
"""Returns the serial IDs of slabs identified by their MagC IDs.
2635
2736
If a magc_id does not have a serial ID, then returns None.

src/python/janelia_emrp/msem/ingestion_ibeammsem/roi.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import matplotlib.pyplot as plt
88
import numpy as np
9-
109
from janelia_emrp.msem.ingestion_ibeammsem.constant import N_BEAMS
1110
from janelia_emrp.msem.ingestion_ibeammsem.xdim import XDim
1211
from janelia_emrp.msem.ingestion_ibeammsem.xvar import XVar
@@ -104,6 +103,20 @@ def get_n_mfovs(xlog: xr.Dataset, scan: int) -> int:
104103
)
105104

106105

106+
def get_max_mfovs_per_slab(xlog: xr.Dataset) -> int:
107+
"""Gets the maximum number of MFOVs per slab.
108+
109+
The xlog is dimensioned along XDim.MFOV to fit the slab with the most MFOVs.
110+
E.g.: if the largest slab has 24 MFOVs,
111+
then the positive labels of the XDim.MFOV are [0,...,23].
112+
113+
Note that MFOVs with strictly negative IDs exist,
114+
but are internals of the IBEAM-MSEM acquisition
115+
and are not part of the final dataset.
116+
"""
117+
return 1 + xlog[XDim.MFOV].max().values.item()
118+
119+
107120
def get_mfovs(xlog: xr.Dataset, slab: int) -> np.ndarray:
108121
"""Returns the effective MFOV IDs of a slab.
109122

src/python/janelia_emrp/msem/msem_to_render.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
from janelia_emrp.fibsem.volume_transfer_info import params_to_render_connect
1818
from janelia_emrp.msem.field_of_view_layout import FieldOfViewLayout, build_mfov_column_group, \
1919
NINETY_ONE_SFOV_ADJACENT_MFOV_DELTA_Y, NINETY_ONE_SFOV_NAME_TO_ROW_COL
20-
from janelia_emrp.msem.ingestion_ibeammsem.assembly import get_xys_sfov_and_paths
20+
from janelia_emrp.msem.ingestion_ibeammsem.assembly import get_xys_sfov_and_paths, get_max_scans
2121
from janelia_emrp.msem.ingestion_ibeammsem.metrics import get_timestamp
2222
from janelia_emrp.msem.scan_fit_parameters import ScanFitParameters, \
2323
build_fit_parameters_path, WAFER_60_61_SCAN_FIT_PARAMETERS
24-
from janelia_emrp.msem.slab_info import load_slab_info, ContiguousOrderedSlabGroup, MAX_NUMBER_OF_SCANS
24+
from janelia_emrp.msem.slab_info import load_slab_info, ContiguousOrderedSlabGroup
2525
from janelia_emrp.root_logger import init_logger
2626

2727
program_name = "msem_to_render.py"
@@ -163,7 +163,7 @@ def import_slab_stacks_for_wafer(render_ws_host: str,
163163
import_magc_slab_list: list[int],
164164
include_scan_list: list[int],
165165
exclude_scan_list: list[int],
166-
wafer_id: int,
166+
wafer_id: str,
167167
number_of_slabs_per_render_project: int):
168168

169169
func_name = "import_slab_stacks_for_wafer"
@@ -176,6 +176,9 @@ def import_slab_stacks_for_wafer(render_ws_host: str,
176176
raise RuntimeError(f"cannot find wafer xlog: {wafer_xlog_path}")
177177

178178
logger.info(f"{func_name}: loading slab info, wafer_id={wafer_id}, number_of_slabs_per_group={number_of_slabs_per_render_project}")
179+
180+
n_scans_max = get_max_scans(xlog=xlog)
181+
logger.info(f"the maximum number of scans is {n_scans_max}")
179182

180183
slab_group_list = load_slab_info(xlog=xlog,
181184
wafer_id=wafer_id,
@@ -244,7 +247,7 @@ def import_slab_stacks_for_wafer(render_ws_host: str,
244247
logger.warning(f'{func_name}: scan {scan} not found for stack {stack}')
245248
else:
246249
# build scan list by looking for first mfov timestamps for all scans and ignoring excluded scans
247-
for scan in range(0, MAX_NUMBER_OF_SCANS):
250+
for scan in range(0, n_scans_max):
248251
first_mfov_scan_timestamp = get_timestamp(xlog=xlog, scan=scan, slab=slab_info.magc_id, mfov=slab_info.first_mfov)
249252
if first_mfov_scan_timestamp is not None:
250253
if scan not in exclude_scan_list:
@@ -389,7 +392,7 @@ def main(arg_list: List[str]):
389392
parser.add_argument(
390393
"--wafer_id",
391394
help="Wafer identifier (e.g. 60)",
392-
type=int,
395+
type=str,
393396
required=True
394397
)
395398
parser.add_argument(

src/python/janelia_emrp/msem/slab_info.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,31 @@
88
from janelia_emrp.msem.ingestion_ibeammsem.id import get_all_magc_ids, get_serial_ids, get_region_ids
99
from janelia_emrp.msem.ingestion_ibeammsem.roi import get_mfovs
1010

11-
WAFER_NAME_LEN = 2 # wafers 60 and 61
1211
SERIAL_NAME_LEN = 3 # 400+ slabs per wafer
1312
REGION_NAME_LEN = 2 # usually only a few regions per slab, but allow for up to 99
1413

15-
MAX_NUMBER_OF_MFOVS = 100
1614
MAX_NUMBER_OF_SCANS = 500
1715

1816
@dataclass
1917
class SlabInfo:
20-
wafer_id: int
21-
serial_id: int # order in which the slabs were physically cut
18+
wafer_id: str
19+
serial_id: int
20+
"""order in which the slabs were physically cut"""
21+
magc_id: int = field(compare=False)
22+
"""magc ID.
23+
24+
order in which the slabs were originally defined by the user
25+
with the MagFinder plugin in the .magc file
26+
"""
2227
region: int
23-
magc_id: int = field(compare=False) # order in which the slabs were originally defined by the user with the MagFinder plugin in the .magc file
2428
first_mfov: int = field(compare=False)
2529
last_mfov: int = field(compare=False)
2630
serial_name: str = field(init=False, repr=False)
2731
stack_name: str = field(init=False)
2832

2933
def __post_init__(self):
3034
self.serial_name = f"{self.serial_id:0{SERIAL_NAME_LEN}}"
31-
self.stack_name = f"w{self.wafer_id:0{WAFER_NAME_LEN}}_s{self.serial_name}_r{self.region:0{REGION_NAME_LEN}}"
35+
self.stack_name = f"w{self.wafer_id}_s{self.serial_name}_r{self.region:0{REGION_NAME_LEN}}"
3236

3337
def build_mfov_position_list(self,
3438
xlog: xarray.Dataset,
@@ -59,16 +63,14 @@ def to_render_project_name(self,
5963

6064

6165
def load_slab_info(xlog: xarray.Dataset,
62-
wafer_id: int,
66+
wafer_id: str,
6367
number_of_slabs_per_group: int) -> list[ContiguousOrderedSlabGroup]:
6468

6569
magc_ids = get_all_magc_ids(xlog=xlog).tolist()
66-
serial_ids = get_serial_ids(xlog=xlog, magc_ids=magc_ids)
6770

6871
slabs: list[SlabInfo] = []
69-
for i in range(len(magc_ids)):
70-
id_serial=serial_ids[i]
71-
slab = magc_ids[i]
72+
for slab in magc_ids:
73+
id_serial=get_serial_ids(xlog=xlog,magc_ids=[slab])[0]
7274
mfovs = get_mfovs(xlog=xlog, slab=slab)
7375
region_ids = get_region_ids(xlog=xlog, slab=slab, mfovs=mfovs)
7476
id_region = region_ids[0]
@@ -128,7 +130,7 @@ def main(argv: list[str]):
128130
print(f"loading slab info with wafer_id {argv[2]} and {argv[3]} number_of_slabs_per_group ...")
129131
number_of_slabs_per_group=int(argv[3])
130132
slab_groups = load_slab_info(xlog=xlog,
131-
wafer_id=int(argv[2]),
133+
wafer_id=argv[2],
132134
number_of_slabs_per_group=number_of_slabs_per_group)
133135
for slab_group in slab_groups:
134136
print(f"render project: {slab_group.to_render_project_name(number_of_slabs_per_group)} "

0 commit comments

Comments
 (0)