Example #1
0
# triggering signal will be required at the beginning!


class FlashProtocol(Protocol):
    name = "flash protocol"

    def __init__(self):
        super().__init__()
        self.pause_duration = 1.
        self.flash_duration = 2.

    def get_stim_sequence(self):
        stimuli = [
            TriggerStimulus(),
            Pause(duration=self.pause_duration),
            FullFieldVisualStimulus(duration=self.flash_duration,
                                    color=(0, 255, 0)),
            Pause(duration=self.pause_duration),
            TriggerStimulus(),
            Pause(duration=self.pause_duration),
            FullFieldVisualStimulus(duration=self.flash_duration,
                                    color=(255, 0, 0)),
            Pause(duration=self.pause_duration),
        ]
        return stimuli


if __name__ == "__main__":
    trigger = ZmqTrigger(port="5555")
    st = Stytra(protocol=FlashProtocol(), scope_triggering=trigger)
Example #2
0
from stytra import Stytra

if __name__ == "__main__":
    from stytra.examples.gratings_exp import GratingsProtocol

    # We make a new instance of Stytra with this protocol as the only option:
    s = Stytra(protocol=GratingsProtocol(), stim_plot=True)
Example #3
0
        for i in range(self.n_looms):
            # The radius is only specified at the beginning and at the
            # end of expansion. More elaborate functional relationships
            # than linear can be implemented by specifying a more
            # detailed interpolation table

            radius_df = pd.DataFrame(
                dict(
                    t=[0, np.random.rand() * self.max_loom_duration],
                    radius=[0, np.random.rand() * self.max_loom_size],
                ))

            # We construct looming stimuli with the radius change specification
            # and a random point of origin within the projection area
            # (specified in fractions from 0 to 1 for each dimension)
            stimuli.append(
                LoomingStimulus(
                    background_color=(255, 255, 255),
                    circle_color=(0, 0, 0),
                    df_param=radius_df,
                    origin=(self.x_pos_pix, self.y_pos_pix),
                ))

        return stimuli


if __name__ == "__main__":
    # We make a new instance of Stytra with this protocol as the only option:
    s = Stytra(protocol=LoomingProtocol())
Example #4
0
        # Abituation phase:
        for _ in range(self.abituation_trials_n):
            stimuli.append(
                ClosedLoop1DGratings(
                    df_param=df,
                    grating_angle=np.pi / 2,
                    wave_shape="sine",
                    grating_period=1 / self.baseline_grating_freq,
                    grating_col_1=(255,) * 3,
                )
            )

        freq_list = self.grating_freq_list * self.trials_n
        shuffle(freq_list)

        # Actual acuity testing:
        for freq in freq_list:
            stimuli.append(
                ClosedLoop1DGratings(
                    df_param=df,
                    grating_angle=np.pi / 2,
                    wave_shape="sine",
                    grating_period=1 / freq,
                )
            )
        return stimuli


if __name__ == "__main__":
    s = Stytra(protocol=ClosedLoop1DProt())
Example #5
0
from pathlib import Path
from stytra import Stytra
from stytra.examples.gratings_exp import GratingsProtocol

REQUIRES_EXTERNAL_HARDWARE = False


class TrackingGratingsProtocol(GratingsProtocol):
    name = "gratings_tail_tracking"

    # To add tracking to a protocol, we simply need to add a tracking
    # argument to the stytra_config:
    stytra_config = dict(
        tracking=dict(embedded=True, method="tail"),
        camera=dict(video_file=str(
            Path(__file__).parent / "assets" / "fish_compressed.h5")),
    )


if __name__ == "__main__":
    s = Stytra(protocol=TrackingGratingsProtocol())
Example #6
0
from multiprocessing import Event
from stytra.collectors import FramerateQueueAccumulator

import qdarkstyle
from PyQt5.QtWidgets import QApplication
from stytra.hardware.video.write import VideoWriter
from stytra.stimulation import Protocol, Pause
from stytra.stimulation.stimuli import FullFieldVisualStimulus
from lightparam import Param

from stytra.experiments.tracking_experiments import CameraVisualExperiment
from stytra.tracking.tracking_process import DispatchProcess
from stytra import Stytra


# Here ve define an empty protocol:
class PauseProtocol(Protocol):
    name = "camera_recording_protocol"  # every protocol must have a name.

    def __init__(self):
        super().__init__()
        self.period_sec = Param(10.0, limits=(0.2, None))

    def get_stim_sequence(self):
        return [Pause(duration=self.period_sec)]


