Skip to content

Commit

Permalink
Merge pull request #18 from djdt/laser_sync
Browse files Browse the repository at this point in the history
ESL laser log importer
  • Loading branch information
djdt authored Jul 18, 2024
2 parents ba65a1d + 32f7662 commit 8f18c07
Show file tree
Hide file tree
Showing 19 changed files with 6,802 additions and 5,439 deletions.
67 changes: 54 additions & 13 deletions docs/dialogs/import.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,47 @@ Parameters from :ref:`laser_parameters` will be automatically read from imports
| Scantime | s | Acquistion time for each pixel; Total dwell time for all elements. |
+----------+-------+--------------------------------------------------------------------+


LaserLog Import Wizard
-----------------------
.. index:: LaserLog Import Wizard

* **File -> Import -> ESL Laser Log Wizard**
* **Drag-and-Drop -> Log and laser data files**

This wizard guides you through importing ICP-MS data and aligning it with a ESL laser ablation log file.
ICP-MS data should be collected as one line/sample or one file per laser pattern, multiple batches can be imported per log.

.. note::
To use this import make sure to activate the **save Iolite log file** option on the ActiveView2 home page, *before ablating*.

On the first page open or drag-and-drop the laser log file, this is usually named in the format 'LaserLog_YY-mm-dd_HH-MM-SS.csv'.

The next two pages import laser data and instructions in `Import Wizard` should be followed.
Only data formats that save the event times are supported (Agilent batches, Perkin-Elmer 'XL' and Thermo iCap CSV).

.. warning::
Currently only Agilent data has been tested with the importer.

.. figure:: ../images/dialog_nwi_import.png
:width: 480px
:align: center
:name: nwi_laser_group

The ESL Import groups page. Here both pattern per sample and pattern per file data has been selected for import.

The groups page shows all imported patterns and data files.
Drag the laser files to match with their corresponding laser log patterns.

Checking the *Split data into rows* can be used if data has been collected as one line/sample per pattern.
This will add a *row X* parameter to each laser line, as in :ref:`nwi_laser_group`.

Imported data is previewed on the next page, and the back button can be used to make changes to pattern-laser groupings.
A *Delay* control is provided for instrument setups with a long transport time (time taken for ablations to reach the ICP-MS).
Laser images are imported with their real world positions and parameters and a final control,
*Remove space between images*, can be used to collapse any empty space between images and make the scene more compact.


Spot-wise Import Wizard
-----------------------
.. index:: Spot-wise Import Wizard
Expand Down Expand Up @@ -176,16 +217,16 @@ The `Difference` output will show the difference in the shape to the current pea
Rastered collections should enabled the alternating raster option.
Once the image is correct the spotsize can be entered on the following page.

Kriss-Kross Import Wizard
-------------------------
.. index:: Kriss-Kross Import Wizard

* **File -> Import -> Kriss-Kross Import Wizard**

Import of Kriss-Kross_ collected Super-Resolution-Reconstruction images is performed
using the `Kriss-Kross Import Wizard`. This will guide users through import of the data
in a simliar manner to the :ref:`Import Wizard`.

.. seealso::
:ref:`Example: Importing file-per-line data`.
Example showing how to use the import wizard.
.. Kriss-Kross Import Wizard
.. -------------------------
.. .. index:: Kriss-Kross Import Wizard
..
.. * **File -> Import -> Kriss-Kross Import Wizard**
..
.. Import of Kriss-Kross_ collected Super-Resolution-Reconstruction images is performed
.. using the `Kriss-Kross Import Wizard`. This will guide users through import of the data
.. in a simliar manner to the :ref:`Import Wizard`.
..
.. .. seealso::
.. :ref:`Example: Importing file-per-line data`.
.. Example showing how to use the import wizard.
Binary file added docs/images/dialog_nwi_import.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 28 additions & 17 deletions pewpew/graphics/lasergraphicsview.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import numpy as np
from pewlib.process.register import fft_register_offset
from PySide6 import QtCore, QtGui, QtWidgets
Expand All @@ -24,14 +23,22 @@
)


class IgnoreRightButtonScene(QtWidgets.QGraphicsScene):
def mousePressEvent(self, event: QtGui.QMouseEvent):
if event.button() == QtCore.Qt.MouseButton.RightButton:
event.accept()
else:
super().mousePressEvent(event)


class LaserGraphicsView(OverlayGraphicsView):
"""The pewpew laser view."""

def __init__(
self, options: GraphicsOptions, parent: QtWidgets.QWidget | None = None
):
super().__init__(
QtWidgets.QGraphicsScene(QtCore.QRectF(-1e5, -1e5, 2e5, 2e5), parent),
IgnoreRightButtonScene(QtCore.QRectF(-1e5, -1e5, 2e5, 2e5), parent),
parent,
)
self.setDragMode(QtWidgets.QGraphicsView.DragMode.RubberBandDrag)
Expand All @@ -51,15 +58,6 @@ def __init__(
self.options.visiblityOptionsChanged.connect(self.updateOverlayVisibility)
self.viewScaleChanged.connect(self.scalebar.requestPaint)

# self.shown = False

# def showEvent(self, event: QtGui.QShowEvent) -> None:
# super().showEvent(event)
# if not self.shown:
# print('shown')
# self.zoomReset()
# self.shown = True

def laserItems(self) -> list[LaserImageItem]:
return [
item
Expand All @@ -69,8 +67,18 @@ def laserItems(self) -> list[LaserImageItem]:
if isinstance(item, LaserImageItem)
]

def selectedLaserItems(self) -> list[LaserImageItem]:
return [
item
for item in self.scene().selectedItems()
if isinstance(item, LaserImageItem)
]

def alignLaserItemsFFT(self) -> None:
items = self.laserItems()
items = self.selectedLaserItems()
if len(items) == 0:
items = self.laserItems()

base = items[0]
for item in items[1:]:
offset = fft_register_offset(base.rawData(), item.rawData())
Expand All @@ -79,25 +87,28 @@ def alignLaserItemsFFT(self) -> None:
base.pos()
+ QtCore.QPointF(offset[1] * psize.width(), offset[0] * psize.height())
)
self.zoomReset()

