From 2d26904275bd4242e60a59b25c2a1904be647ecd Mon Sep 17 00:00:00 2001 From: Aquiles Carattino Date: Tue, 30 Jul 2019 12:17:29 +0200 Subject: [PATCH] Mayor improvements in the documentation. First steps in Dispertech experiment model --- .editorconfig | 35 ++++++ AUTHORS | 2 +- docs/_static/example_config.yml | 72 +++++++++++++ docs/_static/screenshot_01.png | Bin 0 -> 65657 bytes docs/_static/screenshot_free_run.png | Bin 0 -> 27757 bytes docs/_static/screenshot_particles.png | Bin 0 -> 37054 bytes docs/_static/screenshot_save_image.png | Bin 0 -> 27626 bytes docs/_static/screenshot_snap.png | Bin 0 -> 26951 bytes docs/_static/screenshot_toolbar.png | Bin 0 -> 24976 bytes docs/_static/screenshot_tracking.png | Bin 0 -> 24976 bytes docs/conf.py | 4 +- .../controller/devices/hamamatsu.rst | 4 + docs/developers/controller/devices/index.rst | 13 +++ .../controller/devices/keysight.rst | 7 ++ .../controller/devices/photonicscience.rst | 4 + docs/developers/controller/index.rst | 13 +++ docs/developers/index.rst | 21 ++-- docs/developers/model/cameras/base_camera.rst | 4 + docs/developers/model/cameras/basler.rst | 4 + .../developers/model/cameras/dummy_camera.rst | 4 + docs/developers/model/cameras/hamamatsu.rst | 4 + docs/developers/model/cameras/index.rst | 16 +++ docs/developers/model/cameras/psi.rst | 4 + .../model/cameras/simulate_brownian.rst | 4 + .../daqs/index.rst} | 29 ++--- .../model/experiments/fiber_tracking.rst | 4 + .../experiments/index.rst} | 37 +++---- .../model/experiments/np_tracking.rst | 4 + .../{pynta.model.rst => model/index.rst} | 27 +++-- docs/developers/modules.rst | 7 -- .../pynta.controller.data_sources.rst | 10 -- .../pynta.controller.devices.hamamatsu.rst | 22 ---- .../pynta.controller.devices.keysight.rst | 22 ---- ...nta.controller.devices.photonicscience.rst | 22 ---- docs/developers/pynta.controller.devices.rst | 19 ---- docs/developers/pynta.controller.rst | 27 ----- docs/developers/pynta.exceptions.rst | 19 +--- docs/developers/pynta.model.cameras.rst | 61 ----------- .../pynta.model.experiment.nano_cet.rst | 70 ------------ docs/developers/pynta.rst | 37 ++----- .../developers/pynta.view.GUI.old.Monitor.rst | 70 ------------ docs/developers/pynta.view.GUI.old.rst | 61 ----------- .../{pynta.view.GUI.rst => view/GUI.rst} | 57 ++-------- .../{pynta.view.rst => view/index.rst} | 33 ++---- docs/index.rst | 2 +- docs/requirements_docs.txt | 67 ++++++++++++ examples/config/dispertech.yml | 92 ++++++++++++++++ pynta/config.py | 2 +- pynta/controller/devices/__init__.py | 6 ++ .../devices/hamamatsu/hamamatsu_camera.py | 14 +-- .../devices/keysight/infiniivision.py | 7 +- .../devices/photonicscience/scmoscam.py | 4 +- pynta/model/cameras/base_camera.py | 61 ++++++----- pynta/model/cameras/basler.py | 102 ++++++++++++++---- pynta/model/cameras/dummy_camera.py | 20 ++-- pynta/model/cameras/hamamatsu.py | 22 ++-- pynta/model/cameras/psi.py | 26 ++--- pynta/model/cameras/simulate_brownian.py | 6 +- pynta/model/daqs/NI.py | 4 +- pynta/model/daqs/daq_dummy.py | 16 +-- pynta/model/daqs/skeleton.py | 17 +-- pynta/model/experiment/__init__.py | 15 +++ pynta/model/experiment/base_experiment.py | 8 +- pynta/model/experiment/config.py | 4 +- pynta/model/experiment/dispertech/__init__.py | 0 pynta/model/experiment/dispertech/database.py | 80 ++++++++++++++ .../experiment/dispertech/fiber_tracking.py | 82 ++++++++++++++ pynta/model/experiment/dispertech/util.py | 32 ++++++ .../nanoparticle_tracking/localization.py | 2 +- .../nanoparticle_tracking/np_tracking.py | 16 ++- .../experiment/nanoparticle_tracking/saver.py | 4 +- .../nanoparticle_tracking/waterfall_worker.py | 3 +- pynta/model/experiment/publisher.py | 2 +- pynta/model/experiment/subscriber.py | 4 +- pynta/tests/test_controllers.py | 7 +- pynta/tests/test_examples.py | 7 +- pynta/tests/test_models.py | 7 +- pynta/tools/worker_thread.py | 4 +- pynta/util/log.py | 4 +- pynta/view/GUI/__init__.py | 26 +++++ pynta/view/GUI/config_widget.py | 2 +- pynta/view/GUI/old/Monitor/cameraViewer.py | 2 +- .../view/GUI/old/Monitor/clearQueueThread.py | 2 +- pynta/view/GUI/old/Monitor/crossCut.py | 2 +- pynta/view/GUI/old/mainwindow.py | 10 +- pynta/view/GUI/old/messageWidget.py | 2 +- pynta/view/GUI/old/trajectoryWidget.py | 2 +- pynta/view/GUI/old/waterfallWidget.py | 2 +- pynta/view/__init__.py | 13 +++ pynta/view/subscriber_thread.py | 2 +- setup.py | 2 +- 91 files changed, 932 insertions(+), 737 deletions(-) create mode 100644 .editorconfig create mode 100644 docs/_static/example_config.yml create mode 100644 docs/_static/screenshot_01.png create mode 100644 docs/_static/screenshot_free_run.png create mode 100644 docs/_static/screenshot_particles.png create mode 100644 docs/_static/screenshot_save_image.png create mode 100644 docs/_static/screenshot_snap.png create mode 100644 docs/_static/screenshot_toolbar.png create mode 100644 docs/_static/screenshot_tracking.png create mode 100644 docs/developers/controller/devices/hamamatsu.rst create mode 100644 docs/developers/controller/devices/index.rst create mode 100644 docs/developers/controller/devices/keysight.rst create mode 100644 docs/developers/controller/devices/photonicscience.rst create mode 100644 docs/developers/controller/index.rst create mode 100644 docs/developers/model/cameras/base_camera.rst create mode 100644 docs/developers/model/cameras/basler.rst create mode 100644 docs/developers/model/cameras/dummy_camera.rst create mode 100644 docs/developers/model/cameras/hamamatsu.rst create mode 100644 docs/developers/model/cameras/index.rst create mode 100644 docs/developers/model/cameras/psi.rst create mode 100644 docs/developers/model/cameras/simulate_brownian.rst rename docs/developers/{pynta.model.daqs.rst => model/daqs/index.rst} (58%) create mode 100644 docs/developers/model/experiments/fiber_tracking.rst rename docs/developers/{pynta.model.experiment.rst => model/experiments/index.rst} (50%) create mode 100644 docs/developers/model/experiments/np_tracking.rst rename docs/developers/{pynta.model.rst => model/index.rst} (64%) delete mode 100644 docs/developers/modules.rst delete mode 100644 docs/developers/pynta.controller.data_sources.rst delete mode 100644 docs/developers/pynta.controller.devices.hamamatsu.rst delete mode 100644 docs/developers/pynta.controller.devices.keysight.rst delete mode 100644 docs/developers/pynta.controller.devices.photonicscience.rst delete mode 100644 docs/developers/pynta.controller.devices.rst delete mode 100644 docs/developers/pynta.controller.rst delete mode 100644 docs/developers/pynta.model.cameras.rst delete mode 100644 docs/developers/pynta.model.experiment.nano_cet.rst delete mode 100644 docs/developers/pynta.view.GUI.old.Monitor.rst delete mode 100644 docs/developers/pynta.view.GUI.old.rst rename docs/developers/{pynta.view.GUI.rst => view/GUI.rst} (51%) rename docs/developers/{pynta.view.rst => view/index.rst} (52%) create mode 100644 docs/requirements_docs.txt create mode 100644 examples/config/dispertech.yml create mode 100644 pynta/model/experiment/dispertech/__init__.py create mode 100644 pynta/model/experiment/dispertech/database.py create mode 100644 pynta/model/experiment/dispertech/fiber_tracking.py create mode 100644 pynta/model/experiment/dispertech/util.py diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b0d304f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,35 @@ +# http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true +end_of_line = lf +charset = utf-8 + +# Docstrings and comments use max_line_length = 79 +[*.py] +max_line_length = 119 + +[*.rst] +indent_size = 3 + +# Use 2 spaces for the HTML files +[*.html] +indent_size = 2 + +# The JSON files contain newlines inconsistently +[*.json] +indent_size = 2 +insert_final_newline = false + +# Makefiles always use tabs for indentation +[Makefile] +indent_style = tab + +# Batch files use tabs for indentation +[*.bat] +indent_style = tab diff --git a/AUTHORS b/AUTHORS index 5d4d499..4d270ab 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,5 @@ Authors ------- -Aquiles Carattino +Aquiles Carattino Sanli Faez diff --git a/docs/_static/example_config.yml b/docs/_static/example_config.yml new file mode 100644 index 0000000..82c4720 --- /dev/null +++ b/docs/_static/example_config.yml @@ -0,0 +1,72 @@ +%YAML 1.2 +--- +# Default parameters for the Tracking program +# All parameters can be changed to accommodate user needs. +# All parameters can be changed at runtime with the appropriate config window +user: + name: Aquiles + +saving: + auto_save: False + auto_save_waterfall: True + directory: C:\Users\carat002\Data + filename_video: Video # Can be the same filename for video and photo + filename_photo: Snap + filename_tracks: Tracks + filename_waterfall: Waterfall + filename_trajectory: Trajectory + filename_log: Log + max_memory: 200 # In megabytes + +GUI: + length_waterfall: 20 # Total length of the Waterfall (lines) + refresh_time: 50 # Refresh rate of the GUI (in ms) + +camera: + model: dummy_camera # Should be a python file in model/cameras + init: 0 # Initial arguments to pass when creating the camera + #extra_args: [extra, arguments] # Extra arguments that can be passed when constructing the model + model_camera: Orca Flash # To keep a registry of which camera was used in the experiment + exposure_time: 30ms # Initial exposure time (in ms) + fps: 30 # Frames per second, should either be defined by the camera or within the model based on timing + binning_x: 1 # Binning + binning_y: 1 + roi_x1: 0 + roi_x2: 599 + roi_y1: 0 + roi_y2: 399 + background: '' # Full path to background file, or empty for none. + background_method: [Method1, Method2] + +waterfall: # Parameters for calculating the waterfall plot + length: 20 # The total length of the waterfall (lines) + vertical_bin: 10 # Total number of lines of the CCD to integrate + +movie: + buffer_length: 1000 # Frames + +tracking: + locate: + diameter: 11 # Diameter of the particles (in pixels) to track, has to be an odd number + invert: False + minmass: 100 + link: + memory: 3 + search_range: 4 + filter: # Filter spurious trajectories + min_length: 25 + process: + compute_drift: False + um_pixel: 0.01 # Microns per pixel (calibration of the microscope) + min_traj_length: 2 + min_mass: 0.05 + max_size: 50.0 + max_ecc: 1 + fps: 30 + param_1: 0. + param_2: 0 + +debug: + logging_level: Nothing # One of Nothing, Debug, Info, Warning, Error + queue_memory: False + to_screen: True \ No newline at end of file diff --git a/docs/_static/screenshot_01.png b/docs/_static/screenshot_01.png new file mode 100644 index 0000000000000000000000000000000000000000..6c10b90a615c75a28af49541e11dca1a70e14ea6 GIT binary patch literal 65657 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 DosnIG literal 0 HcmV?d00001 diff --git a/docs/_static/screenshot_free_run.png b/docs/_static/screenshot_free_run.png new file mode 100644 index 0000000000000000000000000000000000000000..b8d4fe077e198f92b2f222bf527e065a2aaf8279 GIT binary patch literal 27757 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 X!>}Ue#_VF$Nqnk`TK|+NJPrCEPTD1& literal 0 HcmV?d00001 diff --git a/docs/_static/screenshot_particles.png b/docs/_static/screenshot_particles.png new file mode 100644 index 0000000000000000000000000000000000000000..9e71378129bf2ec91aeda7ca7ce7d8a11f5a8af9 GIT binary patch literal 37054 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 literal 0 HcmV?d00001 diff --git a/docs/_static/screenshot_save_image.png b/docs/_static/screenshot_save_image.png new file mode 100644 index 0000000000000000000000000000000000000000..577c980a03f89cbef89cbb16ce4c96a8f6718e1a GIT binary patch literal 27626 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 Snw5jtUa-8nT(Qiv_x}r%e|9SX literal 0 HcmV?d00001 diff --git a/docs/_static/screenshot_toolbar.png b/docs/_static/screenshot_toolbar.png new file mode 100644 index 0000000000000000000000000000000000000000..1d1a4dd44c13675e1949714e5b626b287e8b523e GIT binary patch literal 24976 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 literal 0 HcmV?d00001 diff --git a/docs/_static/screenshot_tracking.png b/docs/_static/screenshot_tracking.png new file mode 100644 index 0000000000000000000000000000000000000000..1d1a4dd44c13675e1949714e5b626b287e8b523e GIT binary patch literal 24976 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 literal 0 HcmV?d00001 diff --git a/docs/conf.py b/docs/conf.py index b281205..884e2b5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -177,4 +177,6 @@ # -- Options for todo extension ---------------------------------------------- # If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True \ No newline at end of file +todo_include_todos = True + +autodoc_mock_imports = ["pydaqmx", "lantz"] \ No newline at end of file diff --git a/docs/developers/controller/devices/hamamatsu.rst b/docs/developers/controller/devices/hamamatsu.rst new file mode 100644 index 0000000..b1163e9 --- /dev/null +++ b/docs/developers/controller/devices/hamamatsu.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.controller.devices.hamamatsu.hamamatsu_camera + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/controller/devices/index.rst b/docs/developers/controller/devices/index.rst new file mode 100644 index 0000000..3ef7e8e --- /dev/null +++ b/docs/developers/controller/devices/index.rst @@ -0,0 +1,13 @@ +.. automodule:: pynta.controller.devices + :members: + :undoc-members: + :show-inheritance: + + +.. toctree:: + :maxdepth: 2 + :caption: List of available devices + + hamamatsu + keysight + photonicscience diff --git a/docs/developers/controller/devices/keysight.rst b/docs/developers/controller/devices/keysight.rst new file mode 100644 index 0000000..6ec197a --- /dev/null +++ b/docs/developers/controller/devices/keysight.rst @@ -0,0 +1,7 @@ +Keysight +======== + +.. automodule:: pynta.controller.devices.keysight.infiniivision + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/controller/devices/photonicscience.rst b/docs/developers/controller/devices/photonicscience.rst new file mode 100644 index 0000000..6c4c1cc --- /dev/null +++ b/docs/developers/controller/devices/photonicscience.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.controller.devices.photonicscience.scmoscam + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/controller/index.rst b/docs/developers/controller/index.rst new file mode 100644 index 0000000..02d2430 --- /dev/null +++ b/docs/developers/controller/index.rst @@ -0,0 +1,13 @@ +Pynta Controllers +================= + +.. automodule:: pynta.controller + :members: + :undoc-members: + :show-inheritance: + +.. toctree:: + :maxdepth: 1 + :caption: Contents + + devices/index diff --git a/docs/developers/index.rst b/docs/developers/index.rst index c4620c8..28bf2af 100644 --- a/docs/developers/index.rst +++ b/docs/developers/index.rst @@ -16,19 +16,23 @@ Below you will find an introduction to the code architecture. Read through to un Controller ---------- -In our definition of the MVC pattern, :mod:`controllers ` are the drivers of the devices. Controllers for cameras, for example, rely on library files (.dll files on Windows, .so in Linux) that can be more or less documented. For example :mod:`~pynta.controller.devices.hamamatsu` uses the *DCAM-API*, while :mod:`~pynta.controller.devices.photonicscience` uses *scmoscam.dll*. Controllers should follow the specifications of each device as closely as possible. For instance, the units each devices uses for setting exposure times or framerates, etc. Moreover, they shouldn't implement anything that the device is not capable of doing. A clear example would be to set a region of interest. Some cameras support it but some don't. You could be tempted to apply a ROI in the software directly, but you shouldn't do it in the Controller, there is a better place as we will see later. +In our definition of the MVC pattern, :mod:`~pynta.controller` are the drivers of the devices. Controllers for cameras, for example, rely on library files (.dll files on Windows, .so in Linux) that can be more or less documented. For example :mod:`~pynta.controller.devices.hamamatsu` uses the *DCAM-API*, while :mod:`~pynta.controller.devices.photonicscience` uses *scmoscam.dll*. Controllers should follow the specifications of each device as closely as possible. For instance, the units each devices uses for setting exposure times or framerates, etc. Moreover, they shouldn't implement anything that the device is not capable of doing. A clear example would be to set a region of interest. Some cameras support it but some don't. You could be tempted to apply a ROI in the software directly, but you shouldn't do it in the Controller, there is a better place as we will see later. Controllers are not always plain python files, sometimes are entire packages on themselves. For instance, the controller for Basler cameras (PyPylons) or National Instruments cards (pyDAQmx) are packages on their own. Sometimes the controllers where developed by other people, like the case of the Hamamatsu code, which was borrowed from Zhuang's lab. If you explore the controllers folder, you will notice that there are some available, like the :mod:`~pynta.controller.devices.keysight` ,that holds the drivers for an oscilloscope and function generator. Those controllers are remnants of a different incarnation of PyNTA, but that may still be valuable for the future. Model ----- +In the MVC pattern that we have defined earlier, :mod:`~pynta.model` is the place to define all the logic on how to use the devices is located. The core principle of splitting Controllers and Models is to separate what the device can do by design and what the user imposes to the devices. For example, imagine a camera which can acquire frames one by one. The controller would provide a way to snap a single-frame. However, a user may want to acquire a movie by developing a for-loop that acquires a series of frames. The controller should reflect the capacities of the device, while the model will include all the user-imposed logic. + +A clear advantage of having models is that in the case where controllers are not part of the package, for example if the driver is provided by the manufacturer itself, a model will make explicit how the driver is used. For example, NI-cards are very complex devices, and if one wants to monitor a signal, there are several required steps, which can be written down as a method of a class and re-used as much as wanted. Models can make use of explicit units (through Pint), for example. + +Models are not limited to devices, but they also make explicit how an experiment is performed. In PyNTA, there are available at least two different experimental models, one for performing nanoparticle tracking analysis in 2D images (the classical NTA) and one to perform tracking analysis in hollow optical fibers, i.e., 1-D nanoparticle tracking. In these experiment models, you can find all the steps and how they relate to each other. For example, you can't subtract background if you haven't acquired the background first, etc. Models for the Cameras ^^^^^^^^^^^^^^^^^^^^^^ +Imagine you have a camera that doesn't support setting a region of interest (ROI), you can still crop the resulting images in the software, giving the same result as what a camera that does support ROI does. By having an intermediate layer between the controllers and the users, it is possible to detach the specific logic of an experiment and the specifications of the devices. Moreover, it makes very straightforward to add new devices to the experiment, exchanging cameras, etc. -Models define the way the users will interact with the devices. Imagine you have a camera that doesn't support setting a region of interest (ROI), you can still crop the resulting images in the software, giving the same result as what a camera that does support ROI does. By having an intermediate layer between the controllers and the users, it is possible to detach the specific logic of an experiment and the specifications of the devices. Moreover, it makes very straightforward to add new devices to the experiment, exchanging cameras, etc. - -Therefore in :doc:`pynta.model.cameras` is where we will develop classes that have always the same methods and outputs defined, but that behave completely different when communicating with the devices. The starting point is the :mod:`skeleton `, where the ``cameraBase`` class is defined. In this class all the methods and variables needed by the rest of the program are defined. This strategy not only allows to keep track of the functions, it also enables the subclassing, which will be discussed later. +Therefore in :mod:`~pynta.model.cameras` is where we will develop classes that have always the same methods and outputs defined, but that behave completely different when communicating with the devices. The starting point is the :mod:`skeleton `, where the ``cameraBase`` class is defined. In this class all the methods and variables needed by the rest of the program are defined. This strategy not only allows to keep track of the functions, it also enables the subclassing, which will be discussed later. Having models also allow to quickly change from one camera to another. For example, if one desires to switch from a :mod:`Hamamatsu ` to a :mod:`PSI `, the only needed thing to do is to replace:: @@ -52,14 +56,13 @@ The idea behind the experiment model is that it makes it very clear what the log View ---- -The View is, as the name suggests, where the GUI is defined. Since we defined all the logic of the experiment in a separate class, the View takes care of only triggering specific steps of the experiment and displaying the results. In principle, the only logic present in the view modules is only for aesthetic reasons. For instance, disable a specific button while a measurement is going on, etc. However, it should be the experiment model the one that avoids triggering two measurements if it is not possible, etc. That guarantees a lower-level safety. +In the MVC patter, :mod:`~pynta.view` is, as the name suggests, where the GUI is defined. Since we defined all the logic of the experiment in a separate class, the View takes care of only triggering specific steps of the experiment and displaying the results. In principle, the only logic present in the view modules is only for aesthetic reasons. For instance, disable a specific button while a measurement is going on, etc. However, it should be the experiment model the one that avoids triggering two measurements if it is not possible, etc. That guarantees a lower-level safety. -:doc:`pynta.view` is where the GUI lives. Within the module, you will also find :doc:`pynta.view.GUI`, in which the different widgets that make up the window are defined and another folder called designer, where the Qt Designer files are located. Adapting the looks of a program should start by looking into the ``.ui`` files, then checking the associated widgets in the ``GUI`` module, in order to connect the proper signals, etc. and finally modifying the main view class. +:mod:`~pynta.view` is where the GUI lives. Within the module, you will also find :mod:`pynta.view.GUI`, in which the different widgets that make up the window are defined and another folder called designer, where the Qt Designer files are located. Adapting the looks of a program should start by looking into the ``.ui`` files, then checking the associated widgets in the ``GUI`` module, in order to connect the proper signals, etc. and finally modifying the main view class. .. toctree:: - :maxdepth: 4 - :caption: Contents: + :maxdepth: 1 + :caption: PyNTA API pynta - modules diff --git a/docs/developers/model/cameras/base_camera.rst b/docs/developers/model/cameras/base_camera.rst new file mode 100644 index 0000000..5fbd2e3 --- /dev/null +++ b/docs/developers/model/cameras/base_camera.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.model.cameras.base_camera + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/model/cameras/basler.rst b/docs/developers/model/cameras/basler.rst new file mode 100644 index 0000000..4c0dc98 --- /dev/null +++ b/docs/developers/model/cameras/basler.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.model.cameras.basler + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/model/cameras/dummy_camera.rst b/docs/developers/model/cameras/dummy_camera.rst new file mode 100644 index 0000000..ecd1a76 --- /dev/null +++ b/docs/developers/model/cameras/dummy_camera.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.model.cameras.dummy_camera + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/model/cameras/hamamatsu.rst b/docs/developers/model/cameras/hamamatsu.rst new file mode 100644 index 0000000..82516d6 --- /dev/null +++ b/docs/developers/model/cameras/hamamatsu.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.model.cameras.hamamatsu + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/model/cameras/index.rst b/docs/developers/model/cameras/index.rst new file mode 100644 index 0000000..ccb0f3c --- /dev/null +++ b/docs/developers/model/cameras/index.rst @@ -0,0 +1,16 @@ +Camera Models +============= +.. automodule:: pynta.model.cameras + :members: + :undoc-members: + :show-inheritance: + +.. toctree:: + :maxdepth: 1 + + base_camera + simulate_brownian + dummy_camera + basler + hamamatsu + psi diff --git a/docs/developers/model/cameras/psi.rst b/docs/developers/model/cameras/psi.rst new file mode 100644 index 0000000..b5d8f53 --- /dev/null +++ b/docs/developers/model/cameras/psi.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.model.cameras.psi + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/model/cameras/simulate_brownian.rst b/docs/developers/model/cameras/simulate_brownian.rst new file mode 100644 index 0000000..4947afb --- /dev/null +++ b/docs/developers/model/cameras/simulate_brownian.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.model.cameras.simulate_brownian + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/pynta.model.daqs.rst b/docs/developers/model/daqs/index.rst similarity index 58% rename from docs/developers/pynta.model.daqs.rst rename to docs/developers/model/daqs/index.rst index 05f8e30..5910714 100644 --- a/docs/developers/pynta.model.daqs.rst +++ b/docs/developers/model/daqs/index.rst @@ -1,38 +1,25 @@ -pynta.model.daqs package -======================== - -Submodules ----------- - -pynta.model.daqs.NI module --------------------------- - -.. automodule:: pynta.model.daqs.NI +Data Acquisition Cards Models +============================= +.. automodule:: pynta.model.daqs :members: :undoc-members: :show-inheritance: -pynta.model.daqs.daq\_dummy module ----------------------------------- +Available DAQS +--------------- -.. automodule:: pynta.model.daqs.daq_dummy +.. automodule:: pynta.model.daqs.NI :members: :undoc-members: :show-inheritance: -pynta.model.daqs.skeleton module --------------------------------- - -.. automodule:: pynta.model.daqs.skeleton +.. automodule:: pynta.model.daqs.daq_dummy :members: :undoc-members: :show-inheritance: -Module contents ---------------- - -.. automodule:: pynta.model.daqs +.. automodule:: pynta.model.daqs.skeleton :members: :undoc-members: :show-inheritance: diff --git a/docs/developers/model/experiments/fiber_tracking.rst b/docs/developers/model/experiments/fiber_tracking.rst new file mode 100644 index 0000000..21652a3 --- /dev/null +++ b/docs/developers/model/experiments/fiber_tracking.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.model.experiment.dispertech.fiber_tracking + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/pynta.model.experiment.rst b/docs/developers/model/experiments/index.rst similarity index 50% rename from docs/developers/pynta.model.experiment.rst rename to docs/developers/model/experiments/index.rst index d84045a..5240748 100644 --- a/docs/developers/pynta.model.experiment.rst +++ b/docs/developers/model/experiments/index.rst @@ -1,45 +1,38 @@ -pynta.model.experiment package -============================== - -Subpackages ------------ +Model for Experiments +===================== .. toctree:: + :maxdepth: 1 + :caption: Available Experiments - pynta.model.experiment.nano_cet - -Submodules ----------- + fiber_tracking + np_tracking -pynta.model.experiment.base\_experiment module ----------------------------------------------- +.. automodule:: pynta.model.experiment + :members: + :undoc-members: + :show-inheritance: .. automodule:: pynta.model.experiment.base_experiment :members: :undoc-members: :show-inheritance: -pynta.model.experiment.publisher module ---------------------------------------- - .. automodule:: pynta.model.experiment.publisher :members: :undoc-members: :show-inheritance: -pynta.model.experiment.subscriber module ----------------------------------------- - .. automodule:: pynta.model.experiment.subscriber :members: :undoc-members: :show-inheritance: - -Module contents ---------------- - -.. automodule:: pynta.model.experiment +.. automodule:: pynta.model.experiment.config :members: :undoc-members: :show-inheritance: + + + + diff --git a/docs/developers/model/experiments/np_tracking.rst b/docs/developers/model/experiments/np_tracking.rst new file mode 100644 index 0000000..fb381ff --- /dev/null +++ b/docs/developers/model/experiments/np_tracking.rst @@ -0,0 +1,4 @@ +.. automodule:: pynta.model.experiment.nanoparticle_tracking.np_tracking + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/developers/pynta.model.rst b/docs/developers/model/index.rst similarity index 64% rename from docs/developers/pynta.model.rst rename to docs/developers/model/index.rst index 2dfd91e..b895d78 100644 --- a/docs/developers/pynta.model.rst +++ b/docs/developers/model/index.rst @@ -1,23 +1,22 @@ -pynta.model package -=================== +PyNTA Models +============ -Models are the place to develop the logic of how the devices are used and how the experiment is performed. You will find models for cameras and daqs. Cameras are heavily used in PyNTA, while DAQs where inherited from a previous incarnation and were left behind as a reference and to speed up future developments in which not only a camera has to be controlled but an external trigger or a different signal is required. +Models are the place to develop the logic of how the devices are used and how the experiment is performed. You will find models for cameras and daqs. Cameras are heavily used in PyNTA, while DAQs where inherited from a previous incarnation and were left here as a reference and to speed up future developments in which not only a camera has to be controlled. The model for the experiment is the easiest place where the developer can have a sense of what is going on under-the-hood. You can check, for example, :mod:`~pynta.model.experiment.nanoparticle_tracking.np_tracking.NPTracking` in order to see the steps that make a tracking measurement. Remember that the program runs with different threads and processes in parallel, and therefore the behavior may not be trivial to understand. -Subpackages ------------ +.. automodule:: pynta.model + :members: + :undoc-members: + :show-inheritance: + .. toctree:: + :maxdepth: 1 + :caption: Available Models - pynta.model.cameras - pynta.model.daqs - pynta.model.experiment + cameras/index + daqs/index + experiments/index -Module contents ---------------- -.. automodule:: pynta.model - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/modules.rst b/docs/developers/modules.rst deleted file mode 100644 index 2138552..0000000 --- a/docs/developers/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -pynta -===== - -.. toctree:: - :maxdepth: 4 - - pynta diff --git a/docs/developers/pynta.controller.data_sources.rst b/docs/developers/pynta.controller.data_sources.rst deleted file mode 100644 index 66b5f57..0000000 --- a/docs/developers/pynta.controller.data_sources.rst +++ /dev/null @@ -1,10 +0,0 @@ -pynta.controller.data\_sources package -====================================== - -Module contents ---------------- - -.. automodule:: pynta.controller.data_sources - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.controller.devices.hamamatsu.rst b/docs/developers/pynta.controller.devices.hamamatsu.rst deleted file mode 100644 index 5b56010..0000000 --- a/docs/developers/pynta.controller.devices.hamamatsu.rst +++ /dev/null @@ -1,22 +0,0 @@ -pynta.controller.devices.hamamatsu package -========================================== - -Submodules ----------- - -pynta.controller.devices.hamamatsu.hamamatsu\_camera module ------------------------------------------------------------ - -.. automodule:: pynta.controller.devices.hamamatsu.hamamatsu_camera - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.controller.devices.hamamatsu - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.controller.devices.keysight.rst b/docs/developers/pynta.controller.devices.keysight.rst deleted file mode 100644 index e68486f..0000000 --- a/docs/developers/pynta.controller.devices.keysight.rst +++ /dev/null @@ -1,22 +0,0 @@ -pynta.controller.devices.keysight package -========================================= - -Submodules ----------- - -pynta.controller.devices.keysight.infiniivision module ------------------------------------------------------- - -.. automodule:: pynta.controller.devices.keysight.infiniivision - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.controller.devices.keysight - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.controller.devices.photonicscience.rst b/docs/developers/pynta.controller.devices.photonicscience.rst deleted file mode 100644 index 0aca3b7..0000000 --- a/docs/developers/pynta.controller.devices.photonicscience.rst +++ /dev/null @@ -1,22 +0,0 @@ -pynta.controller.devices.photonicscience package -================================================ - -Submodules ----------- - -pynta.controller.devices.photonicscience.scmoscam module --------------------------------------------------------- - -.. automodule:: pynta.controller.devices.photonicscience.scmoscam - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.controller.devices.photonicscience - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.controller.devices.rst b/docs/developers/pynta.controller.devices.rst deleted file mode 100644 index c48c276..0000000 --- a/docs/developers/pynta.controller.devices.rst +++ /dev/null @@ -1,19 +0,0 @@ -pynta.controller.devices package -================================ - -Subpackages ------------ - -.. toctree:: - - pynta.controller.devices.hamamatsu - pynta.controller.devices.keysight - pynta.controller.devices.photonicscience - -Module contents ---------------- - -.. automodule:: pynta.controller.devices - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.controller.rst b/docs/developers/pynta.controller.rst deleted file mode 100644 index f18eb60..0000000 --- a/docs/developers/pynta.controller.rst +++ /dev/null @@ -1,27 +0,0 @@ -Pynta Controllers -================= - -.. automodule:: pynta.controller - :members: - :undoc-members: - :show-inheritance: - -.. automodule:: pynta.controller.data_sources - :members: - :undoc-members: - :show-inheritance: - -.. automodule:: pynta.controller.devices - :members: - :undoc-members: - :show-inheritance: - -.. automodule:: pynta.controller.devices.photonicscience.scmoscam - :members: - :undoc-members: - :show-inheritance: - -.. automodule:: pynta.controller.devices.hamamatsu.hamamatsu_camera - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.exceptions.rst b/docs/developers/pynta.exceptions.rst index b4ab129..bae12e4 100644 --- a/docs/developers/pynta.exceptions.rst +++ b/docs/developers/pynta.exceptions.rst @@ -1,22 +1,7 @@ -pynta.exceptions package -======================== - -Submodules ----------- - -pynta.exceptions.exceptions module ----------------------------------- +Exceptions +========== .. automodule:: pynta.exceptions.exceptions :members: :undoc-members: :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.exceptions - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.model.cameras.rst b/docs/developers/pynta.model.cameras.rst deleted file mode 100644 index c12aaa3..0000000 --- a/docs/developers/pynta.model.cameras.rst +++ /dev/null @@ -1,61 +0,0 @@ -pynta.model.cameras package -=========================== - -Submodules ----------- - -pynta.model.cameras.dummy\_camera module ----------------------------------------- - -.. automodule:: pynta.model.cameras.dummy_camera - :members: - :undoc-members: - :show-inheritance: - -pynta.model.cameras.basler module ---------------------------------- -.. automodule:: pynta.model.cameras.basler - :members: - :undoc-members: - :show-inheritance: - -pynta.model.cameras.hamamatsu module ------------------------------------- - -.. automodule:: pynta.model.cameras.hamamatsu - :members: - :undoc-members: - :show-inheritance: - -pynta.model.cameras.psi module ------------------------------- - -.. automodule:: pynta.model.cameras.psi - :members: - :undoc-members: - :show-inheritance: - -pynta.model.cameras.simulate\_brownian module ---------------------------------------------- - -.. automodule:: pynta.model.cameras.simulate_brownian - :members: - :undoc-members: - :show-inheritance: - -pynta.model.cameras.skeleton module ------------------------------------ - -.. automodule:: pynta.model.cameras.skeleton - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.model.cameras - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.model.experiment.nano_cet.rst b/docs/developers/pynta.model.experiment.nano_cet.rst deleted file mode 100644 index cc29f19..0000000 --- a/docs/developers/pynta.model.experiment.nano_cet.rst +++ /dev/null @@ -1,70 +0,0 @@ -pynta.model.experiment.nano\_cet package -======================================== - -Submodules ----------- - -pynta.model.experiment.nano\_cet.decorators module --------------------------------------------------- - -.. automodule:: pynta.model.experiment.nanoparticle_tracking.decorators - :members: - :undoc-members: - :show-inheritance: - -pynta.model.experiment.nano\_cet.exceptions module --------------------------------------------------- - -.. automodule:: pynta.model.experiment.nanoparticle_tracking.exceptions - :members: - :undoc-members: - :show-inheritance: - -pynta.model.experiment.nano\_cet.localization module ----------------------------------------------------- - -.. automodule:: pynta.model.experiment.nanoparticle_tracking.localization - :members: - :undoc-members: - :show-inheritance: - -pynta.model.experiment.nano\_cet.nano\_cet module -------------------------------------------------- - -.. automodule:: pynta.model.experiment.nanoparticle_tracking.np_tracking - :members: - :undoc-members: - :show-inheritance: - -pynta.model.experiment.nano\_cet.saver module ---------------------------------------------- - -.. automodule:: pynta.model.experiment.nanoparticle_tracking.saver - :members: - :undoc-members: - :show-inheritance: - -pynta.model.experiment.nano\_cet.waterfall\_worker module ---------------------------------------------------------- - -.. automodule:: pynta.model.experiment.nanoparticle_tracking.waterfall_worker - :members: - :undoc-members: - :show-inheritance: - -pynta.model.experiment.nano\_cet.win\_nanocet module ----------------------------------------------------- - -.. automodule:: pynta.model.experiment.nanoparticle_tracking.np_tracking - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.model.experiment.nanoparticle_tracking - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.rst b/docs/developers/pynta.rst index f2ee8cd..efc814a 100644 --- a/docs/developers/pynta.rst +++ b/docs/developers/pynta.rst @@ -1,35 +1,16 @@ -pynta package -============= +.. _PyNTA: -Subpackages ------------ +PyNTA API +========= .. toctree:: + :maxdepth: 2 + :caption: Contents: - pynta.controller - pynta.exceptions - pynta.model + controller/index + model/index + view/index pynta.tests pynta.tools pynta.util - pynta.view - -Submodules ----------- - -pynta.config module -------------------- - -.. automodule:: pynta.config - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta - :members: - :undoc-members: - :show-inheritance: + pynta.exceptions diff --git a/docs/developers/pynta.view.GUI.old.Monitor.rst b/docs/developers/pynta.view.GUI.old.Monitor.rst deleted file mode 100644 index 44efea7..0000000 --- a/docs/developers/pynta.view.GUI.old.Monitor.rst +++ /dev/null @@ -1,70 +0,0 @@ -pynta.view.GUI.old.Monitor package -================================== - -Submodules ----------- - -pynta.view.GUI.old.Monitor.LocateParticle module ------------------------------------------------- - -.. automodule:: pynta.view.GUI.old.Monitor.LocateParticle - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.Monitor.cameraViewer module ----------------------------------------------- - -.. automodule:: pynta.view.GUI.old.Monitor.cameraViewer - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.Monitor.clearQueueThread module --------------------------------------------------- - -.. automodule:: pynta.view.GUI.old.Monitor.clearQueueThread - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.Monitor.crossCut module ------------------------------------------- - -.. automodule:: pynta.view.GUI.old.Monitor.crossCut - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.Monitor.popOut module ----------------------------------------- - -.. automodule:: pynta.view.GUI.old.Monitor.popOut - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.Monitor.resources module -------------------------------------------- - -.. automodule:: pynta.view.GUI.old.Monitor.resources - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.Monitor.specialTaskTrack module --------------------------------------------------- - -.. automodule:: pynta.view.GUI.old.Monitor.specialTaskTrack - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.view.GUI.old.Monitor - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.view.GUI.old.rst b/docs/developers/pynta.view.GUI.old.rst deleted file mode 100644 index 9ef9a84..0000000 --- a/docs/developers/pynta.view.GUI.old.rst +++ /dev/null @@ -1,61 +0,0 @@ -pynta.view.GUI.old package -========================== - -Subpackages ------------ - -.. toctree:: - - pynta.view.GUI.old.Monitor - -Submodules ----------- - -pynta.view.GUI.old.mainwindow module ------------------------------------- - -.. automodule:: pynta.view.GUI.old.mainwindow - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.messageWidget module ---------------------------------------- - -.. automodule:: pynta.view.GUI.old.messageWidget - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.trajectoryWidget module ------------------------------------------- - -.. automodule:: pynta.view.GUI.old.trajectoryWidget - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.waterfallWidget module ------------------------------------------ - -.. automodule:: pynta.view.GUI.old.waterfallWidget - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.old.workerThread module --------------------------------------- - -.. automodule:: pynta.view.GUI.old.workerThread - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.view.GUI.old - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.view.GUI.rst b/docs/developers/view/GUI.rst similarity index 51% rename from docs/developers/pynta.view.GUI.rst rename to docs/developers/view/GUI.rst index 187085a..73a2974 100644 --- a/docs/developers/pynta.view.GUI.rst +++ b/docs/developers/view/GUI.rst @@ -1,85 +1,48 @@ -pynta.view.GUI package -====================== - -Subpackages ------------ - -.. toctree:: - - pynta.view.GUI.old - -Submodules ----------- +GUI modules +=========== +.. automodule:: pynta.view.GUI + :members: + :undoc-members: + :show-inheritance: -pynta.view.GUI.camera\_viewer\_widget module --------------------------------------------- +.. automodule:: pynta.view.GUI.camera_focusing + :members: + :undoc-members: + :show-inheritance: .. automodule:: pynta.view.GUI.camera_viewer_widget :members: :undoc-members: :show-inheritance: -pynta.view.GUI.config\_tracking\_widget module ----------------------------------------------- - .. automodule:: pynta.view.GUI.config_tracking_widget :members: :undoc-members: :show-inheritance: -pynta.view.GUI.config\_widget module ------------------------------------- - .. automodule:: pynta.view.GUI.config_widget :members: :undoc-members: :show-inheritance: -pynta.view.GUI.histogram\_tracks\_widget module ------------------------------------------------ - .. automodule:: pynta.view.GUI.histogram_tracks_widget :members: :undoc-members: :show-inheritance: -pynta.view.GUI.histogram\_widget module ---------------------------------------- - .. automodule:: pynta.view.GUI.histogram_widget :members: :undoc-members: :show-inheritance: -pynta.view.GUI.main\_window module ----------------------------------- - .. automodule:: pynta.view.GUI.main_window :members: :undoc-members: :show-inheritance: -pynta.view.GUI.resources module -------------------------------- - -.. automodule:: pynta.view.GUI.resources - :members: - :undoc-members: - :show-inheritance: - -pynta.view.GUI.tracks\_widget module ------------------------------------- - .. automodule:: pynta.view.GUI.tracks_widget :members: :undoc-members: :show-inheritance: -Module contents ---------------- - -.. automodule:: pynta.view.GUI - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/developers/pynta.view.rst b/docs/developers/view/index.rst similarity index 52% rename from docs/developers/pynta.view.rst rename to docs/developers/view/index.rst index 8044456..5bb2a2e 100644 --- a/docs/developers/pynta.view.rst +++ b/docs/developers/view/index.rst @@ -1,37 +1,22 @@ -pynta.view package -================== - -Subpackages ------------ +View +==== +.. automodule:: pynta.view + :members: + :undoc-members: + :show-inheritance: .. toctree:: + :maxdepth: 1 + :caption: Contents - pynta.view.GUI - -Submodules ----------- - -pynta.view.main module ----------------------- + GUI .. automodule:: pynta.view.main :members: :undoc-members: :show-inheritance: -pynta.view.subscriber\_thread module ------------------------------------- - .. automodule:: pynta.view.subscriber_thread :members: :undoc-members: :show-inheritance: - - -Module contents ---------------- - -.. automodule:: pynta.view - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/index.rst b/docs/index.rst index 83c6647..374456b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -58,7 +58,7 @@ Organization, under VICI grant (PI: Prof. Allard Mosk) and Projectruimte FOM.PR1 .. toctree:: :maxdepth: 2 - :caption: Contents: + :caption: Contents installing example_config diff --git a/docs/requirements_docs.txt b/docs/requirements_docs.txt new file mode 100644 index 0000000..78cae68 --- /dev/null +++ b/docs/requirements_docs.txt @@ -0,0 +1,67 @@ +alabaster==0.7.12 +asn1crypto==0.24.0 +Babel==2.7.0 +certifi==2019.6.16 +cffi==1.12.3 +chardet==3.0.4 +cryptography==2.7 +cycler==0.10.0 +docutils==0.14 +h5py==2.9.0 +idna==2.8 +imagesize==1.1.0 +Jinja2==2.10.1 +kiwisolver==1.1.0 +lantz-core==0.5.3 +lantz-drivers==0.5.2 +lantz-ino==0.5.2 +lantz-qt==0.5.3 +lantz-sims==0.5.2 +lantzdev==0.5.2 +llvmlite==0.29.0 +MarkupSafe==1.1.1 +matplotlib==3.1.1 +mkl-fft==1.0.12 +mkl-random==1.0.2 +numba==0.45.0 +numpy==1.16.4 +packaging==19.0 +pandas==0.24.2 +pimpmyclass==0.4.3 +Pint==0.9 +pycparser==2.19 +PyDAQmx==1.4.2 +Pygments==2.4.2 +pyOpenSSL==19.0.0 +pyparsing==2.4.1 +pypylon==1.4.0 +pyqt5==5.13.0 +pyqt5-sip==4.19.18 +pyqtgraph==0.10.0 +pyreadline==2.1 +PySignal==1.1.1 +PySocks==1.7.0 +python-dateutil==2.8.0 +pytz==2019.1 +PyVISA==1.9.1 +PyYAML==5.1.1 +pyzmq==18.0.0 +requests==2.22.0 +scipy==1.2.1 +Serialize==0.1 +six==1.12.0 +snowballstemmer==1.9.0 +Sphinx==2.1.2 +sphinx-rtd-theme==0.4.3 +sphinxcontrib-applehelp==1.0.1 +sphinxcontrib-devhelp==1.0.1 +sphinxcontrib-htmlhelp==1.0.2 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.2 +sphinxcontrib-serializinghtml==1.1.3 +stringparser==0.5 +tornado==6.0.3 +trackpy==0.4.1 +urllib3==1.24.2 +win-inet-pton==1.1.0 +wincertstore==0.2 diff --git a/examples/config/dispertech.yml b/examples/config/dispertech.yml new file mode 100644 index 0000000..e405e3d --- /dev/null +++ b/examples/config/dispertech.yml @@ -0,0 +1,92 @@ +%YAML 1.2 +--- +# Default parameters for the Tracking program +# All parameters can be changed to accommodate user needs. +# All parameters can be changed at runtime with the appropriate config window +user: + name: Aquiles + +arduino: + port: COM3 + +saving: + auto_save: False + auto_save_waterfall: True + directory: D:\Data + filename_video: Video # Can be the same filename for video and photo + filename_photo: Snap + filename_tracks: Tracks + filename_waterfall: Waterfall + filename_trajectory: Trajectory + filename_log: Log + max_memory: 200 # In megabytes + +GUI: + length_waterfall: 20 # Total length of the Waterfall (lines) + refresh_time: 50 # Refresh rate of the GUI (in ms) + +camera_fiber: + model: basler # Should be a python file in model/cameras + init: daA1280 # Initial arguments to pass when creating the camera + #extra_args: [extra, arguments] # Extra arguments that can be passed when constructing the model + model_camera: Dart # To keep a registry of which camera was used in the experiment + exposure_time: 30ms # Initial exposure time (in ms) + fps: 30 # Frames per second, should either be defined by the camera or within the model based on timing + binning_x: 1 # Binning + binning_y: 1 + roi_x1: 0 + roi_x2: 1280 + roi_y1: 0 + roi_y2: 960 + background: '' # Full path to background file, or empty for none. + background_method: [Method1, Method2] + +camera_microscope: + model: basler # Should be a python file in model/cameras + init: acA1920 # Initial arguments to pass when creating the camera + #extra_args: [extra, arguments] # Extra arguments that can be passed when constructing the model + model_camera: ACE # To keep a registry of which camera was used in the experiment + exposure_time: 30ms # Initial exposure time (in ms) + fps: 30 # Frames per second, should either be defined by the camera or within the model based on timing + binning_x: 1 # Binning + binning_y: 1 + roi_x1: 0 + roi_x2: 1920 + roi_y1: 0 + roi_y2: 1200 + background: '' # Full path to background file, or empty for none. + background_method: [Method1, Method2] + +waterfall: # Parameters for calculating the waterfall plot + length: 20 # The total length of the waterfall (lines) + vertical_bin: 10 # Total number of lines of the CCD to integrate + +movie: + buffer_length: 1000 # Frames + +tracking: + locate: + diameter: 5 # Diameter of the particles (in pixels) to track, has to be an odd number + invert: False + minmass: 100 + link: + memory: 3 + search_range: 5 + filter: # Filter spurious trajectories + min_length: 25 + process: + compute_drift: False + um_pixel: 0.15 # Microns per pixel (calibration of the microscope) + min_traj_length: 2 + min_mass: 0.05 + max_size: 50.0 + max_ecc: 1 + fps: 30 + param_1: 0. + param_2: 0 + +debug: + logging_level: Nothing # One of Nothing, Debug, Info, Warning, Error + queue_memory: False + to_screen: True + diff --git a/pynta/config.py b/pynta/config.py index 7033353..a9817c6 100644 --- a/pynta/config.py +++ b/pynta/config.py @@ -7,7 +7,7 @@ or falling edge of the trigger, etc. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ diff --git a/pynta/controller/devices/__init__.py b/pynta/controller/devices/__init__.py index f7bb992..8793fb5 100644 --- a/pynta/controller/devices/__init__.py +++ b/pynta/controller/devices/__init__.py @@ -5,5 +5,11 @@ external libraries. Thus, be aware that you may need to install some dependencies in order to make the controllers work correctly. A common example is the requirement of pyvisa to communicate with serial devices, or the DLL's from Hamamatsu in order to use their cameras. + + For several devices, drivers in Python are provided by the manufacturers and thus they won't be found in this + module. A clear example is the Python wrapper of Pylon to work with Basler cameras, known as PyPylon. In that case, + PyNTA only provides a model which relies on that package. For DAQ devices such as those from National Instruments, + PyNTA depends on PyDAQmx, although NI has released its own wrapper, + `NIDAQmx-Python `_ which may be worth exploring. """ diff --git a/pynta/controller/devices/hamamatsu/hamamatsu_camera.py b/pynta/controller/devices/hamamatsu/hamamatsu_camera.py index 5ccd4cc..f63b95d 100644 --- a/pynta/controller/devices/hamamatsu/hamamatsu_camera.py +++ b/pynta/controller/devices/hamamatsu/hamamatsu_camera.py @@ -1,11 +1,10 @@ # -*- coding: utf-8 -*- """ - hamamatsu_camera.py - ~~~~~~~~~~~~~~~~~~~~ - File taken from `ZhuangLab `_ + Hamamatsu Driver + ================ + Original file taken from `ZhuangLab `_ - A ctypes based interface to Hamamatsu cameras. - (tested on a sCMOS Flash 4.0). + A ctypes based interface to Hamamatsu cameras. (tested on a sCMOS Flash 4.0). The documentation is a little confusing to me on this subject.. I used c_int32 when this is explicitly specified, otherwise I use c_int. @@ -14,9 +13,10 @@ .. todo:: How to stream 2048 x 2048 at max frame rate to the flash disk? The Hamamatsu software can do this. - Copyright: Hazen Babcock - This file was adapted to Python 3 and documented in the numpy style by Aquiles Carattino + This file was adapted to Python 3 and documented in the numpy style by Aquiles Carattino + :copyright: Hazen Babcock + :license: The MIT License """ import ctypes diff --git a/pynta/controller/devices/keysight/infiniivision.py b/pynta/controller/devices/keysight/infiniivision.py index a5f96a0..fa9bdc1 100644 --- a/pynta/controller/devices/keysight/infiniivision.py +++ b/pynta/controller/devices/keysight/infiniivision.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- - """ - inifiniivision.py - ~~~~~~~~~~~~~~~~~ + Keysight InfiniiVision + ====================== Driver for the Keysight InfiniiVision DSOX2022A oscilloscope with function generation capabilities. Source: Programmers Guide, Version 02.39.0000 by Keysight Technologies @@ -10,7 +9,7 @@ .. note:: Not all functions were implemented in the code as methods in the class. However a fair amount of the most useful ones was formatted according to Lantz standards. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ diff --git a/pynta/controller/devices/photonicscience/scmoscam.py b/pynta/controller/devices/photonicscience/scmoscam.py index 452b814..c4a6cfe 100644 --- a/pynta/controller/devices/photonicscience/scmoscam.py +++ b/pynta/controller/devices/photonicscience/scmoscam.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - scmoscam.py - ~~~~~~~~~~~ + Photonic Science GEVSCMOS + ========================= Driver for Photonic Science Cameras (Pleora GEV). This driver was originally written by Perceval Guillou , in Py2 and has been successfully tested with scmoscontrol.dll SCMOS Pleora (GEV) control dll (x86 )v5.6.0.0 (date modified 10/2/2013) diff --git a/pynta/model/cameras/base_camera.py b/pynta/model/cameras/base_camera.py index 46e04be..62f0a5b 100644 --- a/pynta/model/cameras/base_camera.py +++ b/pynta/model/cameras/base_camera.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - Base Camera - =========== + Base Camera Model + ================= Camera class with the base methods. Having a base class exposes the general API for working with cameras. This file is important to keep track of the methods which are exposed to the View. The class BaseCamera should be subclassed when developing new Models for other cameras. This ensures that all the @@ -22,7 +22,7 @@ .. note:: **IMPORTANT** Whatever new function is implemented in a specific model, it should be first declared in the BaseCamera class. In this way the other models will have access to the method and the program will keep running (perhaps with non intended behavior though). - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ import numpy as np @@ -35,30 +35,32 @@ logger = get_logger(__name__) - class BaseCamera: MODE_CONTINUOUS = 1 MODE_SINGLE_SHOT = 0 + ACQUISITION_MODE = { + MODE_CONTINUOUS: 'Continuous', + MODE_SINGLE_SHOT: 'Single' + } def __init__(self, camera): self.camera = camera self.running = False - self.maxWidth = 0 - self.maxHeight = 0 + self.max_width = 0 + self.max_height = 0 self.exposure = 0 self.config = {} self.data_type = np.uint16 # The data type that the camera generates when acquiring images. It is very important to have it available in order to create the buffer and saving to disk. self.logger = get_logger(name=__name__) - def configure(self, properties): + def configure(self, properties: dict): self.logger.info('Updating config') update_cam = False update_roi = False update_exposure = False - update_binning = True - for k in properties: - new_prop = properties[k] + update_binning = False + for k, new_prop in properties.items(): self.logger.debug('Updating {} to {}'.format(k, new_prop)) update_cam = True @@ -79,22 +81,24 @@ def configure(self, properties): if update_cam: if update_roi: - - X = np.sort([properties['roi_x1'], properties['roi_x2']]) - Y = np.sort([properties['roi_y1'], properties['roi_y2']]) - self.setROI(X, Y) + X = sorted([properties['roi_x1'], properties['roi_x2']]) + Y = sorted([properties['roi_y1'], properties['roi_y2']]) + self.set_ROI(X, Y) self.config.update({'roi_x1': X[0], 'roi_x2': X[1], 'roi_y1': Y[0], 'roi_y2': Y[1]}) if update_exposure: - exposure = Q_(properties['exposure_time']) + exposure = properties['exposure_time'] + if isinstance(exposure, str): + exposure = Q_(exposure) + new_exp = self.set_exposure(exposure) self.config['exposure_time'] = new_exp if update_binning: - self.setBinning(properties['binning_x'], properties['binning_y']) + self.set_binning(properties['binning_x'], properties['binning_y']) self.config.update({'binning_x': properties['binning_x'], 'binning_y': properties['binning_y']}) @@ -103,8 +107,8 @@ def initialize(self): """ Initializes the camera. """ - self.maxWidth = self.GetCCDWidth() - self.maxHeight = self.GetCCDHeight() + self.max_width = self.GetCCDWidth() + self.max_height = self.GetCCDHeight() return True @not_implemented @@ -123,7 +127,6 @@ def set_acquisition_mode(self, mode): """ self.mode = mode - @not_implemented def get_acquisition_mode(self): """ Returns the acquisition mode, either continuous or single shot. @@ -159,7 +162,7 @@ def read_camera(self): pass @not_implemented - def setROI(self, X, Y): + def set_ROI(self, X, Y): """ Sets up the ROI. Not all cameras are 0-indexed, so this is an important place to define the proper ROI. @@ -170,14 +173,14 @@ def setROI(self, X, Y): return X, Y - def clearROI(self): + def clear_ROI(self): """ Clears the ROI from the camera. """ - self.setROI([0, self.maxWidth], [0, self.maxHeight]) + self.set_ROI([0, self.max_width], [0, self.max_height]) @not_implemented - def getSize(self): + def get_size(self): """Returns the size in pixels of the image being acquired. This is useful for checking the ROI settings. """ pass @@ -208,7 +211,7 @@ def stopAcq(self): pass @not_implemented - def setBinning(self, xbin, ybin): + def set_binning(self, xbin, ybin): """ Sets the binning of the camera if supported. Has to check if binning in X/Y can be different or not, etc. @@ -218,10 +221,18 @@ def setBinning(self, xbin, ybin): """ pass + @not_implemented + def clear_binning(self): + """ + Clears the binning of the camera to its default value. + """ + pass + @not_implemented def stop_camera(self): """Stops the acquisition and closes the connection with the camera. """ pass - + def __str__(self): + return f"Base Camera {self.camera}" diff --git a/pynta/model/cameras/basler.py b/pynta/model/cameras/basler.py index 552d0c1..d684233 100644 --- a/pynta/model/cameras/basler.py +++ b/pynta/model/cameras/basler.py @@ -1,15 +1,17 @@ """ Basler Camera Model =================== - Model to adapt PyPylon to the needs of Pynta. PyPylon is only a wrapper for Pylon, thus the documentation + Model to adapt PyPylon to the needs of PyNTA. PyPylon is only a wrapper for Pylon, thus the documentation has to be found in the folder where Pylon was installed. It refers only to the C++ documentation, which is very extensive, but not necessarily clear. Some assumptions ---------------- - The program forces software trigger during :meth:`~nanoparticle_tracking.model.cameras.basler.Camera.initialize`. + The program forces software trigger during :meth:`~pynta.model.cameras.basler.Camera.initialize`. """ import logging +import warnings +from typing import Tuple from pypylon import pylon @@ -27,15 +29,19 @@ def __init__(self, camera): self.cam_num = camera self.max_width = 0 self.max_height = 0 - self.logger = get_logger(name=__name__) + self.width = None + self.height = None self.mode = None + self.X = None + self.Y = None + self.friendly_name = None def initialize(self): """ Initializes the communication with the camera. Get's the maximum and minimum width. It also forces the camera to work on Software Trigger. - .. warning:: It may be useful to integrate with other types of triggers in applications that need to - synchronize with other hardware. + .. warning:: It may be useful to integrate other types of triggers in applications that need to + synchronize with other hardware. """ logger.debug('Initializing Basler Camera') @@ -44,20 +50,35 @@ def initialize(self): if len(devices) == 0: raise CameraNotFound('No camera found') - self.camera = pylon.InstantCamera() - self.camera.Attach(tl_factory.CreateDevice(devices[self.cam_num])) - self.camera.Open() + for device in devices: + if self.cam_num in device.GetFriendlyName(): + self.camera = pylon.InstantCamera() + self.camera.Attach(tl_factory.CreateDevice(device)) + self.camera.Open() + self.friendly_name = device.GetFriendlyName() + + if not self.camera: + msg = f'{self.cam_num} not found. Please check your config file and cameras connected' + logger.error(msg) + raise CameraNotFound(msg) logger.info(f'Loaded camera {self.camera.GetDeviceInfo().GetModelName()}') self.max_width = self.camera.Width.Max self.max_height = self.camera.Height.Max + offsetX = self.camera.OffsetX.Value + offsetY = self.camera.OffsetY.Value + width = self.camera.Width.Value + height = self.camera.Height.Value + self.X = (offsetX, offsetX+width) + self.Y = (offsetY, offsetY+height) + self.camera.RegisterConfiguration(pylon.SoftwareTriggerConfiguration(), pylon.RegistrationMode_ReplaceAll, pylon.Cleanup_Delete) self.set_acquisition_mode(self.MODE_SINGLE_SHOT) def set_acquisition_mode(self, mode): - self.logger.info(f'Setting acquisition mode to {mode}') + logger.info(f'Setting acquisition mode to {mode}') if mode == self.MODE_CONTINUOUS: logger.debug(f'Setting buffer to {self.camera.MaxNumBuffer.Value}') self.camera.OutputQueueSize = self.camera.MaxNumBuffer.Value @@ -69,26 +90,32 @@ def set_acquisition_mode(self, mode): self.camera.AcquisitionStart.Execute() - def setROI(self, X, Y): + def set_ROI(self, X: Tuple[int, int], Y: Tuple[int, int]) -> Tuple[int, int]: """ Set up the region of interest of the camera. Basler calls this the Area of Interest (AOI) in their manuals. Beware that not all cameras allow to set the ROI (especially if they are not area sensors). Both the corner positions and the width/height need to be multiple of 4. Compared to Hamamatsu, Baslers provides a very descriptive error warning. + :param tuple X: Horizontal limits for the pixels, 0-indexed and including the extremes. You can also check + :mod:`Base Camera ` + To select, for example, the first 100 horizontal pixels, you would supply the following: (0, 99) + :param tuple Y: Vertical limits for the pixels. + """ - width = abs(X[1]-X[0]) + width = abs(X[1]-X[0])+1 width = int(width-width%4) x_pos = int(X[0]-X[0]%4) - height = int(abs(Y[1]-Y[0])) + height = int(abs(Y[1]-Y[0])+1) y_pos = int(Y[0]-Y[0]%2) + logger.info(f'Updating ROI: (x, y, width, height) = ({x_pos}, {y_pos}, {width}, {height})') if x_pos+width > self.max_width: raise CameraException('ROI width bigger than camera area') if y_pos+height > self.max_height: raise CameraException('ROI height bigger than camera area') # First set offset to minimum, to avoid problems when going to a bigger size - self.clearROI() + self.clear_ROI() logger.debug(f'Setting width to {width}') self.camera.Width.SetValue(width) logger.debug(f'Setting X offset to {x_pos}') @@ -97,25 +124,50 @@ def setROI(self, X, Y): self.camera.Height.SetValue(height) logger.debug(f'Setting Y offset to {y_pos}') self.camera.OffsetY.SetValue(y_pos) - self.X = [x_pos, x_pos+width] - self.Y = [y_pos, y_pos+width] - self.width = width - self.heigth = height - return width, height - - def clearROI(self): + self.X = (x_pos, x_pos+width) + self.Y = (y_pos, y_pos+width) + self.width = self.camera.Width.Value + self.height = self.camera.Height.Value + return self.width, self.height + + def clear_ROI(self): + """ Resets the ROI to the maximum area of the camera""" self.camera.OffsetX.SetValue(self.camera.OffsetX.Min) self.camera.OffsetY.SetValue(self.camera.OffsetY.Min) self.camera.Width.SetValue(self.camera.Width.Max) self.camera.Height.SetValue(self.camera.Height.Max) - def GetCCDWidth(self): + def GetCCDWidth(self) -> int: + """ Get the full width of the camera sensor. + + :return int: Maximum width + + .. deprecated:: 0.1.3 + Use self.max_width instead + + """ + warnings.warn("This method will be removed in a future release. Use cls.max_width instead", DeprecationWarning) return self.max_width - def GetCCDHeight(self): + def GetCCDHeight(self) -> int: + """ Get the full height (in pixels) of the camera sensor. + + :return int: Maximum height + + .. deprecated:: 0.1.3 + Use self.max_height instead + + """ + warnings.warn("This method will be removed in a future release. Use cls.max_height instead", DeprecationWarning) return self.max_height - def getSize(self): + def get_size(self) -> Tuple[int, int]: + """ Get the size of the current Region of Interest (ROI). Remember that the actual size may be different from + the size that the user requests, given that not all cameras accept any pixel. For example, Basler has some + restrictions regarding corner pixels and possible widths. + + :return tuple: (Width, Height) + """ return self.camera.Width.Value, self.camera.Height.Value def trigger_camera(self): @@ -160,9 +212,13 @@ def read_camera(self): return [i.T for i in img] # Transpose to have the correct size def stop_camera(self): + logger.info('Stopping camera') self.camera.StopGrabbing() self.camera.AcquisitionStop.Execute() + def __str__(self): + return self.friendly_name + def __del__(self): self.camera.Close() diff --git a/pynta/model/cameras/dummy_camera.py b/pynta/model/cameras/dummy_camera.py index 0421cdb..728c532 100644 --- a/pynta/model/cameras/dummy_camera.py +++ b/pynta/model/cameras/dummy_camera.py @@ -1,19 +1,19 @@ # -*- coding: utf-8 -*- """ - dummyCamera.py - ~~~~~~~~~~~~~~ + Dummy Camera Model + ================== Dummy camera class for testing GUI and other functionality. This specific version generates randomly diffusing - particles. However, the settings are controlled in a different class, SimBrownian. + particles. However, the settings are controlled in a different class, :mod:`SimBrownian `. .. TODO:: The camera defines plenty of parameters that are not used or that they are confusing later on. Rasing - exceptions does not happen even if trying to extend beyond the maximum dimensions of the CCD. + exceptions does not happen even if trying to extend beyond the maximum dimensions of the CCD. .. TODO:: The parameters for the simulation of the brownian motion should be made explicitly here, in such a way - that can be used from within the config file as well. + that can be used from within the config file as well. .. TODO:: Some of the methods do not return the same datatype as the real models - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ @@ -98,7 +98,7 @@ def read_camera(self): time.sleep(self.exposure.m_as('s') - elapsed) # to simulate exposure time corrected for data generation delay return [sample] - def setROI(self, X, Y): + def set_ROI(self, X, Y): """ Sets up the ROI. Not all cameras are 0-indexed, so this is an important place to define the proper ROI. @@ -116,9 +116,9 @@ def setROI(self, X, Y): self.Y = Y self.X[1] -= 1 self.Y[1] -= 1 - return self.getSize() + return self.get_size() - def getSize(self): + def get_size(self): """ :return: Returns the size in pixels of the image being acquired. This is useful for checking the ROI settings. """ @@ -142,7 +142,7 @@ def GetCCDHeight(self): """ return self.maxY - def setBinning(self, xbin, ybin): + def set_binning(self, xbin, ybin): """Sets the binning of the camera if supported. Has to check if binning in X/Y can be different or not, etc. :param: xbin: binning in x diff --git a/pynta/model/cameras/hamamatsu.py b/pynta/model/cameras/hamamatsu.py index 2ff97de..9a03bee 100644 --- a/pynta/model/cameras/hamamatsu.py +++ b/pynta/model/cameras/hamamatsu.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - hamamatsu.py - ~~~~~~~~~~~~ + Hamamatsu Model + =============== Model class for controlling Hamamatsu cameras via de DCAM-API. At the time of writing this class, little documentation on the DCAM-API was available. Hamamatsu has a different time schedule regarding support of @@ -11,13 +11,13 @@ DCAM-API relies mostly on setting parameters into the camera. The correct data type of each parameter is not well documented; however it is possible to print all the available properties and work from there. The properties are stored in a filed named params.txt next to the :mod:`Hamamatsu Driver - ` + ` .. note:: When setting the ROI, Hamamatsu only allows to set multiples of 4 for every setting (X,Y and vsize, hsize). This is checked in the function. Changing the ROI cannot be done directly, one first needs to disable it and then re-enable. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ import numpy as np @@ -43,10 +43,10 @@ def initialize(self): :return: """ self.camera.initCamera() - self.maxWidth = self.GetCCDWidth() - self.maxHeight = self.GetCCDHeight() - self.X = [0, self.maxWidth-1] - self.Y = [0, self.maxHeight-1] + self.max_width = self.GetCCDWidth() + self.max_height = self.GetCCDHeight() + self.X = [0, self.max_width - 1] + self.Y = [0, self.max_height - 1] # This is important to not have shufled patches of the CCD. # Have to check documentation!! @@ -121,7 +121,7 @@ def read_camera(self): # img = np.reshape(img,(dims[0],dims[1])) return img - def setROI(self, X, Y): + def set_ROI(self, X, Y): """ Sets up the ROI. Not all cameras are 0-indexed, so this is an important place to define the proper ROI. @@ -148,9 +148,9 @@ def setROI(self, X, Y): self.camera.setPropertyValue("subarray_vsize", vsize) self.camera.setPropertyValue("subarray_hsize", hsize) self.camera.setSubArrayMode() - return self.getSize() + return self.get_size() - def getSize(self): + def get_size(self): """Returns the size in pixels of the image being acquired. This is useful for checking the ROI settings. """ X = self.camera.getPropertyValue("subarray_hsize") diff --git a/pynta/model/cameras/psi.py b/pynta/model/cameras/psi.py index 3432fb7..deeda50 100644 --- a/pynta/model/cameras/psi.py +++ b/pynta/model/cameras/psi.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- """ - psi.py - ~~~~~~ + Photonic Science GEV Model + ========================== Model for Photonic Science GEV Cameras. The model just implements the basic methods defined in the - :meth:`~nanoparticle_tracking.model.cameras.skeleton.BaseCamera` using a Photonic Sicence camera. The controller for this - camera is :mod:`~nanoparticle_tracking.controller.devices.photonicscience` + :meth:`~pynta.model.cameras.base_camera.BaseCamera` using a Photonic Sicence camera. The controller for this + camera is :mod:`~pynta.controller.devices.photonicscience` - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ import numpy as np @@ -28,7 +28,7 @@ def initialize(self): """ Initializes the camera. - .. todo:: :meth:`UUTrack.Controller.devices.PhotonicScience.scmoscam.GEVSCMOS.SetGainMode` behaves unexpectedly. + .. todo:: :meth:`pynta.controller.devices.photonicscience.scmoscam.GEVSCMOS.SetGainMode` behaves unexpectedly. One is forced to set the gain mode twice to have it right. So far, this is the only way to prevent the *weird lines* from appearing. Checking the meaning of the gains is a **must**. @@ -42,9 +42,9 @@ def initialize(self): self.camera.EnableAutoLevel(0) self.camera.SetExposure(10, "Millisec") self.trigger_camera() - size = self.getSize() - self.maxWidth = size[0] - self.maxHeight = size[1] + size = self.get_size() + self.max_width = size[0] + self.max_height = size[1] self.camera.SetGainMode("gain30") # Change the gain here! Check scmoscam.py for information def trigger_camera(self): @@ -73,7 +73,7 @@ def read_camera(self): img = np.array(img) return np.transpose(img) - def setROI(self, X, Y): + def set_ROI(self, X, Y): """Sets up the ROI. """ X -= 1 @@ -86,7 +86,7 @@ def setROI(self, X, Y): self.camera.SetSubArea(l, t, r, b) return self.camera.GetSize() - def getSize(self): + def get_size(self): """Returns the size in pixels of the image being acquired. """ return self.camera.GetSize() @@ -117,11 +117,11 @@ def getParameters(self): def GetCCDWidth(self): """Gets the CCD width.""" - return self.getSize()[0] + return self.get_size()[0] def GetCCDHeight(self): """Gets the CCD height.""" - return self.getSize()[1] + return self.get_size()[1] def stopAcq(self): """Stop the acquisition even if ongoing.""" diff --git a/pynta/model/cameras/simulate_brownian.py b/pynta/model/cameras/simulate_brownian.py index 04568b7..637f951 100644 --- a/pynta/model/cameras/simulate_brownian.py +++ b/pynta/model/cameras/simulate_brownian.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - simulate_brownian.py - ==================== + Simulated Brownian Diffusion + ============================ The SimBrownian class generates synthetic images corresponding to particles performing a thermal Brownian motion. This class was designed in order to make explicit the real parameters of the particles (i.e. the diffusion coefficient in real-space) with the magnification of the microscope. The PSF on the camera is derived from the @@ -16,7 +16,7 @@ .. TODO:: Think how to add noise, background, and intensity fluuctuations to the particles. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ import numpy as np diff --git a/pynta/model/daqs/NI.py b/pynta/model/daqs/NI.py index e5d2d02..9e7710d 100644 --- a/pynta/model/daqs/NI.py +++ b/pynta/model/daqs/NI.py @@ -27,8 +27,10 @@ or renaming implies that you have to check all the downstream code, and being YML the first step, it will imply reviewing everything. + .. TODO:: National Instruments has releasedi its own Python driver (NIDAQmx-Python) which may be worth exploring for + future development - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ try: diff --git a/pynta/model/daqs/daq_dummy.py b/pynta/model/daqs/daq_dummy.py index 5651479..41bce0a 100644 --- a/pynta/model/daqs/daq_dummy.py +++ b/pynta/model/daqs/daq_dummy.py @@ -1,20 +1,24 @@ # -*- coding: utf-8 -*- """ - nanoparticle_tracking.model.daqs.daq_dummy.py - ==================================== - Dummy daq class for testing GUI and other functionalities. Based on the skeleton. + Dummy DAQ + ========= + DAQ model for testing GUI and other functionalities. Based on the skeleton. It does not interact with any real + device, it just generates random data and accepts inputs which have no effect. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ +from pynta.util import get_logger from .skeleton import DaqBase +logger = get_logger(__name__) + class DAQDummy(DaqBase): def __init__(self, dev_number=None): - print('Initialized device with number: %s' % dev_number) + super().__init__(dev_number) + logger.info('Initialized device with number: %s' % dev_number) self.test_value = 0 - pass def triggerAnalog(self, conditions): """Triggers an analog measurement. It does not read the value. diff --git a/pynta/model/daqs/skeleton.py b/pynta/model/daqs/skeleton.py index 3c33b16..0834842 100644 --- a/pynta/model/daqs/skeleton.py +++ b/pynta/model/daqs/skeleton.py @@ -1,18 +1,21 @@ # -*- coding: utf-8 -*- """ - base_camera.py - ~~~~~~~~~~~ + Base Model for DAQs + =================== + Base model that makes explicit the API for working with DAQ cards. Every new DAQ card should inherit this model. + This allows to check the argument type, for example, but they also guarantee forward-compatibility in case new + methods are developed. .. note:: **IMPORTANT** Whatever new function is implemented in a specific model, it should be first declared in the - laserBase class. In this way the other models will have access to the method and the program will keep running - (perhaps with non intended behavior though). + laserBase class. In this way the other models will have access to the method and the program will keep running + (perhaps with non intended behavior though). - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: AGPLv3, see LICENSE for more details """ -class DaqBase(): +class DaqBase: def __init__(self, dev_number): self.dev_number = dev_number @@ -42,4 +45,4 @@ def read_analog(self, task_number, conditions): """ Gets the analog values acquired with the triggerAnalog function. """ - pass \ No newline at end of file + pass diff --git a/pynta/model/experiment/__init__.py b/pynta/model/experiment/__init__.py index 6a335f2..08a0f97 100644 --- a/pynta/model/experiment/__init__.py +++ b/pynta/model/experiment/__init__.py @@ -1,3 +1,18 @@ +# -*- coding: utf-8 -*- +""" + Experiment Models + ================= + Experiment models make explicit the different steps needed to perform a measurement. The Base Experiment class + defines some methods that are transversal to all experiments (such as loading a configuration file) but individual + experiment models can overwrite this methods to develop custom solutions. + + Moreover, PyNTA introduces the PUB/SUB pattern in order to exchange information between different parts of the + program in a flexible and efficient way. You can find more information on :mod:`~pynta.model.experiment.publisher` + and :mod:`~pynta.model.experiment.subscriber`. + + :copyright: Aquiles Carattino + :license: GPLv3, see LICENSE for more details +""" from pynta.model.experiment.config import Config config = Config() \ No newline at end of file diff --git a/pynta/model/experiment/base_experiment.py b/pynta/model/experiment/base_experiment.py index 9f6ddf6..8f0e592 100644 --- a/pynta/model/experiment/base_experiment.py +++ b/pynta/model/experiment/base_experiment.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ base_experiment.py - ~~~~~~~~~~~~~~~~~~ + ================== Base class for the experiments. ``BaseExperiment`` defines the common patterns that every experiment should have. Importantly, it starts an independent process called publisher, that will be responsible for broadcasting messages that are appended to a queue. The messages rely on the pyZMQ library and should be tested further in order to @@ -18,7 +18,7 @@ .. TODO:: Check whether the serialization of objects with cPickle may be a bottleneck for performance. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ from multiprocessing import Process, Event @@ -34,7 +34,7 @@ class BaseExperiment: """ Base class to define experiments. Should keep track of the basic methods needed regardless of the experiment to be performed. For instance, a way to start and a way to finalize a measurement. """ - def __init__(self): + def __init__(self, filename=None): self.config = {} # Dictionary storing the configuration of the experiment self.logger = get_logger(name=__name__) self._threads = [] @@ -43,6 +43,8 @@ def __init__(self): self._connections = [] self.subscriber_events = [] + if filename: + self.load_configuration(filename) def stop_publisher(self): """ Puts the proper data to the queue in order to stop the running publisher process diff --git a/pynta/model/experiment/config.py b/pynta/model/experiment/config.py index 1806890..4071dde 100644 --- a/pynta/model/experiment/config.py +++ b/pynta/model/experiment/config.py @@ -1,14 +1,14 @@ # -*- coding: utf-8 -*- """ Experiment Configuration - =========================== + ======================== Class which holds some parameters that need to be used throughout the lifetime of a program. Keeping them in a separate class gives great flexibility, because it allows to overwrite values at run time. .. TODO:: Changes to config at runtime will have no effect on other processes. Find a way in which config can broadcast itself to all the instances of the class - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ from pynta.util import get_logger diff --git a/pynta/model/experiment/dispertech/__init__.py b/pynta/model/experiment/dispertech/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pynta/model/experiment/dispertech/database.py b/pynta/model/experiment/dispertech/database.py new file mode 100644 index 0000000..3ad7a47 --- /dev/null +++ b/pynta/model/experiment/dispertech/database.py @@ -0,0 +1,80 @@ +import sqlite3 +from pathlib import Path +from typing import Tuple + +import yaml + +from pynta.util import get_logger + +logger = get_logger(__name__) + + +def initialize_database() -> Tuple[sqlite3.Connection, sqlite3.Cursor]: + """ We are using a simple SQLite database to store some information regarding the use of the program. The most + important feature is being able to store the latest set parameters in such a way the they can be recovered when + restarting the program. If the database does not exist, it should be created. + """ + home = Path.home() + pynta_path = Path(home, '.pynta') + if not pynta_path.is_dir(): + try: + pynta_path.mkdir() + except PermissionError: + logger.error(f'This user does not have access to {pynta_path}. Consider another directory') + raise + + database_path = Path(pynta_path, 'config.sqlite') + if not database_path.is_file(): + logger.info('Going to create a new database') + conn = sqlite3.connect(str(database_path)) + cur = conn.cursor() + sql_command = """CREATE TABLE configs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + name VARCHAR, + description VARCHAR) + """ + cur.execute(sql_command) + sql_command = """CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP) + """ + cur.execute(sql_command) + sql_command = """CREATE TABLE samples ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR, + description TEXT + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP) + """ + cur.execute(sql_command) + sql_command = """CREATE TABLE experiments ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR, + user_id INTEGER NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(id)) + """ + cur.execute(sql_command) + sql_command = """INSERT INTO configs (name, description) + VALUES + ('Initial Database', 'Starting Fiber Tracking for the first time') + """ + cur.execute(sql_command) + conn.commit() + else: + logger.info('Database found') + conn = sqlite3.connect(str(database_path)) + cur = conn.cursor() + return conn, cur + + +def store_config(db: Tuple[sqlite3.Connection, sqlite3.Cursor], config: dict) -> None: + conn = db[0] + cur = db[1] + data = yaml.dump(config) + sql_command = f"""INSERT INTO configs (name, description) VALUES + ('Saved Config', '{data}') + """ + cur.execute(sql_command) + conn.commit() + diff --git a/pynta/model/experiment/dispertech/fiber_tracking.py b/pynta/model/experiment/dispertech/fiber_tracking.py new file mode 100644 index 0000000..6de1b8f --- /dev/null +++ b/pynta/model/experiment/dispertech/fiber_tracking.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +""" + Tracking in Hollow Optical Fibers + ================================= + + This experiment is very similar to the nanoparticle tracking experiment, but everything happens inside a hollow + optical fiber. Some steps are different; for example, the user first has to focus the image of the camera on the + top part of the setup in order to couple the laser to the optical fiber. Then, the user needs to maximise the + background signal on the microscope's camera in order to fine-tune the coupling. + + The measurement is essentially a 1-D measurement of diffusion, in which equations need to be adapted for including + diffusion in a cylinder. + + :copyright: Aquiles Carattino + :license: GPLv3, see LICENSE for more details +""" +import importlib +import sqlite3 +from pathlib import Path + +from pynta.model.experiment.base_experiment import BaseExperiment +from pynta.model.experiment.dispertech.util import load_camera_module, instantiate_camera +from pynta.util import get_logger + + +logger = get_logger(name=__name__) + + +class FiberTracking(BaseExperiment): + """ Experiment class for performing nanoparticle tracking analysis inside a hollow optical fiber. + """ + SINGLE_SNAP_BKG = 0 + """Uses only one image to correct the background""" + + ROLLING_AVERAGE = 1 + """Uses a window of averages to correct the background""" + + BACKGROUND_CORRECTION = ( + ('single_snap', SINGLE_SNAP_BKG), + ('rolling_avg', ROLLING_AVERAGE) + ) + + def __init__(self, filename=None): + super().__init__(filename) + self.cameras = { + 'fiber': None, + 'microscope': None + } + self.initialize_threads = [] + + def initialize_cameras(self): + """ The experiment requires two cameras, and they need to be initialized before we can proceed with the + measurement. This requires two entries in the config file with names ``camera_fiber``, which refers to the + camera which monitors the end of the fiber and ``camera_microscope``, which is the one that is used to do the + real measurement. + + """ + + self.cameras['fiber'] = instantiate_camera(config=self.config['camera_fiber']) + self.cameras['microscope'] = instantiate_camera(config=self.config['camera_microscope']) + + logger.info('Initializing the cameras...') + for k, camera in self.cameras.items(): + logger.info(f'Initializing {k} camera: {camera}') + camera.initialize() + + def initialize_mirror(self): + """ Routine to initialize the movable mirror. The steps in this method should be those needed for having the + mirror in a known position (i.e. the homing procedure). + """ + logger.info('Homing mirror') + + def initialize_electronics(self): + """ Routine to initialize the rest of the electronics. For example, the LED's can be set to a default on/off + state. This is also used to measure the temperature. + """ + logger.info('Initializing electronics') + + def initialize(self): + """ Initializes all the devices at the same time using threads. + """ + self.initialize_threads \ No newline at end of file diff --git a/pynta/model/experiment/dispertech/util.py b/pynta/model/experiment/dispertech/util.py new file mode 100644 index 0000000..c5d24bc --- /dev/null +++ b/pynta/model/experiment/dispertech/util.py @@ -0,0 +1,32 @@ +import importlib + +from pynta.util import get_logger + +logger = get_logger(name=__name__) + + +def load_camera_module(name): + try: + logger.info('Importing camera model {}'.format(name)) + logger.debug('pynta.model.cameras.' + name) + camera_model_to_import = 'pynta.model.cameras.' + name + cam_module = importlib.import_module(camera_model_to_import) + except ModuleNotFoundError: + logger.error('The model {} for the camera was not found'.format(name)) + raise + return cam_module + + +def instantiate_camera(config: dict): + cam_module = load_camera_module(config['model']) + cam_init_arguments = config['init'] + if 'extra_args' in config: + logger.info('Initializing camera with extra arguments') + logger.debug('cam_module.camera({}, {})'.format(cam_init_arguments, config['extra_args'])) + camera = cam_module.Camera(cam_init_arguments, *config['extra_args']) + else: + logger.info('Initializing camera without extra arguments') + logger.debug('cam_module.camera({})'.format(cam_init_arguments)) + camera = cam_module.Camera(cam_init_arguments) + + return camera diff --git a/pynta/model/experiment/nanoparticle_tracking/localization.py b/pynta/model/experiment/nanoparticle_tracking/localization.py index 97ffe4d..72d8293 100644 --- a/pynta/model/experiment/nanoparticle_tracking/localization.py +++ b/pynta/model/experiment/nanoparticle_tracking/localization.py @@ -15,7 +15,7 @@ :class:`~nanoparticle_tracking.model.experiment.subscriber.Subscriber` in order to listen for the new data, and in turn publishes it with the Publisher. -:copyright: Aquiles Carattino +:copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ from copy import copy diff --git a/pynta/model/experiment/nanoparticle_tracking/np_tracking.py b/pynta/model/experiment/nanoparticle_tracking/np_tracking.py index 9cee06f..7d37fed 100644 --- a/pynta/model/experiment/nanoparticle_tracking/np_tracking.py +++ b/pynta/model/experiment/nanoparticle_tracking/np_tracking.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ - nanoparticle_tracking.py - =========== + Nanoparticle Tracking + ===================== Nanoparticle tracking is a technique that allows to measure the size of very small objects. The core idea is that by locating objects subject to brownian motion, it is possible to reconstruct their movement, which in turn can be fitted to a model which depends on properties of the medium (i.e. viscosity) and on the diameter of the particles. @@ -11,7 +11,7 @@ at providing a superior approach, allowing researchers to have real-time information on the sample studied and a completely transparent approach regarding algorithms used. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ import sys @@ -48,13 +48,11 @@ class NPTracking(BaseExperiment): BACKGROUND_SINGLE_SNAP = 1 def __init__(self, filename=None): - super().__init__() + super().__init__(filename) self.free_run_running = False self.saving_location = False self.logger = get_logger(name=__name__) - self.load_configuration(filename) - self.dropped_frames = 0 self.keep_acquiring = True self.acquiring = False # Status of the acquisition @@ -125,7 +123,7 @@ def initialize_camera(self): self.camera = cam_module.Camera(cam_init_arguments) self.camera.initialize() - self.current_width, self.current_height = self.camera.getSize() + self.current_width, self.current_height = self.camera.get_size() self.logger.info('Camera sensor ROI: {}px X {}px'.format(self.current_width, self.current_height)) self.max_width = self.camera.GetCCDWidth() self.max_height = self.camera.GetCCDHeight() @@ -156,7 +154,7 @@ def set_roi(self, X, Y): """ self.logger.debug('Setting new camera ROI to x={},y={}'.format(X, Y)) - self.current_width, self.current_height = self.camera.setROI(X, Y) + self.current_width, self.current_height = self.camera.set_ROI(X, Y) self.logger.debug('New camera width: {}px, height: {}px'.format(self.current_width, self.current_height)) self.temp_image = None @@ -168,7 +166,7 @@ def clear_roi(self): self.logger.info('Clearing ROI settings') X = [0, self.max_width-1] Y = [0, self.max_height-1] - self.camera.setROI(X, Y) + self.camera.set_ROI(X, Y) @check_camera @check_not_acquiring diff --git a/pynta/model/experiment/nanoparticle_tracking/saver.py b/pynta/model/experiment/nanoparticle_tracking/saver.py index b9b7a6f..b07bf64 100644 --- a/pynta/model/experiment/nanoparticle_tracking/saver.py +++ b/pynta/model/experiment/nanoparticle_tracking/saver.py @@ -1,5 +1,5 @@ """ - nanoparticle_tracking.model.experiment.workerSaver + pynta.model.experiment.workerSaver ================================== When working with multi threading in Python it is important to define the function that will be run in a separate thread. workerSaver is just a function that will be moved to a separate, parallel thread to save data to disk @@ -25,7 +25,7 @@ :copyright: 2017 - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ import zmq import h5py diff --git a/pynta/model/experiment/nanoparticle_tracking/waterfall_worker.py b/pynta/model/experiment/nanoparticle_tracking/waterfall_worker.py index 32e43fa..78b9dff 100644 --- a/pynta/model/experiment/nanoparticle_tracking/waterfall_worker.py +++ b/pynta/model/experiment/nanoparticle_tracking/waterfall_worker.py @@ -10,4 +10,5 @@ def calculate_waterfall(in_queue, out_queue): :type out_queue: :return: :rtype: - """ \ No newline at end of file + """ + pass \ No newline at end of file diff --git a/pynta/model/experiment/publisher.py b/pynta/model/experiment/publisher.py index 12a412d..109c9ce 100644 --- a/pynta/model/experiment/publisher.py +++ b/pynta/model/experiment/publisher.py @@ -11,7 +11,7 @@ publisher and serialized again to be sent. These three steps could be simplify into one if, for example, one assumes that objects where pickled. There is also a possibility of assuming numpy arrays and using a zero-copy strategy. -:copyright: Aquiles Carattino +:copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ diff --git a/pynta/model/experiment/subscriber.py b/pynta/model/experiment/subscriber.py index 2c2ebfd..b7d4e9f 100644 --- a/pynta/model/experiment/subscriber.py +++ b/pynta/model/experiment/subscriber.py @@ -1,6 +1,6 @@ """ - subscriber.py - ============= + Subscriber + ========== Example script on how to run separate processes to process the data coming from a publisher like the one on ``publisher.py``. The first process just grabs the frame and puts it in a Queue. The Queue is then used by another process in order to analyse, process, save, etc. It has to be noted that on UNIX systems, getting diff --git a/pynta/tests/test_controllers.py b/pynta/tests/test_controllers.py index f5155cc..2dc7954 100644 --- a/pynta/tests/test_controllers.py +++ b/pynta/tests/test_controllers.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- -""" Test the available controllers for the proper structure. +""" +Test the available controllers for the proper structure. Since controllers are inherently impossible to test on all systems, the only reasonable thing to do is to check for consistency in methods. .. TODO:: Define the minimum structure that makes a controller .. TODO:: Implement tests to assert whether the controllers have the needed methods - :copyright: Aquiles Carattino - :license: AGPLv3, see LICENSE for more details +:copyright: Aquiles Carattino +:license: AGPLv3, see LICENSE for more details """ diff --git a/pynta/tests/test_examples.py b/pynta/tests/test_examples.py index 73b868f..0a65ae3 100644 --- a/pynta/tests/test_examples.py +++ b/pynta/tests/test_examples.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- -""" Check whether the examples are able to perform an experiment with dummy devices. +""" +Check whether the examples are able to perform an experiment with dummy devices. .. TODO:: Find a way of testing the UI, is it possible within Travis? may be useful to check what `PyQtGraph `_ is doing for the tests. - :copyright: Aquiles Carattino - :license: AGPLv3, see LICENSE for more details +:copyright: Aquiles Carattino +:license: AGPLv3, see LICENSE for more details """ \ No newline at end of file diff --git a/pynta/tests/test_models.py b/pynta/tests/test_models.py index 7756694..c106bc3 100644 --- a/pynta/tests/test_models.py +++ b/pynta/tests/test_models.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -""" Models can be checked for structure, but also models which depend on dummy devices can be tested +""" +Models can be checked for structure, but also models which depend on dummy devices can be tested thoroughly. .. TODO:: Define minimum structure for each kind of model .. TODO:: Define tests for dummy-based models. - :copyright: Aquiles Carattino - :license: AGPLv3, see LICENSE for more details. +:copyright: Aquiles Carattino +:license: AGPLv3, see LICENSE for more details. """ \ No newline at end of file diff --git a/pynta/tools/worker_thread.py b/pynta/tools/worker_thread.py index 4902600..d7258e5 100644 --- a/pynta/tools/worker_thread.py +++ b/pynta/tools/worker_thread.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ work_thread.py - =========== + ============== Running the acquisition on a separate thread gives a lot of flexibility when designing the program. It comes, however with some potential risks. First, threads are still running on the same Python interpreter. Therefore they do not overcome the GIL limitations. They are able to share memory, which makes them transparent to less experienced @@ -10,7 +10,7 @@ without user intervention for long periods of time. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: AGPLv3, see LICENSE for more details """ from threading import Thread diff --git a/pynta/util/log.py b/pynta/util/log.py index c7da5ff..b06a413 100644 --- a/pynta/util/log.py +++ b/pynta/util/log.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- """ nanoparticle_tracking.util.log.py - ================= + ================================= Adding log capacities to PyNTA - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: AGPLv3, see LICENSE for more details """ import logging diff --git a/pynta/view/GUI/__init__.py b/pynta/view/GUI/__init__.py index e69de29..5d16354 100644 --- a/pynta/view/GUI/__init__.py +++ b/pynta/view/GUI/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +""" + GUI + === + Developing a GUI for an application is a delicated task. On the one hand, developers want to deliver quick solutions. + On the other, users are exposed to programs developed over decades, by large teams, including designers. Therefore, + it is very hard for a single developer to obtain user interfaces as beautiful as the ones you can get from commercial + suppliers. + + However, it is possible to build a collection of tools that can be reused and that can generate a much more + consistent result throughout different applications. The approach PyNTA follows is to develop GUI's using Qt5. There + are different ports of Qt for Python, such as PySide and PyQt. For the time being, PyNTA is based on PyQt5, but this + can change without previous notice. + + To develop a Graphical User Interface (GUI), we have opted to use Qt Designer, and the files are loaded directly to + the class through ``uic.loadUi`` instead of compiling the files into a Python class. On the one hand, this + simplifies the cycle for updating the interface, on the other it does not make explicit which methods are available. + Compiling the files is up to the developer, but the *official* approach is to use only the UI files generated by + Qt Designer. + + .. TODO:: Different wrappers of Qt for Python expose the same API in different ways. We should explore using an + intermediate package to unify the use of Qt. + + :copyright: Aquiles Carattino + :license: GPLv3, see LICENSE for more details +""" \ No newline at end of file diff --git a/pynta/view/GUI/config_widget.py b/pynta/view/GUI/config_widget.py index d7ace15..abfb7f7 100644 --- a/pynta/view/GUI/config_widget.py +++ b/pynta/view/GUI/config_widget.py @@ -6,7 +6,7 @@ .. todo:: Remove the printing to screen of the parameters once the debugging is done. - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ import os diff --git a/pynta/view/GUI/old/Monitor/cameraViewer.py b/pynta/view/GUI/old/Monitor/cameraViewer.py index 9f9b185..d3ae89c 100644 --- a/pynta/view/GUI/old/Monitor/cameraViewer.py +++ b/pynta/view/GUI/old/Monitor/cameraViewer.py @@ -8,7 +8,7 @@ .. todo:: Unify the main viewer with this one. - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ import pyqtgraph as pg diff --git a/pynta/view/GUI/old/Monitor/clearQueueThread.py b/pynta/view/GUI/old/Monitor/clearQueueThread.py index 8d69be4..2a7369f 100644 --- a/pynta/view/GUI/old/Monitor/clearQueueThread.py +++ b/pynta/view/GUI/old/Monitor/clearQueueThread.py @@ -5,7 +5,7 @@ .. warning:: If this Thread is run while the save thread is running there will be data loss without warning. Moreover, of the clear queue destroys the last element of the Queue before the saver arrives to it, te saver will not stop. - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ from pyqtgraph.Qt import QtCore diff --git a/pynta/view/GUI/old/Monitor/crossCut.py b/pynta/view/GUI/old/Monitor/crossCut.py index 3c87312..9bec38c 100644 --- a/pynta/view/GUI/old/Monitor/crossCut.py +++ b/pynta/view/GUI/old/Monitor/crossCut.py @@ -3,7 +3,7 @@ =================================== Window that displays a 1D plot of a cross cut on the main window. - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ import pyqtgraph as pg diff --git a/pynta/view/GUI/old/mainwindow.py b/pynta/view/GUI/old/mainwindow.py index 30d7325..28da0f5 100644 --- a/pynta/view/GUI/old/mainwindow.py +++ b/pynta/view/GUI/old/mainwindow.py @@ -2,7 +2,7 @@ Main Window =========== - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ import os @@ -514,7 +514,7 @@ def startWaterfall(self): self.area.addDock(self.dwaterfall, 'bottom', self.dmainImage) self.dwaterfall.addWidget(self.watWidget) self.show_waterfall = True - Sx, Sy = self.camera.getSize() + Sx, Sy = self.camera.get_size() self.waterfall_data = np.zeros((self._session.GUI['length_waterfall'], Sx)) self.watWidget.img.setImage(np.transpose(self.waterfall_data), autoLevels=False, autoRange=False, autoHistogramRange=False) self.messageWidget.appendLog('i', 'Waterfall opened') @@ -557,8 +557,8 @@ def setROI(self, X, Y): self.messageWidget.appendLog('i', 'Updated roi_y1: %s' % int(Y[0])) self.messageWidget.appendLog('i', 'Updated roi_y2: %s' % int(Y[1])) - Nx, Ny = self.camera.setROI(X, Y) - Sx, Sy = self.camera.getSize() + Nx, Ny = self.camera.set_ROI(X, Y) + Sx, Sy = self.camera.get_size() self.current_width = Sx self.current_height = Sy @@ -796,7 +796,7 @@ def updateSession(self, session): print(self._session) if update_binning: - self.camera.setBinning(session.Camera['binning_x'],session.Camera['binning_y']) + self.camera.set_binning(session.Camera['binning_x'], session.Camera['binning_y']) self.refreshTimer.stop() self.refreshTimer.start(session.GUI['refresh_time']) diff --git a/pynta/view/GUI/old/messageWidget.py b/pynta/view/GUI/old/messageWidget.py index 3de650b..a56dcb0 100644 --- a/pynta/view/GUI/old/messageWidget.py +++ b/pynta/view/GUI/old/messageWidget.py @@ -15,7 +15,7 @@ .. todo:: Change colors for error, info and debug messages. - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ from datetime import datetime from pyqtgraph.Qt import QtGui diff --git a/pynta/view/GUI/old/trajectoryWidget.py b/pynta/view/GUI/old/trajectoryWidget.py index 7be1d61..d689067 100644 --- a/pynta/view/GUI/old/trajectoryWidget.py +++ b/pynta/view/GUI/old/trajectoryWidget.py @@ -5,7 +5,7 @@ .. todo:: adapt this widget for a useful case. - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ import pyqtgraph as pg diff --git a/pynta/view/GUI/old/waterfallWidget.py b/pynta/view/GUI/old/waterfallWidget.py index 107490d..5511ae6 100644 --- a/pynta/view/GUI/old/waterfallWidget.py +++ b/pynta/view/GUI/old/waterfallWidget.py @@ -7,7 +7,7 @@ .. todo:: Unify the 2D displaying of :mod:`camera Main ` and :mod:`camera Viewer `. - .. sectionauthor:: Aquiles Carattino + .. sectionauthor:: Aquiles Carattino """ import pyqtgraph as pg diff --git a/pynta/view/__init__.py b/pynta/view/__init__.py index e69de29..c9a4829 100644 --- a/pynta/view/__init__.py +++ b/pynta/view/__init__.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +""" + View + ==== + In the broad definition, the View should provide all the tools for the interaction between the user and the + computer. These could be both through the command line or through a Graphical User Interface. In practice, however, + command-line interfaces appear naturally once the models and controllers are properly developed. It is also possible + to use Jupyter notebooks to interface with devices and perform experiments. Therefore, the View will be fundamentally + responsible for generating graphical applications. + + :copyright: Aquiles Carattino + :license: GPLv3, see LICENSE for more details +""" \ No newline at end of file diff --git a/pynta/view/subscriber_thread.py b/pynta/view/subscriber_thread.py index 1a50866..bf9947c 100644 --- a/pynta/view/subscriber_thread.py +++ b/pynta/view/subscriber_thread.py @@ -5,7 +5,7 @@ Allows to transform topics coming from a socket (ZMQ) to Qt signals that can be connected to any method, etc. - :copyright: Aquiles Carattino + :copyright: Aquiles Carattino :license: GPLv3, see LICENSE for more details """ import numpy as np diff --git a/setup.py b/setup.py index 6b796a5..165cac6 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ url='https://github.com/nanoepics/pynta', license='GPLv3', author='Aquiles Carattino', - author_email='aquiles@aquicarattino.com', + author_email='aquiles@uetke.com', classifiers=[ 'Intended Audience :: End Users/Desktop', 'Operating System :: Microsoft :: Windows',