if __name__ == "__main__":
    st = Stytra(protocol=PauseProtocol(), recording=True)
        frozen = []

        for j, c in enumerate(choices):
            if c is None:
                coh.extend([0, 0])
                frozen.extend([1, 1])
            else:
                coh.extend([c, c])
                frozen.extend([0, 0])

            t.extend([j * d, (j + 1) * d])

        coherence_df = pd.DataFrame(dict(t=t, coherence=coh, frozen=frozen))

        return [
            RandomDotKinematogram(
                df_param=coherence_df,
                theta=self.theta * (np.pi / 180),
                dot_radius=self.dot_radius,
                color_dots=(0, 0, 0),
                color_bg=(255, 255, 255),
                velocity=self.velocity,
                max_coherent_for=self.max_coherent_for,
                dot_density=self.dot_density,
            )
        ]


if __name__ == "__main__":
    stytra = Stytra(protocol=Exp26Protocol())
Example #8
0
    def get_stim_sequence(self):
        stimuli = []
        # The phototaxis stimulus for zebrafish is bright on one side of the
        # fish and dark on the other. The type function combines two classes:
        stim = type("phototaxis", (FishTrackingStimulus, HalfFieldStimulus),
                    {})

        # The stimuli are a sequence of a phototactic stimulus and full-field
        # illumination
        for i in range(self.n_trials):

            # The stimulus of interest is wrapped in a CenteringStimulus,
            # so if the fish moves out of the field of view, a stimulus is
            # displayed which brings it back
            stimuli.append(
                CenteringWrapper(stimulus=stim(
                    duration=self.stim_on_duration,
                    color=(self.brightness, ) * 3,
                    center_dist=self.center_offset,
                )))

            stimuli.append(
                FullFieldVisualStimulus(color=(self.brightness, ) * 3,
                                        duration=self.stim_off_duration))

        return stimuli


if __name__ == "__main__":
    s = Stytra(protocol=PhototaxisProtocol())
Example #9
0
    name = 'voltage_protocol'

    def __init__(self):
        super().__init__()
        self.add_params(v_min=1., v_max=4., time_up=5., time_down=10.)

    def get_stim_sequence(self):
        v_list = [
            self.params['v_min'], self.params['v_max'], self.params['v_min']
        ]
        t_list = [0, self.params['time_up'], self.params['time_down']]
        df = pd.DataFrame(dict(t=t_list, voltage=v_list))
        # stimuli = [Pause(duration=1),
        #            SetVoltageStimulus(duration=1, voltage=0),
        #            SetVoltageStimulus(duration=1, voltage=1),
        #            SetVoltageStimulus(duration=1, voltage=2)
        #            ]
        stimuli = [InterpolatedVoltageStimulus(df_param=df)]
        return stimuli


if __name__ == "__main__":
    st = Stytra(protocols=[VoltageProtocol])
    st.base.close()
    # import nidaqmx
    from nidaqmx.stream_readers import AnalogSingleChannelReader
    from nidaqmx.stream_writers import AnalogSingleChannelWriter

    # with nidaqmx.Task() as task:
    #     task.ao_channels.add_ao_voltage_chan("Dev1/ao0")
    #     task.write(1.0)
Example #10
0
        super().__init__()
        self.theta = Param(0, (-360, 360))
        self.delta = Param(0, (-360, 360))

    def get_stim_sequence(self):
        MovingStim = type(
            "MovingStim",
            (FishRelativeStimulus, InterpolatedStimulus,
             SeamlessImageStimulus),
            dict(),
        )
        motion_df = pd.DataFrame(
            dict(t=[0, 10, 120], x=[50, 50, 1200], y=[50, 50, 50]))

        stimuli = [
            MovingStim(
                background=Path(__file__).parent / "assets" /
                "coordinate_system.png",
                df_param=motion_df,
                duration=300,
                x=self.delta,
                y=self.delta,
                theta=self.theta * np.pi / 180,
            )
        ]
        return stimuli


if __name__ == "__main__":
    st = Stytra(protocol=BackgroundProtocol())
from lightparam import Param
from stytra import Stytra
from stytra.stimulation import Protocol
from stytra.stimulation.stimuli import Pause

fa = 5  # repetition of stimulus


