magscope.processes
==================

.. py:module:: magscope.processes


Attributes
----------

.. autoapisummary::

   magscope.processes.logger
   magscope.processes.ValueTypeUI8


Classes
-------

.. autoapisummary::

   magscope.processes.InterprocessValues
   magscope.processes.SingletonMeta
   magscope.processes.SingletonABCMeta
   magscope.processes.ManagerProcessBase


Module Contents
---------------

.. py:data:: logger

.. py:data:: ValueTypeUI8

.. py:class:: InterprocessValues

   .. py:attribute:: video_process_busy_count
      :type:  ValueTypeUI8


   .. py:attribute:: video_process_reserved_stacks
      :type:  multiprocessing.Value[ctypes.c_uint32]


   .. py:attribute:: video_process_completed_stacks
      :type:  multiprocessing.Value[ctypes.c_uint64]


   .. py:attribute:: live_profile_enabled
      :type:  ValueTypeUI8


   .. py:attribute:: live_profile_bead
      :type:  multiprocessing.Value[ctypes.c_int]


   .. py:attribute:: camera_total_frames
      :type:  multiprocessing.Value[ctypes.c_uint64]


   .. py:attribute:: camera_consecutive_timeouts
      :type:  multiprocessing.Value[ctypes.c_uint32]


   .. py:attribute:: camera_queue_full_events
      :type:  multiprocessing.Value[ctypes.c_uint64]


   .. py:attribute:: camera_last_frame_timestamp
      :type:  multiprocessing.Value[ctypes.c_double]


.. py:class:: SingletonMeta

   Bases: :py:obj:`type`


   .. py:attribute:: _instances


   .. py:method:: __call__(*args, **kwargs)


.. py:class:: SingletonABCMeta

   Bases: :py:obj:`abc.ABCMeta`, :py:obj:`SingletonMeta`


   Metaclass for defining Abstract Base Classes (ABCs).

   Use this metaclass to create an ABC.  An ABC can be subclassed
   directly, and then acts as a mix-in class.  You can also register
   unrelated concrete classes (even built-in classes) and unrelated
   ABCs as 'virtual subclasses' -- these and their descendants will
   be considered subclasses of the registering ABC by the built-in
   issubclass() function, but the registering ABC won't show up in
   their MRO (Method Resolution Order) nor will method
   implementations defined by the registering ABC be callable (not
   even via super()).


.. py:class:: ManagerProcessBase

   Bases: :py:obj:`multiprocessing.Process`, :py:obj:`abc.ABC`


   Abstract base class for processes in the MagScope

   Subclass requirements:
   * Each subclass should have a unique name.
   * There should only be one instance of each subclass (singleton).
   * The class name is used for consistent inter-process identification.


   .. py:attribute:: _acquisition_on
      :type:  bool
      :value: True



   .. py:attribute:: _acquisition_dir
      :type:  str | None
      :value: None



   .. py:attribute:: _acquisition_dir_on
      :type:  bool
      :value: False



   .. py:attribute:: _acquisition_mode
      :type:  magscope.utils.AcquisitionMode


   .. py:attribute:: bead_roi_buffer
      :type:  magscope.datatypes.BeadRoiBuffer | None
      :value: None



   .. py:attribute:: _bead_roi_ids
      :type:  numpy.ndarray


   .. py:attribute:: _bead_roi_values
      :type:  numpy.ndarray


   .. py:attribute:: camera_type
      :type:  type[magscope.camera.CameraBase] | None
      :value: None



   .. py:attribute:: hardware_types
      :type:  dict[str, type[magscope.hardware.HardwareManagerBase]]


   .. py:attribute:: locks
      :type:  dict[str, multiprocessing.synchronize.Lock] | None
      :value: None



   .. py:attribute:: _magscope_quitting
      :type:  multiprocessing.synchronize.Event | None
      :value: None



   .. py:attribute:: name
      :type:  str
      :value: 'ManagerProcessBase'



   .. py:attribute:: _pipe
      :type:  multiprocessing.connection.Connection | None
      :value: None



   .. py:attribute:: live_profile_buffer
      :type:  magscope.datatypes.LiveProfileBuffer | None
      :value: None



   .. py:attribute:: _quitting
      :type:  multiprocessing.synchronize.Event


   .. py:attribute:: _quit_requested
      :type:  bool
      :value: False



   .. py:attribute:: _running
      :type:  bool
      :value: False



   .. py:attribute:: settings
      :value: None



   .. py:attribute:: tracks_buffer
      :type:  magscope.datatypes.MatrixBuffer | None
      :value: None



   .. py:attribute:: video_buffer
      :type:  magscope.datatypes.VideoBuffer | None
      :value: None



   .. py:attribute:: shared_values
      :type:  InterprocessValues | None
      :value: None



   .. py:attribute:: _command_registry
      :type:  magscope.ipc.CommandRegistry | None
      :value: None



   .. py:attribute:: _command_handlers
      :type:  dict[type[magscope.ipc_commands.Command], str]


   .. py:property:: quitting_event
      :type: multiprocessing.synchronize.Event


      Event set when this process has begun quitting.


   .. py:property:: bead_rois
      :type: dict[int, tuple[int, int, int, int]]



   .. py:method:: get_cached_bead_rois() -> tuple[numpy.ndarray, numpy.ndarray]


   .. py:method:: _refresh_bead_roi_cache() -> None


   .. py:method:: configure_shared_resources(*, camera_type: type[magscope.camera.CameraBase] | None, hardware_types: dict[str, type[magscope.hardware.HardwareManagerBase]], quitting_event: multiprocessing.synchronize.Event, settings: magscope.settings.MagScopeSettings, shared_values: InterprocessValues, locks: dict[str, multiprocessing.synchronize.Lock], pipe_end: multiprocessing.connection.Connection, command_registry: magscope.ipc.CommandRegistry) -> None

      Attach shared references provided by :class:`~magscope.scope.MagScope`.

      This centralizes initialization so callers do not need to mutate
      underscored attributes directly when preparing processes before
      ``start()`` is invoked.



   .. py:method:: run()

      Start the process when ``start()`` is called.

      Subclasses should create a main loop that calls ``receive_ipc()`` last::

          while self._running:
              # do other stuff
              self.receive_ipc()



   .. py:method:: setup()
      :abstractmethod:



   .. py:method:: do_main_loop()
      :abstractmethod:



   .. py:method:: quit()

      Shutdown the process (and ask the other processes to quit too).



   .. py:method:: send_ipc(command: magscope.ipc_commands.Command)


   .. py:method:: receive_ipc()


   .. py:method:: set_acquisition_dir(value: str | None)


   .. py:method:: set_acquisition_dir_on(value: bool)


   .. py:method:: set_acquisition_mode(mode: magscope.utils.AcquisitionMode)


   .. py:method:: set_acquisition_on(value: bool)


   .. py:method:: refresh_bead_rois()


   .. py:method:: set_settings(settings: magscope.settings.MagScopeSettings)


   .. py:method:: _report_exception(exc: BaseException) -> None


