Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies = [
"h5py>=3.14.0",
"natsort>=8.4.0",
"notebook>=7.5.1",
"opencv-python>=4.12.0.88",
"pandas-stubs==2.3.2.250827",
"pymmcore-plus==0.13.7",
"pymmcore==11.2.1.71.0",
Expand Down
1 change: 0 additions & 1 deletion src/pyclm/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
Import modules that may be used in creating custom pattern and segmentation methods
"""

from ..directories import experiment_from_toml, schedule_from_directory
from .experiments import ExperimentSchedule
from .manager import Manager, MicroscopeOutbox, SLMBuffer
from .microscope import MicroscopeProcess
Expand Down
92 changes: 38 additions & 54 deletions src/pyclm/core/patterns/bar_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class BarPatternBase(PatternMethod):
"""
Creates a BarPattern or StationaryBarPattern depending on the requested barspeed
"""

def __new__(cls, *args, **kwargs):
if cls is BarPatternBase: # Check if the base class is being instantiated
if kwargs.get("bar_speed") != 0:
Expand All @@ -16,7 +17,6 @@ def __new__(cls, *args, **kwargs):
return super().__new__(cls)

def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)
print(f"Initializing {self.__class__.__name__}")

Expand All @@ -28,28 +28,22 @@ class StationaryBarPattern(BarPatternBase):

name = "bar (stationary)"

def __init__(self, experiment_name, camera_properties, duty_cycle=0.2, bar_speed=0, period=30, **kwargs):
def __init__(self, duty_cycle=0.2, bar_speed=0, period=30, **kwargs):
"""
:param duty_cycle: fraction of time spent on (float 0-1), and consequently fraction of
vertical axis containing "on" pixels
:param bar_speed: speed in um/min
:param period: period in um
"""
super().__init__(experiment_name, camera_properties)
super().__init__(**kwargs)

self.duty_cycle = duty_cycle
self.bar_speed = 0
self.period_space = period # in um
self.period_time = 0 # in minutes

def initialize(self, experiment):
super().initialize(experiment)

return []

def generate(self, data_dock: DataDock):
self.period_space = period # in um
self.period_time = 0 # in minutes

xx, yy = self.get_meshgrid()
def generate(self, context):
_xx, yy = self.get_meshgrid()

is_on = ((yy / self.period_space) % 1.0) < self.duty_cycle

Expand All @@ -63,86 +57,76 @@ class BarPattern(BarPatternBase):

name = "bar"

def __init__(self, experiment_name, camera_properties, duty_cycle=0.2, bar_speed=1, period=30, **kwargs):
def __init__(self, duty_cycle=0.2, bar_speed=1, period=30, **kwargs):
"""
:param duty_cycle: fraction of time spent on (float 0-1), and consequently fraction of
vertical axis containing "on" pixels
:param bar_speed: speed in um/min
:param period: period in um
"""
super().__init__(experiment_name, camera_properties)
super().__init__(**kwargs)

self.duty_cycle = duty_cycle
self.bar_speed = bar_speed
self.period_space = period # in um
self.period_time = period / bar_speed # in minutes

def initialize(self, experiment):
super().initialize(experiment)

return []

def generate(self, data_dock: DataDock):

t = data_dock.time_seconds / 60

xx, yy = self.get_meshgrid()

is_on = ((t - (yy / self.bar_speed)) % self.period_time) < self.duty_cycle*self.period_time
self.period_space = period # in um
self.period_time = period / bar_speed # in minutes

def _get_pattern_at_time(self, t_minutes):
_xx, yy = self.get_meshgrid()
is_on = (
(t_minutes - (yy / self.bar_speed)) % self.period_time
) < self.duty_cycle * self.period_time
return is_on.astype(np.float16)

def generate(self, context):
return self._get_pattern_at_time(context.time / 60)

class SawToothMethod(PatternMethod):

class SawToothMethod(PatternMethod):
name = "sawtooth"

def __init__(self, experiment_name, camera_properties, duty_cycle=0.2,
bar_speed=1, period=30, inverse=False, **kwargs):
def __init__(self, duty_cycle=0.2, bar_speed=1, period=30, inverse=False, **kwargs):
"""
:param duty_cycle: fraction of time spent on (float 0-1), and consequently fraction of
vertical axis containing "on" pixels
:param bar_speed: speed in um/min
:param period: period in um
"""
super().__init__(experiment_name, camera_properties)
super().__init__(**kwargs)

self.duty_cycle = duty_cycle
self.bar_speed = bar_speed
self.period_space = period # in um
self.period_time = period / bar_speed # in minutes
self.inverse = inverse

def initialize(self, experiment):
super().initialize(experiment)

return []

def generate(self, data_dock: DataDock):
t = data_dock.time_seconds / 60
def generate(self, context):
t = context.time / 60

xx, yy = self.get_meshgrid()
_xx, yy = self.get_meshgrid()

is_on = ((t - (yy / self.bar_speed)) % self.period_time) < self.duty_cycle * self.period_time
is_on = (
(t - (yy / self.bar_speed)) % self.period_time
) < self.duty_cycle * self.period_time

val = ((t - (yy / self.bar_speed)) % self.period_time) / (self.duty_cycle * self.period_time)
val = ((t - (yy / self.bar_speed)) % self.period_time) / (
self.duty_cycle * self.period_time
)

if not self.inverse:
val = 1 - val

pattern_out = (is_on*val).astype(np.float16)
pattern_out = (is_on * val).astype(np.float16)

print(np.min(pattern_out), np.max(pattern_out))

return pattern_out


class BouncingBarPattern(BarPattern):

name = "bar_bounce"

def __init__(self, experiment_name, camera_properties, duty_cycle=0.2,
bar_speed=1, period=30, t_loop=60, **kwargs):
def __init__(self, duty_cycle=0.2, bar_speed=1, period=30, t_loop=60, **kwargs):
"""

:param duty_cycle: fraction of time spent on (float 0-1), and consequently fraction of
Expand All @@ -151,18 +135,18 @@ def __init__(self, experiment_name, camera_properties, duty_cycle=0.2,
:param period: period in um
:param t_loop: period of reversal (there and back) in minutes
"""
super().__init__(experiment_name, camera_properties, duty_cycle, bar_speed, period, **kwargs)
super().__init__(
duty_cycle=duty_cycle, bar_speed=bar_speed, period=period, **kwargs
)
self.t_loop_s = t_loop * 60

def generate(self, data_dock: DataDock):
t = data_dock.time_seconds
def generate(self, context):
t = context.time
t = t % self.t_loop_s

halfway = self.t_loop_s / 2

if t > halfway:
t = halfway - (t - halfway)

data_dock.time_seconds = t

return super().generate(data_dock)
return self._get_pattern_at_time(t / 60)
Loading