class PauseProtocol(Protocol):
    name = "free_swimming_protocol"

    stytra_config = dict(tracking=dict(method="fish"), log_format="hdf5")

    def __init__(self):
        super().__init__()
        # Specify parameters as Param(something) to change them from the interface. If yuo dont care, yust type the umbers
        self.duration = Param(600.0, limits=(20, 3000))

    def get_stim_sequence(self):

        stimuli = [Pause(duration=self.duration)]
        return stimuli


if __name__ == "__main__":
    # We make a new instance of Stytra with this protocol as the only option:
    s = Stytra(protocol=PauseProtocol())
Example #12
0
        LoomingStimulus = type("LoomingStimulus",
                               (InterpolatedStimulus, CircleStimulus), {})

        for i in range(self.params["n_looms"]):
            # The radius is only specified at the beginning and at the
            # end of expansion. More elaborate functional relationships
            # than linear can be implemented by specifying a more
            # detailed interpolation table

            radius_df = pd.DataFrame(
                dict(
                    t=[0,
                       np.random.rand() * self.params["max_loom_duration"]],
                    radius=[
                        0, np.random.rand() * self.params["max_loom_size"]
                    ],
                ))

            # We construct looming stimuli with the radius change specification
            # and a random point of origin within the projection area
            # (specified in fractions from 0 to 1 for each dimension)
            stimuli.append(LoomingStimulus(df_param=radius_df,
                                           origin=(30, 30)))

        return stimuli


if __name__ == "__main__":
    # We make a new instance of Stytra with this protocol as the only option
    s = Stytra(protocols=[LoomingProtocol])
Example #13
0
            return False


class FlashProtocol(Protocol):
    name = "flash protocol"

    def __init__(self):
        super().__init__()
        self.add_params(period_sec=5., flash_duration=2.)

    def get_stim_sequence(self):
        stimuli = [
            Pause(duration=self.params["period_sec"] -
                  self.params["flash_duration"]),
            FullFieldVisualStimulus(duration=self.params["flash_duration"],
                                    color=(255, 255, 255)),
        ]
        return stimuli


if __name__ == "__main__":
    # Select a directory:
    path = "."

    # Instantiate the trigger:
    trigger = NewFileTrigger(path)

    # Call stytra assigning the triggering. Note that stytra will wait for
    # the trigger only if the "wait for trigger" checkbox is ticked!
    st = Stytra(protocols=[FlashProtocol], trigger=trigger)
Example #14
0
from pathlib import Path
from stytra import Stytra
from stytra.examples.windmill_exp import WindmillProtocol

REQUIRES_EXTERNAL_HARDWARE = False


class TrackingWindmillProtocol(WindmillProtocol):
    name = "windmill"

    # To add tracking to a protocol, we simply need to add a tracking
    # argument to the stytra_config:
    stytra_config = dict(
        tracking=dict(embedded=True, method="eyes"),
        camera=dict(video_file=str(
            Path(__file__).parent / "assets" / "fish_compressed.h5")),
    )


if __name__ == "__main__":
    s = Stytra(protocol=TrackingWindmillProtocol())
Example #15
0
        t_base = [0, p, p, p + d, p + d, 2 * p + d]
        vel_base = [0, 0, -v, -v, 0, 0]
        t = [0]
        vel = [0]
        gain = [0]

        # Low, medium, high gain:
        for g in gain_values:
            t.extend(t[-1] + np.array(t_base))
            vel.extend(vel_base)
            gain.extend([0] * 2 + [g] * 2 + [0] * 2)

        df = pd.DataFrame(dict(t=t, base_vel=vel, gain=gain))

        ClosedLoop1DGratings = type("Stim",
                                    (GainLagClosedLoop1D, GratingStimulus), {})

        stimuli.append(
            ClosedLoop1DGratings(
                df_param=df,
                grating_angle=np.pi / 2,
                grating_period=self.grating_cycle,
                grating_col_1=(255, ) * 3,
            ))
        return stimuli


if __name__ == "__main__":
    Stytra(protocol=Portugues2011Protocol())
