Ejemplo n.º 1
0
    def main(self, *args, **kwargs):
        t = get_time()

        # Update sawtooth
        a = 1.
        p = 2.
        sawtooth = - 2 * a / np.pi * np.arctan(1. / np.tan(np.pi * t / p))
        self.sawtooth_attr.write(sawtooth)

        # Update poisson_1p200
        if self.poisson_high_end >= get_time():
            new_state = True
        else:
            self.poisson_high_end = 0.
            new_state = np.random.randint(200) == 0
            if new_state:
                # Show high state for 5ms
                self.poisson_high_end = get_time() + 0.005

        self.poisson_1p20_attr.write(new_state)
Ejemplo n.º 2
0
 def start_phase(self):
     self.start_visual()
     self.set_record_group_attrs({
         'start_time':
         get_time(),
         'visual_module':
         self.current_visual.__module__,
         'visual_name':
         str(self.current_visual.__class__.__qualname__),
         'target_duration':
         self.current_protocol.current_phase.duration,
         'target_sample_rate':
         config.CONF_DISPLAY_FPS
     })
Ejemplo n.º 3
0
 def main(self, *args, **kwargs):
     t = get_time()
     self.whitenoise.write(3. * np.random.normal() + np.sin(t * 2. * np.pi * 20) + np.sin(t * 2. *  np.pi * 180))
Ejemplo n.º 4
0
 def main(self, *args, **kwargs):
     t = get_time()
     sig = int(t / 2) % 2
     self.test_onoff.write(sig)
Ejemplo n.º 5
0
    def main(self, **frames):

        # Read frame
        frame = frames.get(self.camera_device_id)

        # Check if frame was returned
        if frame is None:
            return

        # Reduce to mono
        if frame.ndim > 2:
            frame = frame[:,:,0]

        # Write frame to buffer
        self.frame.write(frame.T)

        # Do eye detection and angular position estimation
        if not bool(self.rois):
            return

        # If eyes were marked: iterate over ROIs and extract eye positions
        saccade_happened = False
        for id, rect_params in self.rois.items():

            ####
            # Extract rectanglular ROI

            # Convert from pyqtgraph image coordinates to openCV
            # rect_params = (tuple(self.coord_transform_pg2cv(rect_params[0])), tuple(rect_params[1]), -rect_params[2],)

            # Get rect and frame parameters
            center, size, angle = rect_params[0], rect_params[1], rect_params[2]
            center, size = tuple(map(int, center)), tuple(map(int, size))
            height, width = frame.shape[0], frame.shape[1]

            # Rotate
            M = cv2.getRotationMatrix2D(center, angle, 1)
            rotFrame = cv2.warpAffine(frame, M, (width, height))

            # Crop rect from frame
            cropRect = cv2.getRectSubPix(rotFrame, size, center)

            # Rotate rect so that "up" direction in image corresponds to "foward" for the fish
            center = (size[0]/2, size[1]/2)
            width, height = size
            M = cv2.getRotationMatrix2D(center, 90, 1)
            absCos = abs(M[0, 0])
            absSin = abs(M[0, 1])

            # New bound width/height
            wBound = int(height * absSin + width * absCos)
            hBound = int(height * absCos + width * absSin)

            # Subtract old image center
            M[0, 2] += wBound / 2 - center[0]
            M[1, 2] += hBound / 2 - center[1]
            # Rotate
            rot_rect = cv2.warpAffine(cropRect, M, (wBound, hBound))

            ####
            # Calculate eye angular POSITIONS

            # Apply detection function on cropped rect which contains eyes
            (le_pos, re_pos), new_rect = self.from_ellipse(rot_rect)

            # Get shared attributes
            le_pos_attr = get_attribute(f'{self.ang_le_pos_prefix}{id}')
            re_pos_attr = get_attribute(f'{self.ang_re_pos_prefix}{id}')
            le_vel_attr = get_attribute(f'{self.ang_le_vel_prefix}{id}')
            re_vel_attr = get_attribute(f'{self.ang_re_vel_prefix}{id}')
            le_sacc_attr = get_attribute(f'{self.le_sacc_prefix}{id}')
            re_sacc_attr = get_attribute(f'{self.re_sacc_prefix}{id}')
            rect_roi_attr = get_attribute(f'{self.extracted_rect_prefix}{id}')

            # Calculate eye angular VELOCITIES
            _, _, last_le_pos = le_pos_attr.read()
            last_le_pos = last_le_pos[0]
            _, last_time, last_re_pos = re_pos_attr.read()
            last_re_pos = last_re_pos[0]
            last_time = last_time[-1]
            if last_time is None:
                last_time = -np.inf

            # Calculate time elapsed since last frame
            current_time = get_time()
            dt = (current_time - last_time)

            # Calculate velocities
            le_vel = np.abs((le_pos - last_le_pos) / dt)
            re_vel = np.abs((re_pos - last_re_pos) / dt)

            # Calculate saccade trigger
            _, _, last_le_vel = le_vel_attr.read()
            last_le_vel = last_le_vel[0]
            _, _, last_re_vel = re_vel_attr.read()
            last_re_vel = last_re_vel[0]

            le_sacc = int(last_le_vel < self.saccade_threshold < le_vel)
            re_sacc = int(last_re_vel < self.saccade_threshold < re_vel)

            is_saccade = bool(le_sacc) or bool(re_sacc)
            saccade_happened = saccade_happened or is_saccade
            if is_saccade:
                self.emit_trigger('saccade_trigger')

            # Write to buffer
            le_pos_attr.write(le_pos)
            re_pos_attr.write(re_pos)
            le_vel_attr.write(le_vel)
            re_vel_attr.write(re_vel)

            le_sacc_attr.write(le_sacc)
            re_sacc_attr.write(re_sacc)

            # Set current rect ROI data
            rect_roi_attr.write(new_rect)

        self.saccade_trigger.write(saccade_happened)
