Skip to content

Commit

Permalink
Merge pull request #46 from hephy-dd/devel-0.9.x
Browse files Browse the repository at this point in the history
0.9.0
  • Loading branch information
arnobaer authored Apr 2, 2024
2 parents 4248f4b + 1b51e46 commit c1bc98b
Show file tree
Hide file tree
Showing 76 changed files with 161 additions and 32 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ['3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand Down Expand Up @@ -40,16 +40,15 @@ jobs:
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 src --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
flake8 src --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Lint with pylint
run: |
pylint -E sqc
pylint -E src
- name: Test with pytest
run: |
pytest
- name: Run application
run: |
python -m sqc --version
4 changes: 2 additions & 2 deletions .github/workflows/windows-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.10
- name: Set up Python 3.11
uses: actions/setup-python@v2
with:
python-version: 3.10
python-version: 3.11
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,16 @@ sqc --browser /home/jdoe/sqc

## Run Emulators

Run comet socket instrument emulators specified in `emulators.yaml` file.
For development and testing run [comet](https://github.com/hephy-dd/comet) instrument emulator sockets specified in `emulators.yaml` file.

```bash
python -m comet.emulators -f emulators.yaml
python -m comet.emulator -f emulators.yaml
```

## Binaries

See for pre-built Windows binaries in the [releases](https://github.com/hephy-dd/sqc/releases) section.

## License

SQC is licensed under the [GNU General Public License Version 3](LICENSE).
30 changes: 28 additions & 2 deletions changelog
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.9.0] - 2024-04-02

### Added
- Bad strips selection dialog (#26).
- Switching scheme figure to documentation.

### Changed
- Migration to comet-1.0.0.
- Using src-layout as project layout.

## [0.8.1] - 2024-02-29

### Fixed
- Measurement fails when in compliance (#44).

## [0.8.0] - 2024-01-24

### Added
- Manual control of flashing light and _Keep light flashing_ option in optical scan (#40).
- Added action _Github_ in help menu to open the Github page (#41).
Expand All @@ -25,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Flipped padfile and sequence inputs in sensor profile dialog.

## [0.7.1] - 2023-10-05

### Added
- Show sensor information for JSON files in data browser (#35).
- Toggle gradual Z approach for contacting pads (#38).
Expand All @@ -34,11 +46,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updating table position in Alignment Dialog (#37).

## [0.7.0] - 2023-10-04

### Added
- Profiles for acceleration/velocity for table movements (#33).
- Preferences dialog.

## [0.6.0] - 2023-10-02

### Added
- Auto uncheck measurements on success (#29).
- Button to move to scan position in inspection dialog (#30).
Expand All @@ -48,11 +62,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Issues with microscope inspection (#19).

## [0.5.0] - 2023-09-25

### Added
- Microscope inspection of sensors (#19).
- Reset alignment when changing sensor profiles (#27).

## [0.4.0] - 2023-09-18

### Added
- Support for PyInstaller (#18).
- Support for Python 3.11.
Expand All @@ -64,13 +80,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support for Python 3.7.

## [0.3.1] - 2023-01-09

### Added
- Improve table movements over distances (#14).

### Removed
- Dump TANGO diagnostics.

## [0.3.0] - 2023-01-09

### Added
- Display AC needles position.
- Calibration routines for table and needles (#12).
Expand All @@ -80,37 +98,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Using comet driver for Tango controller.

## [0.2.1] - 2022-12-12

### Fixed
- Verify needle position (#12).
- Migrated to comet-1.0.dev1.

## [0.2.0] - 2022-10-27

### Added
- Wait until required humidity reached (#10).

## [0.1.4] - 2022-09-27

### Fixed
- Missing assets when installed using pip (#8).

## [0.1.3] - 2022-09-27

### Fixed
- Measurement timestamp issue (#5).
- Table position validation issue (#6).

## [0.1.2] - 2022-09-23

### Changed
- Migrated to comet-1.0.dev0.

## [0.1.1] - 2022-09-20

### Added
- Prevent measurement if environment out of bounds (#1).
- Set test-running in environment box (#2).

## [0.1.0] - 2022-09-01

### Added
- Documentation of measurement configuration parameters.

[Unreleased]: https://github.com/hephy-dd/sqc/compare/0.8.1...HEAD
[Unreleased]: https://github.com/hephy-dd/sqc/compare/0.9.0...HEAD
[0.9.0]: https://github.com/hephy-dd/sqc/compare/0.8.1...0.9.0
[0.8.1]: https://github.com/hephy-dd/sqc/compare/0.8.0...0.8.1
[0.8.0]: https://github.com/hephy-dd/sqc/compare/0.7.1...0.8.0
[0.7.1]: https://github.com/hephy-dd/sqc/compare/0.7.0...0.7.1
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ nav:
markdown_extensions:
- smarty
extra:
version: 0.3.1
version: 0.9.0
theme:
name: readthedocs
locale: en
2 changes: 1 addition & 1 deletion pyinstaller/windows_app.spec
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ create_versionfile(
company_name="HEPHY",
file_description="Sensor Quality Control for the CMS Tracker",
internal_name="SQC",
legal_copyright="Copyright © 2022-2023 HEPHY. All rights reserved.",
legal_copyright="Copyright © 2022-2024 HEPHY. All rights reserved.",
original_filename=filename,
product_name="SQC",
)
Expand Down
13 changes: 5 additions & 8 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@ long_description_content_type = text/markdown
license = GPLv3

[options]
python_requires = >=3.8
packages = find:
python_requires = >=3.9
install_requires =
comet @ git+https://github.com/hephy-dd/comet.git@1.0.dev5
PyQt5==5.15.9
comet @ git+https://github.com/hephy-dd/comet.git@v1.0.0
PyQt5==5.15.10
PyQtChart==5.15.6
PyYAML==6.0.1
numpy==1.21.6; python_version < '3.11'
numpy==1.26.0; python_version >= '3.11'
scipy==1.7.3; python_version < '3.11'
scipy==1.11.2; python_version >= '3.11'
numpy==1.26.4
scipy==1.12.0
schema==0.7.5
pyueye==4.95.0
test_suite = tests
Expand Down
1 change: 0 additions & 1 deletion sqc/__init__.py

This file was deleted.

1 change: 1 addition & 0 deletions src/sqc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "0.9.0"
4 changes: 2 additions & 2 deletions sqc/__main__.py → src/sqc/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from .context import Context
from .station import Station

from .view.mainwindow import MainWindow
from .view.databrowser import DataBrowserWindow
from .gui.mainwindow import MainWindow
from .gui.databrowser import DataBrowserWindow

from .plugins import Plugin
from .plugins.json_writer import JSONWriterPlugin
Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
84 changes: 84 additions & 0 deletions src/sqc/gui/badstrips.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from typing import Dict, Optional

from PyQt5 import QtCore, QtWidgets


class BadStripSelectDialog(QtWidgets.QDialog):

def __init__(self, parent: Optional[QtWidgets.QWidget]) -> None:
super().__init__(parent)

self.setObjectName("BadStripSelectDialog")
self.setWindowTitle("Select Bad Strips")

self.statistics = None

self.remeasureCountSpinBox = QtWidgets.QSpinBox(self)
self.remeasureCountSpinBox.setRange(1, 99)
self.remeasureCountSpinBox.valueChanged.connect(self.updatePreview)

self.previewTreeWidget = QtWidgets.QTreeWidget(self)
self.previewTreeWidget.setHeaderLabels(["Strip", "Count"])
self.previewTreeWidget.setRootIsDecorated(False)

self.buttonBox = QtWidgets.QDialogButtonBox(self)
self.buttonBox.addButton(QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.addButton(QtWidgets.QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)

layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(QtWidgets.QLabel("Minimal Re-Measure Count"))
layout.addWidget(self.remeasureCountSpinBox)
layout.addWidget(QtWidgets.QLabel("Preview"))
layout.addWidget(self.previewTreeWidget)
layout.addWidget(self.buttonBox)

def readSettings(self) -> None:
settings = QtCore.QSettings()
settings.beginGroup(self.objectName())
geometry = settings.value("geometry", QtCore.QByteArray(), QtCore.QByteArray)
remeasureCount = settings.value("remeasureCount", 1, int)
settings.endGroup()
self.restoreGeometry(geometry)
self.setRemeasureCount(remeasureCount)

def writeSettings(self) -> None:
settings = QtCore.QSettings()
settings.beginGroup(self.objectName())
settings.setValue("geometry", self.saveGeometry())
settings.setValue("remeasureCount", self.remeasureCount())
settings.endGroup()

def setRemeasureCount(self, count: int) -> None:
self.remeasureCountSpinBox.setValue(count)

def remeasureCount(self) -> int:
return self.remeasureCountSpinBox.value()

def setStatistics(self, statistics) -> None:
self.statistics = statistics
self.updatePreview()

def selectedStrips(self) -> str:
threshold = self.remeasureCount()
strips = self.filterStrips(threshold).keys()
return ", ".join([format(strip) for strip in strips])

def updatePreview(self) -> None:
threshold = self.remeasureCount()
self.previewTreeWidget.clear()
root = self.previewTreeWidget.invisibleRootItem()
for strip, count in self.filterStrips(threshold).items():
item = QtWidgets.QTreeWidgetItem([str(strip), str(count)])
root.addChild(item)

def filterStrips(self, threshold: int) -> Dict[str, int]:
strips: Dict[str, int] = {}
if self.statistics is not None:
for strip, counter in self.statistics.remeasure_counter.items():
values = counter.values()
max_value = max(values or [0])
if max_value >= threshold:
strips[strip] = max_value
return strips
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion sqc/view/dashboard.py → src/sqc/gui/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def __init__(self, context, parent: Optional[QtWidgets.QWidget] = None) -> None:

self.sequenceLabel = QtWidgets.QLabel("Sequence")

self.sequenceWidget = SequenceWidget(self)
self.sequenceWidget = SequenceWidget(self.context, self)
self.sequenceWidget.currentItemChanged.connect(self.loadSequenceItemParameters)

# Parameters
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
21 changes: 18 additions & 3 deletions sqc/view/sequence.py → src/sqc/gui/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from ..core.utils import parse_strip_expression, normalize_strip_expression
from ..strategy import SequenceStrategy

from .badstrips import BadStripSelectDialog

__all__ = [
"SequenceItem",
"SequenceWidget",
Expand Down Expand Up @@ -223,8 +225,9 @@ def allChildren(self) -> list:

class SequenceWidget(QtWidgets.QTreeWidget):

def __init__(self, parent=None):
def __init__(self, context, parent: Optional[QtWidgets.QWidget] = None) -> None:
super().__init__(parent)
self.context = context
self.setLocked(False)
headerItem = QtWidgets.QTreeWidgetItem()
headerItem.setText(SequenceItem.NameColumn, "Measurement")
Expand Down Expand Up @@ -307,6 +310,10 @@ def contextMenuEvent(self, event):
restoreStripsAction.setEnabled(False)
restoreStripsAction.setToolTip("Restore default strips from config for selected measurement")

selectBadStripsAction = menu.addAction("Select Bad Strips")
selectBadStripsAction.setEnabled(False)
selectBadStripsAction.setToolTip("Select bad strips that failed in measurements")

menu.addSeparator()

restoreIntervalsAction = menu.addAction("Default Intervals")
Expand All @@ -319,16 +326,24 @@ def contextMenuEvent(self, event):

if item.allChildren():
restoreIntervalsAction.setEnabled(True)
selectBadStripsAction.setEnabled(True)
restoreStripsAction.setEnabled(True)
resetIntervalsAction.setEnabled(True)

res = menu.exec(event.globalPos())
if res == restoreStripsAction:
item.setStrips(item.defaultStrips())
if res == resetIntervalsAction:
elif res == selectBadStripsAction:
dialog = BadStripSelectDialog(self)
dialog.setStatistics(self.context.statistics)
dialog.readSettings()
if dialog.exec() == dialog.Accepted:
item.setStrips(dialog.selectedStrips())
dialog.writeSettings()
elif res == resetIntervalsAction:
for child in item.allChildren():
child.setInterval(1)
if res == restoreIntervalsAction:
elif res == restoreIntervalsAction:
for child in item.allChildren():
child.setInterval(child.defaultInterval())

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit c1bc98b

Please sign in to comment.