Example #16
0
class CombinedProtocol(Protocol):
    name = "combined_custom_protocol"  # every protocol must have a name.

    stytra_config = dict(
        tracking=dict(method="tail", estimator="vigor"),
        camera=dict(video_file=str(
            Path(__file__).parent / "assets" / "fish_compressed.h5")),
    )

    def get_stim_sequence(self):
        # This is the
        # Use six points to specify the velocity step to be interpolated:
        t = [0, 7]
        vel = np.array([10, 10])

        df = pd.DataFrame(dict(t=t, vel_x=vel))

        s_a = MovingGratingStimulus(df_param=df, clip_mask=[0, 0, 1, 0.5])

        df = pd.DataFrame(dict(t=t, vel_x=-vel))
        s_b = MovingGratingStimulus(df_param=df,
                                    grating_angle=180,
                                    clip_mask=[0, 0.5, 1, 0.5])

        stimuli = [ConditionalCombiner([s_a, s_b])]
        return stimuli


if __name__ == "__main__":
    st = Stytra(protocol=CombinedProtocol())
class FlashProtocol(Protocol):
    name = "flash protocol"

    def __init__(self):
        super().__init__()
        self.add_params(period_sec=5., flash_duration=2.)

    def get_stim_sequence(self):
        stimuli = [
            Pause(duration=self.params["period_sec"] -
                  self.params["flash_duration"]),
            FullFieldVisualStimulus(duration=self.params["flash_duration"],
                                    color=(255, 255, 255)),
        ]
        return stimuli


if __name__ == "__main__":
    # trigger = Crappy2PTrigger(r'C:\Users\lpetrucco\Desktop\dummydir')
    # trigger.start()
    trigger = ZmqTrigger(port="5555")
    st = Stytra(
        protocols=[FlashProtocol],
        trigger=trigger,
        directory=r"C:\Users\portugueslab\Desktop\metadata",
    )
    # trigger.terminate_event.set()
    # print('terminating')
    # trigger.join()
Example #18
0
        self.diet = Param("Humans", ["Humans", "Ships", "Unknown"])
        # Redefine age with units:
        self.age = Param(500, limits=(1, 10000), unit="years")
        # A simple integer, with limits:
        self.n_tentacles = Param(8, limits=(1, 200))
        # An integer with inferior boundary only (no upper limit for the terror):
        self.n_casualties = Param(8, limits=(1, None))
        # A simple float, with limits and measure units:
        self.dimensions = Param(8.0, limits=(0.5, 100), unit="m")

        # Some parameters are already defined in the AnimalMetadata class
        # (species, genotype, comments, id). Here we overwrite them:
        self.id = Param("")


# Define some uninteresting stytra protocol for our docile animal:
class FlashProtocol(Protocol):
    name = "empty_protocol"

    def get_stim_sequence(self):
        return [Pause(duration=4.0)]


# Finally, just pass Stytra the new class with the keyword "metadata_animal":
# Remember to pass the metadata class - KrakenMetadata - and not the object
# - KrakenMetadata().
# If you are testing Stytra functionalities you might want to remove the
# "stytra_last_config.json" file from user folder after testing this!
if __name__ == "__main__":
    st = Stytra(protocol=FlashProtocol(), metadata_animal=KrakenMetadata)
Example #19
0
# The "display overlay" attribute, which does not necessarily have to be
# specified, will allow us to overimpose on the GUI an ellipse to monitor
#  live our tracking.


class DrosophilaPipeline(Pipeline):
    def __init__(self):
        super().__init__()

        self.bgsub = BackgroundSubtractor(parent=self.root)
        self.eyetrack = FlyTrackingMethod(parent=self.bgsub)
        self.display_overlay = FlyTrackingSelection


# Here we define our stumulus protocol (empty in this case), passing in the
# config dictionary our custom pipeline:
class FlyTrackingProtocol(Protocol):
    name = "fly_tracking"
    stytra_config = dict(
        tracking=dict(method=DrosophilaPipeline),
        camera=dict(video_file=str(r"/Users/luigipetrucco/Desktop/video.hdf5")),
    )

    def get_stim_sequence(self):
        # Empty protocol of specified duration:
        return [Pause(duration=10)]


if __name__ == "__main__":
    s = Stytra(protocol=FlyTrackingProtocol())
