Skip to content

Commit

Permalink
Merge pull request #81 from tdincer/main
Browse files Browse the repository at this point in the history
Apply the fix scan duration & code refactoring to this branch
  • Loading branch information
kabilar authored Jun 29, 2022
2 parents 00df443 + a2535aa commit 74a7bf4
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 63 deletions.
34 changes: 13 additions & 21 deletions element_calcium_imaging/imaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,10 @@ def key_source(self):
return ProcessingTask & scan.ScanInfo

def make(self, key):
task_mode = (ProcessingTask & key).fetch1("task_mode")
task_mode, output_dir = (ProcessingTask & key).fetch1(
"task_mode", "processing_output_dir"
)

output_dir = (ProcessingTask & key).fetch1("processing_output_dir")
output_dir = find_full_path(get_imaging_root_data_dir(), output_dir).as_posix()
if not output_dir:
output_dir = ProcessingTask.infer_output_dir(key, relative=True, mkdir=True)
Expand Down Expand Up @@ -264,6 +265,15 @@ def make(self, key):
ProcessingTask * ProcessingParamSet * ProcessingMethod * scan.Scan & key
).fetch1("processing_method")

image_files = (
ProcessingTask * scan.Scan * scan.ScanInfo * scan.ScanInfo.ScanFile
& key
).fetch("file_path")
image_files = [
find_full_path(get_imaging_root_data_dir(), image_file)
for image_file in image_files
]

if method == "suite2p":
import suite2p

Expand All @@ -275,15 +285,6 @@ def make(self, key):
ProcessingTask * scan.Scan * scan.ScanInfo & key
).fetch1("fps")

image_files = (
ProcessingTask * scan.Scan * scan.ScanInfo * scan.ScanInfo.ScanFile
& key
).fetch("file_path")
image_files = [
find_full_path(get_imaging_root_data_dir(), image_file)
for image_file in image_files
]

input_format = pathlib.Path(image_files[0]).suffix
suite2p_params["input_format"] = input_format[1:]

Expand All @@ -301,15 +302,6 @@ def make(self, key):
elif method == "caiman":
from element_interface.run_caiman import run_caiman

tiff_files = (
ProcessingTask * scan.Scan * scan.ScanInfo * scan.ScanInfo.ScanFile
& key
).fetch("file_path")
tiff_files = [
find_full_path(get_imaging_root_data_dir(), tiff_file).as_posix()
for tiff_file in tiff_files
]

