Skip to content

Commit

Permalink
release 0.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
cgevans committed Dec 3, 2021
1 parent 5d36d1d commit da90735
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 36 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

## Version 0.4.0

- Much faster `Experiment.sync_from_machine`, only transferring additional log entries rather than the entire log.
- Much faster `Experiment.sync_from_machine`, only transferring additional log
entries rather than the entire log.
- Common plotting routines for fluorescence data.
- More reliable monitoring.
- More reliable connections, and testing.
- `Stage.stepped_ramp` convenience function.
- Fixes to bugs inhibiting exposure setting, and some basic
implementations for this.
- Fixes to qs-monitor for cycle counts > 999 (and other large stage / step / cycle counts).
- Fixes to qs-monitor for cycle counts > 999 (and other large stage / step /
cycle counts).

## Version 0.3.1

Expand Down
14 changes: 4 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
Status](https://img.shields.io/github/workflow/status/cgevans/qslib/Python%20tests)
![PyPI](https://img.shields.io/pypi/v/qslib)


# qslib

QSLib is a package for interacting with Applied Biosystems' QuantStudio
Expand All @@ -15,16 +14,15 @@ machines through their network connection and SCPI interface. It currently
functions only with QuantStudio 5 machines using a 96-well block, but
could be made to support others as well.

Amongst other features that :
Amongst other features that it has:

- Direct fluorescence data ("filter data") as Pandas dataframes, with
times and temperature readings.

- Running-experiment data access, status information, and control.

- Protocol creation and manipulation, allowing functions outside of
AB's software. The ability to update protocols and add stages
mid-run is feasible and planned.
AB's software. Protocols can be modified and updated mid-run.

- Temperature data at one-second resolution during experiments.

Expand All @@ -48,7 +46,6 @@ It requires at least version 3.9 of Python. While it uses async code at
its core for communication, it can be used conveniently in Jupyter or
IPython.


To use the library for communication with machines, you'll need a
machine access password with Observer (for reading data and statuses)
and/or Controller (for running experiments and controlling the machine)
Expand All @@ -57,7 +54,6 @@ recommend against having the machines be accessible online: use a
restricted VPN connection or port forwarding. See the documentation for
more information.


## Disclaimer

This package was developed for my own use. It may break your machine or
Expand All @@ -67,7 +63,5 @@ render your machine unusable or be used to send commands that would
physically/electrically damage the machine or potentially be hazardous
to you or others.

I am in no way connected with Applied Biosystems, and have developed
this package using the machine's documentation system and standard file
formats.

I am not any way connected with Applied Biosystems. I have developed this
package using the machine's documentation system and standard file formats.
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@
"sphinx.ext.ifconfig",
"sphinx.ext.mathjax",
"sphinx.ext.napoleon",
"myst_parser"
"myst_parser",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

#extensions.append("recommonmark")
# extensions.append("recommonmark")

# The suffix of source filenames.
source_suffix = [".rst", ".md"]
Expand Down
2 changes: 1 addition & 1 deletion tests/test_accesslevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ def test_access():
AccessLevel(l1) <= invalid # type: ignore
with pytest.raises(ValueError):
AccessLevel(l1) == invalid # type: ignore
assert str(AccessLevel(l1)) == l1
assert str(AccessLevel(l1)) == l1
43 changes: 30 additions & 13 deletions tests/test_experiment_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,42 @@ def patchrun(self, value: str) -> str:
else:
raise ValueError

monkeypatch.setattr(Machine, 'run_command', patchrun)
m = Machine('none')
monkeypatch.setattr(Machine, "run_command", patchrun)

m = Machine("none")

m.drawer_close()

@pytest.mark.parametrize("function", [("drawer_position", ()),
("machine_status", ()),
("run_status", ()),
("get_running_protocol", ()),
("list_runs_in_storage", ())])


@pytest.mark.parametrize(
"function",
[
("drawer_position", ()),
("machine_status", ()),
("run_status", ()),
("get_running_protocol", ()),
("list_runs_in_storage", ()),
],
)
def test_mach_not_connected(function: tuple[str, tuple[Any]]) -> None:
m = Machine('none')
m = Machine("none")
with pytest.raises(ConnectionError):
getattr(m, function[0]).__call__(*function[1])


@pytest.mark.parametrize("function", [("from_running", (Machine('none'),)),
("from_machine_storage", (Machine('none'), "filename",))])
@pytest.mark.parametrize(
"function",
[
("from_running", (Machine("none"),)),
(
"from_machine_storage",
(
Machine("none"),
"filename",
),
),
],
)
def test_expload_not_connected(function: str) -> None:
with pytest.raises(ConnectionError):
getattr(Experiment, function[0]).__call__(*function[1])
19 changes: 11 additions & 8 deletions tests/test_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def test_proto() -> None:

assert prot_explicitfilter == prot_fromstring


def test_exp_saveload_proto(tmp_path: pathlib.Path):
temperatures = list(np.linspace(51.2, 49.4, num=6))
prot = Protocol(
Expand Down Expand Up @@ -168,26 +169,28 @@ def test_exp_saveload_proto(tmp_path: pathlib.Path):
# FIXME: for now, we don't do a great job with save/load for default filters
assert exp.protocol.to_command() == exp2.protocol.to_command()


def test_stepped_ramp_down():
srstage = Stage.stepped_ramp(60.0, 40.0, 60*21, 21)
srstage = Stage.stepped_ramp(60.0, 40.0, 60 * 21, 21)

df = srstage.dataframe()

assert len(df) == 21
assert df.iloc[-1, :]['temperature_1'] == 40.0
assert df.iloc[0, :]['temperature_1'] == 60.0
assert df.iloc[1, :]['temperature_1'] == 59.0
assert df.iloc[-1, :]["temperature_1"] == 40.0
assert df.iloc[0, :]["temperature_1"] == 60.0
assert df.iloc[1, :]["temperature_1"] == 59.0

assert srstage == Stage(Step(60, 60.0, temp_increment=-1.0), 21)


def test_stepped_ramp_up():
srstage = Stage.stepped_ramp(40.0, 60.0, 60*41, 41)
srstage = Stage.stepped_ramp(40.0, 60.0, 60 * 41, 41)

df = srstage.dataframe()

assert len(df) == 41
assert df.iloc[-1, :]['temperature_1'] == 60.0
assert df.iloc[0, :]['temperature_1'] == 40.0
assert df.iloc[1, :]['temperature_1'] == 40.5
assert df.iloc[-1, :]["temperature_1"] == 60.0
assert df.iloc[0, :]["temperature_1"] == 40.0
assert df.iloc[1, :]["temperature_1"] == 40.5

assert srstage == Stage(Step(60, 40.0, temp_increment=0.5), 41)

0 comments on commit da90735

Please sign in to comment.