Example #20
0
        self.inter_stim_pause = Param(2.)
        self.theta_amp = Param(np.pi / 2)
        self.windmill_freq = Param(0.2)
        self.grating_vel = Param(10)
        self.stim_duration = Param(5.)
        self.wave_shape = Param(value="square",
                                limits=["square", "sinusoidal"])
        self.n_arms = Param(10)

    def get_stim_sequence(self):
        stimuli = []
        p = self.inter_stim_pause / 2
        d = self.stim_duration

        # Windmill
        STEPS = 0.005
        t = np.arange(0, d, STEPS)
        theta = np.sin(2 * np.pi * t * self.windmill_freq) * self.theta_amp

        t = [t[0]] + list(t + p) + [(t + 2 * p)[-1]]
        theta = [theta[0]] + list(theta) + [theta[-1]]
        df = pd.DataFrame(dict(t=t, theta=theta))
        stimuli.append(MovingWindmillStimulus(df_param=df))
        return stimuli


if __name__ == "__main__":
    # We make a new instance of Stytra with this protocol as the only option:
    s = Stytra(protocol=WindmillProtocol())
Example #21
0
            gain.extend([0, 0, g, g, 0, 0])

        df = pd.DataFrame(dict(t=t, vel=vel, gain=gain))

        stimuli.append(ClosedLoop1DGratings(df,
                                            grating_angle=np.pi/2,
                                            grating_period=self.params[
                                                   'grating_cycle'],
                                            color=(255, )*3))
        return stimuli


if __name__ == "__main__":
    save_dir = r'D:\vilim\stytra\\'
    camera_config = dict(type="ximea")

    tracking_config = dict(
        embedded=True, tracking_method="angle_sweep", estimator="vigor"
    )

    display_config = dict(full_screen=True)

    # We make a new instance of Stytra with this protocol as the only option
    s = Stytra(
        protocols=[ClosedLoop1D],
        camera_config=camera_config,
        tracking_config=tracking_config,
        display_config=display_config,
        dir_save=save_dir,
    )
Example #22
0
        self.grating_period = Param(10)  # grating spatial period
        self.grating_angle_deg = Param(90.0)  # grating orientation

    def get_stim_sequence(self):
        # Use six points to specify the velocity step to be interpolated:
        t = [
            0,
            self.t_pre,
            self.t_pre,
            self.t_pre + self.t_move,
            self.t_pre + self.t_move,
            2 * self.t_pre + self.t_move,
        ]

        vel = [0, 0, self.grating_vel, self.grating_vel, 0, 0]

        df = pd.DataFrame(dict(t=t, vel_x=vel))

        return [
            MovingGratingStimulus(
                df_param=df,
                grating_angle=self.grating_angle_deg * np.pi / 180,
                grating_period=self.grating_period,
            )
        ]


if __name__ == "__main__":
    # We make a new instance of Stytra with this protocol as the only option
    s = Stytra(protocol=GratingsProtocol())
Example #23
0
    def paint(self, p, w, h):
        p.setBrush(QBrush(QColor(*self.color)))  # Use chosen color
        p.drawRect(QRect(0, 0, w, h))  # draw full field rectangle

    def update(self):
        fish_vel = self._experiment.estimator.get_velocity()
        # change color if speed of the fish is higher than threshold:
        if fish_vel < -5:
            self.color = (255, 0, 0)
        else:
            self.color = (255, 255, 255)


class CustomProtocol(Protocol):
    name = "custom protocol"  # protocol name

    stytra_config = dict(
        tracking=dict(method="tail", estimator="vigor"),
        camera=dict(
            video_file=str(Path(__file__).parent / "assets" / "fish_compressed.h5")
        ),
    )

    def get_stim_sequence(self):
        return [NewStimulus(duration=10)]


if __name__ == "__main__":
    Stytra(protocol=CustomProtocol())
Example #24
0
from stytra import Stytra
from stytra.stimulation.stimuli import Pause
from pathlib import Path
from stytra.stimulation import Protocol


class Nostim(Protocol):
    name = "empty_protocol"

    # In the stytra_config class attribute we specify a dictionary of
    # parameters that control camera, tracking, monitor, etc.
    # In this particular case, we add a stream of frames from one example
    # movie saved in stytra assets.
    stytra_config = dict(camera=dict(type="spinnaker"))

    #  For a streaming from real cameras connected to the computer, specify camera type, e.g.:
    # stytra_config = dict(camera=dict(type="ximea"))

    def get_stim_sequence(self):
        return [Pause(duration=10)]  # protocol does not do anything


if __name__ == "__main__":
    s = Stytra(protocol=Nostim())