Ejemplo n.º 6
0
    def _handle_protocol(self):
        """Method can be called by all processes that in some way respond to
        the protocol control states.

        Returns True of protocol is currently running and False if not.
        """

        if self.name not in self._protocolized:
            return

        ########
        # RUNNING
        if self.in_state(State.RUNNING):

            # If phase stoptime is exceeded: end phase
            phase_stop = vxipc.Control.Protocol[ProtocolCtrl.phase_stop]
            if phase_stop is not None and phase_stop < time.time():
                self.set_record_group_attrs({'end_time': api.get_time()})

                # Call implementation of end_phase
                self.end_phase()

                self.set_state(State.PHASE_END)

                # Do NOT execute
                return False

            # Default: set phase time and execute protocol
            self.phase_time = time.time() - self.phase_start_time

            # Execute
            return True

        # IDLE
        elif self.in_state(State.IDLE):

            # Check if new protocol is set and prepare it on module-side
            if self.in_state(State.PREPARE_PROTOCOL, PROCESS_CONTROLLER):

                # Fetch protocol class
                _protocol = vxprotocol.get_protocol(vxipc.Control.Protocol[ProtocolCtrl.name])
                if _protocol is None:
                    # Controller should abort this
                    return

                # Instantiate protocol
                self.current_protocol = _protocol()

                # Call implemented preparation function of module
                self.prepare_protocol()

                # Set next state
                self.set_state(State.WAIT_FOR_PHASE)

            # Do NOT execute
            return False

        # WAIT_FOR_PHASE
        elif self.in_state(State.WAIT_FOR_PHASE):

            if not self.in_state(State.PREPARE_PHASE, PROCESS_CONTROLLER):
                return False

            # Set record group to write to in file
            if not self._disable_phases:
                self.set_record_group(f'phase{vxipc.Control.Recording[RecCtrl.record_group_counter]}')

            # Set current phase
            self.current_protocol.current_phase_id = vxipc.Control.Protocol[ProtocolCtrl.phase_id]

            # Prepare implemented phase initialization
            self.prepare_phase()

            # Set next state
            self.set_state(State.READY)

            # Do NOT execute
            return False

        # READY
        elif self.in_state(State.READY):
            # If Controller is not yet running, don't wait for go time, because there may be an abort
            if not self.in_state(State.RUNNING, PROCESS_CONTROLLER):
                return False

            # Wait for go-time
            phase_id = vxipc.Control.Protocol[ProtocolCtrl.phase_id]
            while self.in_state(State.RUNNING, PROCESS_CONTROLLER):
                now = time.time()
                if vxipc.Control.Protocol[ProtocolCtrl.phase_start] <= now:
                    log.debug(f'Start phase {phase_id} in module {self.name} at {(now-self.program_start_time):.3f}')
                    self.set_state(State.RUNNING)
                    self.phase_start_time = vxipc.Control.Protocol[ProtocolCtrl.phase_start]
                    break

            # Immediately start phase now
            self.start_phase()

            # Execute
            return True

        ########
        # PHASE_END
        elif self.in_state(State.PHASE_END):

            # Ctrl in PREPARE_PHASE -> there's a next phase
            if self.in_state(State.PREPARE_PHASE, PROCESS_CONTROLLER):
                self.set_state(State.WAIT_FOR_PHASE)

            # Ctrl in PROTOCOL_END -> clean up protocol remnants
            elif self.in_state(State.PROTOCOL_END, PROCESS_CONTROLLER):

                # Call implemented module method
                self.end_protocol()

                # Set protocol to none
                self.current_protocol = None

                # Reset state to idle
                self.set_state(State.IDLE)

            # Do NOT execute
            return False

        ########
        # Fallback: timeout
        else:
            pass