def alignLaserItemsLeftToRight(self) -> None:
items = self.laserItems()
items = self.selectedLaserItems()
if len(items) == 0:
items = self.laserItems()

base = items[0]
pos = base.pos() + QtCore.QPointF(base.boundingRect().width(), 0.0)
for item in items[1:]:
item.setPos(pos)
pos.setX(pos.x() + item.boundingRect().width())
self.zoomReset()

def alignLaserItemsTopToBottom(self) -> None:
items = self.laserItems()
items = self.selectedLaserItems()
if len(items) == 0:
items = self.laserItems()

base = items[0]
pos = base.pos() + QtCore.QPointF(0.0, base.boundingRect().height())
for item in items[1:]:
item.setPos(pos)
pos.setY(pos.y() + item.boundingRect().height())
self.zoomReset()

def focusOutEvent(self, event: QtGui.QFocusEvent) -> None:
self.clearFocus()
Expand Down
1 change: 0 additions & 1 deletion pewpew/graphics/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ class GraphicsOptions(QtCore.QObject):
"""This object stores information used by pewpew to draw images.
Parameters:
items: dict of item visibilities
colortable: colortable to draw with, see colortables
colorrange_default: default colorrange to use
smoothing: whether to smooth images
Expand Down
55 changes: 53 additions & 2 deletions pewpew/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from types import TracebackType

from pewlib.config import Config, SpotConfig
from pewlib.io.laser import is_nwi_laser_log
from PySide6 import QtCore, QtGui, QtWidgets

from pewpew.actions import qAction, qActionGroup
Expand All @@ -12,7 +13,7 @@
from pewpew.widgets import dialogs
from pewpew.widgets.exportdialogs import ExportAllDialog
from pewpew.widgets.laser import LaserTabView
from pewpew.widgets.wizards import ImportWizard, SpotImportWizard
from pewpew.widgets.wizards import ImportWizard, LaserLogImportWizard, SpotImportWizard

logger = logging.getLogger(__name__)

Expand All @@ -27,6 +28,8 @@ def __init__(self, parent: QtWidgets.QWidget | None = None):
super().__init__(parent)
self.resize(1280, 800)

self.setAcceptDrops(True)

self.log = LoggingDialog()
self.help = HelpDialog()

Expand Down Expand Up @@ -54,6 +57,38 @@ def __init__(self, parent: QtWidgets.QWidget | None = None):

self.default_config = Config()

def dragEnterEvent(self, event: QtGui.QDragEnterEvent) -> None:
if event.mimeData().hasUrls():
paths = [Path(url.toLocalFile()) for url in event.mimeData().urls()]
if any(is_nwi_laser_log(path) for path in paths):
event.acceptProposedAction()
super().dragEnterEvent(event)

def dropEvent(self, event: QtGui.QDropEvent) -> None:
if not event.mimeData().hasUrls():
return super().dropEvent(event)
log_paths = []
paths = []
for url in event.mimeData().urls():
path = Path(url.toLocalFile())
if is_nwi_laser_log(path):
log_paths.append(path)
else:
paths.append(path)

wiz = LaserLogImportWizard(
path=log_paths[0],
laser_paths=paths,
options=self.tabview.options,
parent=self,
)
wiz.laserImported.connect(self.tabview.importFile)
wiz.laserImported.connect(
lambda: self.tabview.activeWidget().graphics.zoomReset()
)
wiz.open()
event.acceptProposedAction()

def createActions(self) -> None:
self.action_about = qAction(
"help-about", "&About", "About pew².", self.actionAbout
Expand Down Expand Up @@ -182,9 +217,15 @@ def createActions(self) -> None:
self.action_wizard_import = qAction(
"",
"Import Wizard",
"Start the line-wise import wizard. .",
"Start the line-wise import wizard.",
self.actionWizardImport,
)
self.action_wizard_laserlog = qAction(
"",
"ESL Laser Log Wizard",
"Import data and sync to a ESL ActiveView2 log file.",
self.actionWizardLaserLog,
)
self.action_wizard_spot = qAction(
"",
"Spotwise Wizard",
Expand All @@ -210,6 +251,7 @@ def createMenus(self) -> None:
# File -> Import
menu_import = menu_file.addMenu("&Import")
menu_import.addAction(self.action_wizard_import)
menu_import.addAction(self.action_wizard_laserlog)
menu_import.addAction(self.action_wizard_spot)
# menu_import.addAction(self.action_wizard_srr)

Expand Down Expand Up @@ -402,6 +444,15 @@ def actionWizardSpot(self) -> QtWidgets.QWizard:
wiz.open()
return wiz

def actionWizardLaserLog(self) -> QtWidgets.QWizard:
wiz = LaserLogImportWizard(options=self.tabview.options, parent=self)
wiz.laserImported.connect(self.tabview.importFile)
wiz.laserImported.connect(
lambda: self.tabview.activeWidget().graphics.zoomReset()
)
wiz.open()
return wiz

# def actionWizardSRR(self) -> QtWidgets.QWizard:
# wiz = SRRImportWizard(config=self.tabview.config, parent=self)
# wiz.laserImported.connect(self.tabview.importFile)
Expand Down
Loading

0 comments on commit 8f18c07

Please sign in to comment.