Example #25
0
        # it available for other stimuli:
        try:
            self._pyb = getattr(experiment, "_pyb")
        except AttributeError:
            experiment._pyb = SerialConnection(com_port=self.com_port,
                                               baudrate=self.baudrate)
            self._pyb = getattr(experiment, "_pyb")

    def start(self):
        """ """
        self._pyb.write("b")  # send blinking command at stimulus start


class ArduinoCommProtocol(Protocol):
    name = "arduino_comm_protocol"  # every protocol must have a name.

    stytra_config = dict(camera=dict(type="ximea"),
                         tracking=dict(method="tail"))

    def get_stim_sequence(self):
        # This is the
        stimuli = []
        for i in range(5):
            stimuli.append(Pause(duration=4))
            stimuli.append(ArduinoCommStimulus(duration=0))
        return stimuli


if __name__ == "__main__":
    st = Stytra(protocol=ArduinoCommProtocol())
Example #26
0
        t_base = [0, p, p, p + d, p + d, 2 * p + d]
        vel_base = [0, 0, -v, -v, 0, 0]
        t = [0]
        vel = [0]
        gain = [0]

        # Low, medium, high gain:
        for g in gain_values:
            t.extend(t[-1] + np.array(t_base))
            vel.extend(vel_base)
            gain.extend([0] * 2 + [g] * 2 + [0] * 2)

        df = pd.DataFrame(dict(t=t, base_vel=vel, gain=gain))

        ClosedLoop1DGratings = type("Stim",
                                    (GainLagClosedLoop1D, GratingStimulus), {})

        stimuli.append(
            ClosedLoop1DGratings(
                df_param=df,
                grating_angle=np.pi / 2,
                grating_period=self.grating_cycle,
                grating_col_1=(255, ) * 3,
            ))
        return stimuli


if __name__ == "__main__":
    Stytra(protocol=ImagingCLProtocol())
    def get_position(self):
        if len(self.acc_tracking.stored_data) > 0:
            last_pos = self.acc_tracking.stored_data[-1]
            return self._data_type(last_pos.snout_x, last_pos.snout_y)
        else:
            return self._data_type(-1, -1)


# a stimulus which draws a circle at the position of the snout
# there is no transform, since this is a virtual experiment, in reality
# one would also use a calibration matrix after obtaining the coordinates
class PosTrackingStimulus(CircleStimulus):
    def update(self):
        self.x, self.y = self._experiment.estimator.get_position()
        super().update()


class RatProtocol(Protocol):
    name = "follow the mouse"
    stytra_config = dict(camera=dict(video_file=video_file),
                         tracking=dict(method=MouseTrackPipeline,
                                       estimator=SnoutPositionEstimator))

    def get_stim_sequence(self):
        return [PosTrackingStimulus(duration=120)]


if __name__ == "__main__":
    Stytra(protocol=RatProtocol())
Example #28
0
from stytra import Stytra, Protocol
from stytra.stimulation.stimuli.visual import Pause, FullFieldVisualStimulus

# 1. Define a protocol subclass
class FlashProtocol(Protocol):
    name = "flash_protocol"  # every protocol must have a name.

    def get_stim_sequence(self):
        # This is the method we need to write to create a new stimulus list.
        # In this case, the protocol is simply a 1 second flash on the entire screen
        # after a pause of 4 seconds:
        stimuli = [
            Pause(duration=4.),
            FullFieldVisualStimulus(duration=1., color=(255, 255, 255)),
        ]
        return stimuli


if __name__ == "__main__":
    # This is the line that actually opens stytra with the new protocol.
    st = Stytra(protocol=FlashProtocol())
Example #29
0
            Pause(duration=self.params["period_sec"] -
                  self.params["flash_duration"]),
            FullFieldVisualStimulus(duration=self.params["flash_duration"],
                                    color=(255, 255, 255)),
        ]
        return stimuli


if __name__ == "__main__":

    # Reading from a file:
    # This will work only with a file!
    # TODO provide downloadable example file
    file = r"J:\_Shared\stytra\fish_tail.h5"
    camera_config = dict(video_file=file, rotation=1)

    # Reading from a Ximea camera:
    # camera_config = dict(type="ximea")

    tracking_config = dict(embedded=True,
                           tracking_method="angle_sweep",
                           preprocessing_method="prefilter")

    # We make a new instance of Stytra with this protocol as the only option
    s = Stytra(
        protocols=[FlashProtocol],
        camera_config=camera_config,
        tracking_config=tracking_config,
        dir_save=r"D:\vilim\stytra\\",
    )