Skip to content

Releases: jdranczewski/puzzlepiece

v0.11.0

24 Oct 14:05
73aa148
Compare
Choose a tag to compare

Added a tutorial! Check it out at https://puzzlepiece.readthedocs.io/en/stable/tutorial.html

New features:

  • Puzzles can be indexed in additional ways as a shortcut - you can now directly say puzzle["piece:param"] to get a param. This also autocompletes in IPython.
  • Child params and actions - use Popup.make_child_params to easily create settings popups that modify hidden params.
  • replace_piece - an experimental method to update a Piece in place.
  • done_signal for the LiveWorker emitted when it finishes.
  • new extra module: ipython_shims adds two convenient magics: %%pzp_script and %%safe_run
  • Improvements to DataGrids, including support for custom Rows in add_row and Popups for the Rows.
  • Ability to set a Popup's title.

Fixes:

  • call_stop stops threads too.
  • reduced reliance on Qt spreadsheets - param changes should always indicate correctly with a red background now.

v0.10.0 - DataGrids, sliders, shortcuts, fixes

09 Apr 11:38
dcc520f
Compare
Choose a tag to compare

New shortcuts:

  • The QApp and Puzzle name arguments are no longer required when creating a Puzzle. The QApp still needs to be created in non-IPython contexts, but it can now be inferred by the Piece.
  • You can directly accesss a Piece's params by indexing it like a dictionary:
puzzle["piece"]["param_name"]
# is now equivalent to
puzzle["piece"].params["param_name"]

New features:

  • A slider parameter type - displays a slider and a value label. Min and max values, as well as the step size, are defined on creation.
  • First extra submodule - DataGrids allow for storing and interacting with data using the param abstractions in a table format. Can be added to a Piece's custom_layout to enable new data manipulation tasks.

Fixes and enhancements:

  • add_piece now returns the Piece instance (useful if a class is being passed for instantiation)
  • v_step argument when creating spinboxes changes the step of the box's buttons.
  • Popups now close when the Puzzle is closed.
  • Default param values are cast to the right type on creation.
  • IPython exception handler is now inserted correctly even if puzzle.process_events() is called in the cell that creates the Puzzle.
  • Pieces can now be instantiated without a parent Puzzle. This allows for using the Piece as a standalone Widget in an environment where only one Piece is needed, or a Puzzle cannot be set up, but is in general not advised.
  • Option to hide the bottom buttons of a Puzzle (Tree, Export, STOP)
  • All code has been re-formatted using ruff.

v0.9.0 - Popups, progress bars, IPython exceptions, fixes

31 Jan 15:02
90a3e27
Compare
Choose a tag to compare

Popups are now available as a convenient way to create a modal window attached to the main Puzzle. Can be used for calibration processes, further settings, or just in general GUI that you don't want cluttering a Piece. See https://puzzlepiece.readthedocs.io/en/latest/puzzlepiece.piece.html#puzzlepiece.piece.Popup for details.

Progress bar params give you a standard way to indicate progress, with tqdm-like iterable wrapping capability:

for i in piece.params['progress'].iter(range(10)):
    print(i)
    # this will automatically update the progress bar as the iteration goes on
    puzzle.process_events() # you may need to refresh the Puzzle to display changes

Exceptions that arise when running in IPython and interacting with the GUI will now display an error dialog just like when running in non-interactive Python. Exceptions that arise during cell execution will still produce a traceback in the Notebook, as before.

Small fixes: all threads now stop when an exception is raised, and a getter result will be cast to the param's type if obtained during a set_value call (that is if the setter doesn't return a value and a getter is present).

See pull request #2 for full changes

set_value and set_partial updates

13 Dec 10:50
Compare
Choose a tag to compare

set_value() now returns the new value, as it may be different than the one being set if the setter returns a value or a getter is defined.

ParamArray has a new property set_partial which allows you to set values to slices of the stored numpy array. This calls the setter of the param.

puzzle['piece'].params['image'].set_partial[100:200, :] = 128

Convenient shortcuts

30 Nov 21:21
Compare
Choose a tag to compare

You can now access the QApplication class as puzzlepiece.QApp, and pass Piece classes to add_piece instead of instantiating them first - this will reduce the clutter when building applications, and bring the minimum viable app to this neater form:

import puzzlepiece as pzp
from puzzlepiece.pieces import random_number

app = pzp.QApp([])
puzzle = pzp.Puzzle(app, "Basic example")
puzzle.add_piece("random", random_number.Piece, 0, 0)
puzzle.show()
app.exec()

Ensurers - capture_exception

28 Nov 15:50
Compare
Choose a tag to compare

Small amendment to v0.6.0: ensurers can now capture the exception when called directly, so they can be used in if statements easily.

# This will not raise an Exception is the check fails
if self._ensure_connected(capture_exception=True):
    print("laser is connected!")

Original v0.6.0 changelog follows:


An ensurer is a decorator that can be placed on getters, setters, and actions, and it will run ahead of these functions. The intended behaviour is performing checks ahead of running the function - for example checking if a laser is connected ahead of trying to set its power. This way one ensurer can be written and used in multiple places easily.

See https://puzzlepiece.readthedocs.io/en/latest/puzzlepiece.piece.html#puzzlepiece.piece.ensurer for examples

Ensurers

28 Nov 15:26
Compare
Choose a tag to compare

An ensurer is a decorator that can be placed on getters, setters, and actions, and it will run ahead of these functions. The intended behaviour is performing checks ahead of running the function - for example checking if a laser is connected ahead of trying to set its power. This way one ensurer can be written and used in multiple places easily.

See https://puzzlepiece.readthedocs.io/en/latest/puzzlepiece.piece.html#puzzlepiece.piece.ensurer for examples

Globals - variable management

28 Nov 13:04
Compare
Choose a tag to compare

It's now easier for multiple Pieces to share a device SDK with each other - they can put a hold on it in puzzle.globals and release it when done, only setting up and closing the SDK once for all Pieces.

See https://puzzlepiece.readthedocs.io/en/latest/puzzlepiece.puzzle.html#puzzlepiece.puzzle.Globals for examples

Array and Dropdown params

27 Nov 12:42
Compare
Choose a tag to compare

Array params let you properly communicate more complex data, like images or spectra, through the unified puzzlepiece API. They use numpy arrays as the data format.

Dropdown params can be populated with default values at startup and make it much easier to select device serial numbers.

The setup method of a Piece is now called ahead of param definition, so that dropdown params can use a device SDK to search for available devices.

Revamp params

22 Nov 17:38
Compare
Choose a tag to compare

The previous design of how params handled being set programmatically and from input fields mostly worked, but was rather convoluted, and limited the precision of the stored value to the display precision, which is very silly.

The back-end way params work and the associated signalling has thus been reworked, and new tests were introduced to test for correctness of the new behaviour.

See af35244 for the exact changes, but most of the behaviour should be unchanged. Most notably:

  • params no longer have limited precision, should go as precise as float allows
  • the changed Signal is now emitted every time set_value is called, even if the value didn't necessarily change
  • if implementing custom params, _input_set_value should block any Signals emitted by changing the input using this method. This can be achieved using self.input.blockSignals(True) and self.input.blockSignals(False)