params = (ProcessingTask * ProcessingParamSet & key).fetch1("params")
sampling_rate = (
ProcessingTask * scan.Scan * scan.ScanInfo & key
Expand All @@ -325,7 +317,7 @@ def make(self, key):
"Caiman pipeline is not capable of analyzing 3D scans at the moment."
)
run_caiman(
file_paths=tiff_files,
file_paths=[f.as_posix() for f in image_files],
parameters=params,
sampling_rate=sampling_rate,
output_dir=output_dir,
Expand Down
38 changes: 15 additions & 23 deletions element_calcium_imaging/imaging_no_curation.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ class ProcessingTask(dj.Manual):
-> scan.Scan
-> ProcessingParamSet
---
processing_output_dir: varchar(255) # output directory of the processed scan relative to root data directory
task_mode='load': enum('load', 'trigger') # 'load': load computed analysis results, 'trigger': trigger computation
processing_output_dir: varchar(255) # output directory of the processed scan relative to root data directory
task_mode='load': enum('load', 'trigger') # 'load': load computed analysis results, 'trigger': trigger computation
"""

@classmethod
Expand Down Expand Up @@ -232,9 +232,10 @@ def key_source(self):
return ProcessingTask & scan.ScanInfo

def make(self, key):
task_mode = (ProcessingTask & key).fetch1("task_mode")
task_mode, output_dir = (ProcessingTask & key).fetch1(
"task_mode", "processing_output_dir"
)

output_dir = (ProcessingTask & key).fetch1("processing_output_dir")
output_dir = find_full_path(get_imaging_root_data_dir(), output_dir).as_posix()
if not output_dir:
output_dir = ProcessingTask.infer_output_dir(key, relative=True, mkdir=True)
Expand Down Expand Up @@ -264,6 +265,15 @@ def make(self, key):
ProcessingTask * ProcessingParamSet * ProcessingMethod * scan.Scan & key
).fetch1("processing_method")

image_files = (
ProcessingTask * scan.Scan * scan.ScanInfo * scan.ScanInfo.ScanFile
& key
).fetch("file_path")
image_files = [
find_full_path(get_imaging_root_data_dir(), image_file)
for image_file in image_files
]

if method == "suite2p":
import suite2p

Expand All @@ -275,15 +285,6 @@ def make(self, key):
ProcessingTask * scan.Scan * scan.ScanInfo & key
).fetch1("fps")

image_files = (
ProcessingTask * scan.Scan * scan.ScanInfo * scan.ScanInfo.ScanFile
& key
).fetch("file_path")
image_files = [
find_full_path(get_imaging_root_data_dir(), image_file)
for image_file in image_files
]

input_format = pathlib.Path(image_files[0]).suffix
suite2p_params["input_format"] = input_format[1:]

Expand All @@ -301,15 +302,6 @@ def make(self, key):
elif method == "caiman":
from element_interface.run_caiman import run_caiman

tiff_files = (
ProcessingTask * scan.Scan * scan.ScanInfo * scan.ScanInfo.ScanFile
& key
).fetch("file_path")
tiff_files = [
find_full_path(get_imaging_root_data_dir(), tiff_file).as_posix()
for tiff_file in tiff_files
]

params = (ProcessingTask * ProcessingParamSet & key).fetch1("params")
sampling_rate = (
ProcessingTask * scan.Scan * scan.ScanInfo & key
Expand All @@ -325,7 +317,7 @@ def make(self, key):
"Caiman pipeline is not capable of analyzing 3D scans at the moment."
)
run_caiman(
file_paths=tiff_files,
file_paths=[f.as_posix() for f in image_files],
parameters=params,
sampling_rate=sampling_rate,
output_dir=output_dir,
Expand Down
47 changes: 28 additions & 19 deletions element_calcium_imaging/scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,22 +208,6 @@ class ScanFile(dj.Part):
file_path: varchar(255) # filepath relative to root data directory
"""

@staticmethod
def estimate_scan_duration(scan_obj):
# Calculates scan duration for Nikon images
ti = (
scan_obj.frame_metadata(0).channels[0].time.absoluteJulianDayNumber
) # Initial frame's JD.
tf = (
scan_obj.frame_metadata(scan_obj.shape[0] - 1)
.channels[0]
.time.absoluteJulianDayNumber
) # Final frame's JD.
fps = (
1000 / scan_obj.experiment[0].parameters.periods[0].periodDiff.avg
) # Frame per second
return (tf - ti) * 86400 + 1 / fps

def make(self, key):
acq_software = (Scan & key).fetch1("acq_software")

Expand Down Expand Up @@ -378,6 +362,32 @@ def make(self, key):
nd2_file = nd2.ND2File(scan_filepaths[0])
is_multiROI = False # MultiROI to be implemented later

# Frame per second
try:
fps = 1000 / nd2_file.experiment[0].parameters.periods[0].periodDiff.avg
except:
fps = 1000 / nd2_file.experiment[0].parameters.periodDiff.avg

# Estimate ND2 file scan duration
def estimate_nd2_scan_duration(nd2_scan_obj):
# Calculates scan duration for Nikon images
ti = (
nd2_scan_obj.frame_metadata(0)
.channels[0]
.time.absoluteJulianDayNumber
) # Initial frame's JD.
tf = (
nd2_scan_obj.frame_metadata(nd2_scan_obj.shape[0] - 1)
.channels[0]
.time.absoluteJulianDayNumber
) # Final frame's JD.

return (tf - ti) * 86400 + 1 / fps

scan_duration = sum(
[estimate_nd2_scan_duration(nd2.ND2File(f)) for f in scan_filepaths]
)

# Insert in ScanInfo
self.insert1(
dict(
Expand All @@ -389,15 +399,14 @@ def make(self, key):
x=None,
y=None,
z=None,
fps=1000
/ nd2_file.experiment[0].parameters.periods[0].periodDiff.avg,
fps=fps,
bidirectional=bool(
nd2_file.custom_data["GrabberCameraSettingsV1_0"][
"GrabberCameraSettings"
]["PropertiesQuality"]["ScanDirection"]
),
nrois=0,
scan_duration=self.estimate_scan_duration(nd2_file),
scan_duration=scan_duration,
)
)

Expand Down

0 comments on commit 74a7bf4

Please sign in to comment.