Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image analysis #8

Closed
wants to merge 263 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
263 commits
Select commit Hold shift + click to select a range
5f8cb48
MNT: Add to gitignore
ericdill Jul 11, 2015
1f93fe8
contrib update
campagnola Jul 11, 2015
1dc4c5c
Merge pull request #181 from ericdill/gitignore
campagnola Jul 11, 2015
3707a67
DOC: Note odd behavior with setup.py develop
ericdill Jul 11, 2015
f929f40
BUG: Divide by zero error in ImageItem autoDownsample
ericdill Jul 11, 2015
a52d8f7
TST: Barn door testing on the divide-by-zero error
ericdill Jul 11, 2015
3bdb29e
MNT: Remove commented code
ericdill Jul 11, 2015
e33dd2b
MNT: Move most of __main__.py into utils.py
ericdill Jul 12, 2015
fdaffea
tweak text
campagnola Jul 12, 2015
0865a31
Merge pull request #183 from ericdill/zero-div-is-bad
campagnola Jul 12, 2015
6375c74
TST: Finish testing all examples
ericdill Jul 12, 2015
f3e63e4
DOC: Add instructions for running the test suite
ericdill Jul 12, 2015
a7bea50
Merge pull request #184 from ericdill/split-main
campagnola Jul 12, 2015
f6de3c6
pyside bugfix
campagnola Jul 12, 2015
c98ded5
Merge pull request #185 from ericdill/add-test-to-contrib
campagnola Jul 12, 2015
e7fbddc
Merge pull request #179 from mrussell42/transform_fft_logscale
campagnola Jul 12, 2015
ed35993
TST: all the testing
ericdill Jul 12, 2015
9d09f4b
DOC: Document the valid args for bg/fg
ericdill Jul 12, 2015
179b8db
make `python examples/` work again
campagnola Jul 12, 2015
8285045
Merge branch 'ericdill-split-main' into develop
campagnola Jul 12, 2015
a6d5e28
Merge pull request #187 from ericdill/color-descriptions
campagnola Jul 12, 2015
0e4fd90
ENH: Clean up temp file from test suite
ericdill Jul 13, 2015
e6c1c54
MNT: Use tempfile
ericdill Jul 17, 2015
f0c9cfa
Merge pull request #188 from ericdill/clean-up-after-oneself
campagnola Jul 18, 2015
9ea38a1
Use glColor instead of mkColor to set GLViewWidget background color.
ixjlyons Jul 22, 2015
0b929d3
MNT: First travis attempt
ericdill Jul 17, 2015
c7aa35b
MNT: dont install pyside for python 3
ericdill Jul 17, 2015
e5c903a
MNT: Test examples too
ericdill Jul 17, 2015
4a1ceaf
MNT: add coverage to install. maybe that will kick coveralls?
ericdill Jul 17, 2015
668884a
MNT: Respect QT environmental variable
ericdill Jul 18, 2015
b6dae6c
MNT: don't install pyqt by default
ericdill Jul 18, 2015
c02dbe7
TST: use pyqtgraph.Qt to import Qt stuff
ericdill Jul 18, 2015
c3cfdfd
TST: Tests are passing on pyside, but many are skipped
ericdill Jul 20, 2015
3e9c9c9
DOC: Add a travis and codecov badges
ericdill Jul 28, 2015
d6e74fe
DOC: Remove commented out test decorator
ericdill Jul 31, 2015
d050ee4
TST: Attempt 1 at breaking out ViewBox tests
ericdill Jul 31, 2015
7938d82
DOC: Removing duplicate code
ericdill Jul 31, 2015
f5aa792
TST: Wrap each test function in setup/teardown
ericdill Jul 31, 2015
26ee8d5
TST: Add the initial window shape test back
ericdill Jul 31, 2015
2b07556
TST: Wheeee overengineered solution!
ericdill Jul 31, 2015
94e4578
TST: How about we don't over-engineer a solution
ericdill Jul 31, 2015
cb326c4
TST: But I should not just copy/paste code...
ericdill Jul 31, 2015
29795a0
TST: Skip the failing test for now.
ericdill Jul 31, 2015
ed21938
MNT: Need to import pytest...
ericdill Jul 31, 2015
740acf5
Merge pull request #191 from ericdill/travis
campagnola Jul 31, 2015
fb910dc
DOC: I should, uh, badge this repo correctly...
ericdill Jul 31, 2015
30515e8
Merge pull request #202 from ericdill/wrong-codecov-link
campagnola Jul 31, 2015
1f05512
MNT: Testing codecov and coveralls
ericdill Jul 31, 2015
a8c4efc
TST: cding all over the place makes codecov sad
ericdill Aug 1, 2015
304f2f1
MNT: hard code the coverage report location
ericdill Aug 1, 2015
728c615
COV: coverage stats seem to fail the upload sometimes
ericdill Aug 1, 2015
cc65519
Merge pull request #203 from ericdill/testing-codecov
campagnola Aug 2, 2015
a058680
MNT: Test python 2.6 on travis
ericdill Aug 2, 2015
4b15fa7
TST: Use pgcollections.OrderedDict for 2.6 compat
ericdill Aug 2, 2015
afbc653
py26: {} cannot be empty for string formatting
ericdill Aug 2, 2015
13c67af
MNT: Ahh it's the semicolon...
ericdill Aug 3, 2015
f224936
Merge pull request #135 from termim/stepMode_and_Average
campagnola Aug 8, 2015
1036edf
Merge pull request #194 from ixjlyons/gl-background
campagnola Aug 8, 2015
f49c179
ignore wheel events in GraphicsView if mouse disabled
Aug 25, 2015
21ed131
support multiple polygon path in FillBetweenItem
Aug 25, 2015
d65008d
defer debug message formatting to improve multiprocess communication …
campagnola Sep 4, 2015
53c9214
Add unicode, bytes to default no-proxy list
campagnola Sep 4, 2015
ab1051f
invalid slice fix
fedebarabas Sep 4, 2015
88091a6
fix update() of nodes with multiple input
duguxy Aug 20, 2015
37367c8
Update functions.py
DavidLP Oct 23, 2015
0904fb4
Pass TableWidget key press events to the parent class to allow for ar…
ixjlyons Oct 25, 2015
5b8d558
Merge pull request #241 from ixjlyons/tablewidget-keypress
campagnola Dec 21, 2015
8b6771f
Merge pull request #232 from duguxy/flowchart-update
campagnola Dec 21, 2015
de6d742
Merge pull request #227 from campagnola/multiprocess-cleanup
campagnola Dec 21, 2015
2360e9f
Merge pull request #226 from fedebarabas/develop
campagnola Dec 21, 2015
9796a3f
Merge pull request #221 from rabryan/finite-fills
campagnola Dec 21, 2015
215b39a
Merge pull request #219 from rabryan/wheel-event-ignore
campagnola Dec 21, 2015
51e06c3
MNT: Switch to WeakKeyDict
ericdill Dec 24, 2015
21c79d1
MNT: Should use the actual widget not 'widget'
ericdill Dec 24, 2015
15ba9e6
Merge branch 'develop' of https://github.com/SiLab-Bonn/pyqtgraph int…
campagnola Jan 2, 2016
e495bbc
Use inplace multiply
campagnola Jan 2, 2016
8803a93
Merge pull request #254 from campagnola/numpy-fix
campagnola Jan 2, 2016
55c1554
Remove parallel unit testing
campagnola Jan 3, 2016
9e8c208
Merge pull request #262 from campagnola/py26compat
campagnola Jan 3, 2016
99aa4cf
Performance improvements for makeARGB. Also adding unit tests..
campagnola Jan 11, 2016
2c415a8
Fix Numpy FutureWarning.
u55 Jan 12, 2016
2f29752
Fix Numpy FutureWarning. Try again.
u55 Jan 12, 2016
905a541
new markers
lesauxvi Jan 15, 2016
ce36ea4
Infiniteline enhancement
lesauxvi Jan 15, 2016
0d4c78a
Infiniteline enhancement
lesauxvi Jan 15, 2016
e2f43ce
simplify makeARGB: remove float support (this was never functional an…
campagnola Jan 26, 2016
4be2869
corrections and cleanups for functions.makeARGB
campagnola Jan 30, 2016
7048243
Improve ImageItem performance by scaling LUT instead of image when po…
campagnola Jan 30, 2016
dcf45b0
Merge pull request #272 from campagnola/image-performance
campagnola Jan 30, 2016
a41f3c3
fix case where connect is ndarray
campagnola Jan 30, 2016
586de31
Merge remote-tracking branch 'pyqtgraph/develop' into u55-u55-patch-1
campagnola Jan 30, 2016
f279988
suppress numpy futurewarning
campagnola Jan 30, 2016
2a80205
ImageItem bugfix
campagnola Jan 30, 2016
3f03622
fix isosurface/isocurve for numpy API change
campagnola Jan 30, 2016
d308d45
avoid numpy warnings when indexing with floats
campagnola Jan 30, 2016
ee3e621
correction for catch_warnings on python 3
campagnola Jan 30, 2016
fd76443
Merge pull request #273 from campagnola/numpy-fix
campagnola Jan 30, 2016
07f6109
creation of a combined method for handling the label location
lesauxvi Feb 1, 2016
98ff70e
Improve drawing performance by caching the line and bounding rect.
Feb 2, 2016
89cb6e4
Import image testing code from vispy
campagnola Feb 3, 2016
51b8be2
Infinite line extension
lesauxvi Feb 3, 2016
aec6ce8
infinite line performance improvement
lesauxvi Feb 4, 2016
2b9f613
Added unit tests checking infiniteline interactivity
campagnola Feb 4, 2016
c1de24e
add hover tests
campagnola Feb 4, 2016
ad8e169
infiniteline API testing
campagnola Feb 5, 2016
4a3525e
infiniteline tests pass
campagnola Feb 5, 2016
5286306
Merge remote-tracking branch 'henesissrl/infinite_line_speedup' into …
campagnola Feb 5, 2016
0be3615
docstring correction
lesauxvi Feb 5, 2016
e7b27c2
text location algorithm simplification
lesauxvi Feb 5, 2016
20ee97c
Fixing order of positions in colormap
lionel-martin Feb 10, 2016
f2a72bf
Image tester is working
campagnola Feb 12, 2016
879f341
fix: no check_output in py 2.6
campagnola Feb 13, 2016
ebe4229
fix py3 imports
campagnola Feb 14, 2016
e0a5dae
Made default image comparison more strict.
campagnola Feb 14, 2016
5171e1f
Remove axes from plotcurveitem test--fonts differ across platforms.
campagnola Feb 14, 2016
e712b86
relax auto-range check
campagnola Feb 14, 2016
0bdc89f
correction for plotcurveitem tests on osx
campagnola Feb 14, 2016
a8b5624
example modifications
lesauxvi Feb 15, 2016
6fc4e1a
renaming of a method for better consistency
lesauxvi Feb 15, 2016
392c3c6
Added symbol example to menu; minor cleanups to symbol example.
campagnola Feb 15, 2016
f988f05
Merge branch 'new_markers' into develop
campagnola Feb 15, 2016
3a50f65
added setColorMap method to ImageView
meganbkratz Feb 15, 2016
229fc6a
added lines setting a custom color map to the ImageView example
meganbkratz Feb 15, 2016
74fad9e
added setPredefinedGradient function to ImageView, and added document…
meganbkratz Feb 15, 2016
e5bd1f5
added note about updating docstring if Gradient list is updated
meganbkratz Feb 15, 2016
de24d6d
correction of the text location bug
lesauxvi Feb 16, 2016
ba4b648
addition of a convenient method for handling the label position
lesauxvi Feb 16, 2016
5888603
addition of a draggable option for infiniteline
lesauxvi Feb 16, 2016
010cda0
correction of a bug regarding the exact placement of the label
lesauxvi Feb 17, 2016
926fe1e
image tester corrections
campagnola Feb 17, 2016
e418645
created a decorator function so we can auto-add the list of defined G…
meganbkratz Feb 18, 2016
240cdb1
changed setPredefinedGradient docstring to reference GradientEditorIt…
meganbkratz Feb 18, 2016
5172b78
Added inflinelabel class, label dragging and position update works.
campagnola Feb 19, 2016
a8510c3
clean up textitem, fix anchoring
campagnola Feb 19, 2016
069a5bf
Labels can rotate with line
campagnola Feb 21, 2016
f3a584b
label correctly follows oblique lines
campagnola Feb 22, 2016
170592c
update example
campagnola Feb 22, 2016
a72fec5
Merge branch 'infline-labels' into infiniteline-tests
campagnola Feb 22, 2016
7a0dfd7
Cleanup: add docstrings and setter methods to InfLineLabel, remove un…
campagnola Feb 22, 2016
5388d52
Fix QHeaderView.setResizeMode monkey patch for Qt5 shim
ales-erjavec Feb 22, 2016
167bcbb
Fix QGraphicsItem.scale monkey patch for Qt5
ales-erjavec Feb 22, 2016
dddd4f5
Remove import of PyQt5.Qt unified module
ales-erjavec Feb 22, 2016
4e424b5
Fixed label dragging for oblique lines
campagnola Feb 23, 2016
e4bdc17
Add qWait surrogate for PySide
campagnola Feb 23, 2016
bd0e490
cleanup: docs, default args
campagnola Feb 28, 2016
b7bf633
minor efficiency boost
campagnola Feb 29, 2016
ac14139
rename example
campagnola Feb 29, 2016
bb97f2e
Switch text anchor when line crosses center of view
campagnola Feb 29, 2016
36b3f11
docstring update
campagnola Feb 29, 2016
9d64b26
Merge pull request #286 from campagnola/infiniteline-tests
campagnola Feb 29, 2016
865141a
slight changes in TextItem
lesauxvi Feb 29, 2016
b7efa54
addition of a method setColor for TextItem
lesauxvi Feb 29, 2016
fe115a9
small change in a docstring
lesauxvi Feb 29, 2016
c65ca6d
Merge branch 'develop' into image-testing
campagnola Mar 18, 2016
e1c6526
change in the setText method of TextItem
lesauxvi Mar 18, 2016
856c5ea
Merge pull request #282 from campagnola/image-testing
ericdill Mar 22, 2016
5cd9646
CHANGELOG addition and slight modification of the setColor method
lesauxvi Mar 23, 2016
0e679ed
some documentation improvements
meganbkratz Mar 25, 2016
18024a0
fix a color name error
WayneTimer Mar 27, 2016
fbff457
Merge pull request #302 from WayneTimer/fix-color-error
ericdill Mar 27, 2016
0ac914f
Merge pull request #291 from lesauxvi/textitem
campagnola Mar 28, 2016
1a22ce3
MNT: Call close() up the inheritance chain
ericdill Mar 23, 2016
90d6c95
MNT: Call close on the mro for ImageView
ericdill Mar 28, 2016
a8d3aad
Add darwin-specific shared mem file open and close in RemoteGraphics…
cboulay Mar 29, 2016
5e420fe
Merge branch 'ImageViewWork' of https://github.com/meganbkratz/pyqtgr…
campagnola Apr 3, 2016
0d2bd10
Use colormap with better perceptual contrast
campagnola Apr 3, 2016
eb62577
Merge branch 'meganbkratz-ImageViewWork' into develop
campagnola Apr 3, 2016
63d12c1
Merge pull request #287 from ales-erjavec/qt5-fix
campagnola Apr 4, 2016
3ec02d0
Fix opt name for SpinBox: range -> bounds.
ixjlyons Apr 12, 2016
9b450b2
Encode QPropertyAnimation property name if not passed as bytes.
ixjlyons Apr 12, 2016
d67d2c6
Merge pull request #308 from ixjlyons/fix-issue260
ericdill Apr 12, 2016
dffc2d4
Merge pull request #300 from ericdill/graphics-view-inheritance
campagnola Apr 21, 2016
6096926
Merge pull request #281 from lionel-martin/colormap_positions
campagnola Apr 21, 2016
f49554d
Merge pull request #304 from cboulay/osx_mremap
campagnola Apr 21, 2016
9e4443c
More detailed comment.
ixjlyons Apr 21, 2016
7062662
Merge pull request #309 from ixjlyons/fix-issue257
campagnola Apr 22, 2016
2eca4ed
Set MetaArray._info after modifications during MetaArray.checkInfo().
cboulay Apr 24, 2016
5a21d59
A few small style changes to MetaArray.py
cboulay Apr 24, 2016
c599635
Merge pull request #305 from cboulay/MetArr_PrettierPrinting
campagnola Apr 24, 2016
b4b1aec
Added "self.moving = False" in InfLineLabel class
rlegnain May 3, 2016
1acb8ac
Merge pull request #326 from rlegnain/develop
ericdill May 3, 2016
2ab5280
added simple roi tests (these do not check output)
campagnola May 3, 2016
bb44a33
Made InfLineLabel.setFormat actually set the format string.
May 3, 2016
670d63c
Merge pull request #327 from lidstrom83/InfLineLabel.setFormat_fix
ericdill May 3, 2016
b4e4101
Correct color handling in test images
campagnola May 9, 2016
5c58448
minor ROI corrections
campagnola May 9, 2016
d4cc2e8
Add getArrayRegion tests for ROI, RectROI, and EllipseROI
campagnola May 9, 2016
ccf2ae4
Fix PolyLineROI.getArrayRegion and a few other bugs
campagnola May 14, 2016
bb507cf
ROI tests pass
campagnola May 18, 2016
8f7b553
Added PolyLineROI unit tests, fixed several bugs in mouse interaction…
campagnola May 31, 2016
49d5543
travis fix
campagnola May 31, 2016
2e59cd6
Fix image test makePng function
campagnola Jun 5, 2016
230659a
Allow Qt lib selection from environment variable for testing
campagnola Jun 5, 2016
637eab8
Add debugging output for image testing
campagnola Jun 15, 2016
f0071a0
docstring update
campagnola Jun 15, 2016
f32dce7
Avoid using QGraphicsLayout for tests; this produces unreliable results
campagnola Jun 17, 2016
0d131e4
Remove axes in ROI tests (these cause travis failures)
campagnola Jul 18, 2016
08b93dc
minor corrections
campagnola Jul 18, 2016
8b0c61e
Add ImageItem tests, fix image downsampling bug
campagnola Jun 3, 2016
e36fca8
Update test data tag
campagnola Jun 3, 2016
0172d7b
Fix pixel error in image tests by preventing an extra plot window fro…
campagnola Jun 4, 2016
e46be6d
Remove axes from tests; these break CI tests.
campagnola Jul 19, 2016
bee5878
Added imageAxisOrder config option
campagnola Apr 28, 2016
e740cb4
updated examples to use normal axis order, fixed a few ROI bugs
campagnola May 3, 2016
54fbfdb
fix from prior merge
campagnola Jun 4, 2016
a76fc37
imageAxisOrder config option now accepts "row-major" and "col-major" …
campagnola Jun 16, 2016
f49bfbf
add transposed roi tests
campagnola Aug 23, 2016
956251f
enabled transposed ROI tests; not passing yet
campagnola Aug 23, 2016
a85fc46
imagecanvasitem updates:
campagnola Aug 24, 2016
df69159
ROI tests pass with row-major axis order
campagnola Aug 26, 2016
af12c75
Added a few useful flowchart nodes
campagnola Aug 26, 2016
d19f02a
Create TVDenoise flowchart filter, cleanup
campagnola Aug 26, 2016
67bff6b
bugfix in polylineroi.getarrayregion
campagnola Aug 27, 2016
95b2acb
Merge pull request #349 from campagnola/roi-tests
campagnola Aug 27, 2016
e84af46
Merge pull request #369 from campagnola/imageitem-tests
campagnola Aug 28, 2016
2e36058
IsocurveItem obeys imageAxisOrder config option
campagnola Aug 28, 2016
e9afbb9
Clean up examples / docs
campagnola Aug 31, 2016
b50e242
Add config option sanity checking
campagnola Aug 31, 2016
db07a16
Test update and more bugfixes
campagnola Aug 31, 2016
c17f03e
LineSegmentROI.getArrayRegion API correction
campagnola Sep 3, 2016
748a843
minor edits
campagnola Sep 7, 2016
8aec44d
Use console's namespace as both local and global context for exec/eval.
campagnola Sep 7, 2016
152c5d3
Fixed bool / monochrome image display, added more unit tests
campagnola Sep 8, 2016
81dac22
style fix
campagnola Sep 8, 2016
4b9f1a2
Merge pull request #370 from campagnola/image-alignment
campagnola Sep 8, 2016
5195d9d
Merge pull request #374 from campagnola/console-scope
campagnola Sep 10, 2016
776013b
Start adding simple image filter buttons back in
campagnola Sep 19, 2016
f5f228c
fixup GroupBox open/close button
campagnola Sep 21, 2016
f9a078e
starting more filter buttons
campagnola Sep 21, 2016
8ca30c8
code cleanup
campagnola Sep 26, 2016
436e84a
Add getter/setter for PythonEval node's source code
campagnola Sep 26, 2016
cd92792
Speed up eq.py array comparison
campagnola Sep 26, 2016
391ba48
Reimplemented old filter buttons w/ flowchart
campagnola Sep 26, 2016
b527267
Don't add useless input/output nodes for flowchart control panel
campagnola Sep 26, 2016
92d2dfe
imagecanvasitem: remember last used slice values when switching filte…
campagnola Sep 26, 2016
53c865e
minor ui cleanup
campagnola Sep 26, 2016
d0b2783
DataManager: Don't write file metadata if the user has not changed field
campagnola Sep 28, 2016
7b35429
DataManager: add busy cursor while loading data
campagnola Sep 28, 2016
14b9c98
Merge pull request #48 from campagnola/no-info-write-on-browse
campagnola Sep 29, 2016
ffbe2ec
Add beginning of MaskPainter
campagnola Oct 6, 2016
a0e0c7d
Merge branch 'develop' into pyqtgraph-core
campagnola Oct 6, 2016
b4278f2
Merge remote-tracking branch 'pyqtgraph-upstream/develop' into pyqtgr…
campagnola Oct 7, 2016
d7baeae
Merge branch 'pyqtgraph-core' into pyqtgraph-merge
campagnola Oct 7, 2016
ea5203a
Bugfixes following pyqtgraph merge
campagnola Oct 7, 2016
0365620
Merge branch 'pyqtgraph-merge' into image-analysis
campagnola Oct 10, 2016
bec6213
code cleanup
campagnola Oct 12, 2016
d38a3fd
Adding save/restore functionality to mosaiceditor
campagnola Oct 12, 2016
8ee851a
MosaicEditor save/reload is mostly working
campagnola Oct 14, 2016
3020661
MosaicEditor save/reload seems to be working
campagnola Oct 20, 2016
1fda24b
MosaicEditor: Add clear button and fix saving bug
campagnola Nov 23, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 151 additions & 39 deletions acq4/analysis/modules/MosaicEditor/MosaicEditor.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
# -*- coding: utf-8 -*-

from PyQt4 import QtGui, QtCore
from acq4.analysis.AnalysisModule import AnalysisModule
#from flowchart import *
import os
import glob
import json
import weakref
from collections import OrderedDict
import acq4.util.debug as debug
import numpy as np
import scipy
import scipy.stats
import acq4.pyqtgraph as pg

import weakref
#import FileLoader
#import DatabaseGui
#import FeedbackButton
import acq4.util.debug as debug
import acq4.pyqtgraph as pg
from acq4.analysis.AnalysisModule import AnalysisModule
from PyQt4 import QtGui, QtCore
from MosaicEditorTemplate import *
import acq4.util.DataManager as DataManager
import acq4.analysis.atlas as atlas
Expand All @@ -39,9 +37,18 @@ class MosaicEditor(AnalysisModule):
The resulting images may be saved as SVG or PNG files.
Mosaic Editor makes extensive use of pyqtgraph Canvas methods.
"""

# Version number for save format.
# increment minor version number for backward-compatible changes
# increment major version number for backward-incompatible changes
_saveVersion = (1, 0)

def __init__(self, host):
AnalysisModule.__init__(self, host)

self.items = weakref.WeakKeyDictionary()
self.files = weakref.WeakValueDictionary()

self.ctrl = QtGui.QWidget()
self.ui = Ui_Form()
self.ui.setupUi(self.ctrl)
Expand All @@ -57,26 +64,36 @@ def __init__(self, host):
self.initializeElements()

self.ui.canvas = self.getElement('Canvas', create=True)
self.items = weakref.WeakKeyDictionary()
self.files = weakref.WeakValueDictionary()
self.cells = {}
self.clear(ask=False)

#addScanImagesBtn = QtGui.QPushButton()
#addScanImagesBtn.setText('Add Scan Image')
self.ui.fileLoader = self.getElement('File Loader', create=True)
self.ui.fileLoader.ui.fileTree.hide()

#self.ui.fileLoader.ui.verticalLayout_2.addWidget(addScanImagesBtn)
try:
self.ui.fileLoader.setBaseClicked() # get the currently selected directory in the DataManager
except:
pass

for a in atlas.listAtlases():
self.ui.atlasCombo.addItem(a)

# Add buttons to the canvas control panel
self.btnBox = QtGui.QWidget()
self.btnLayout = QtGui.QGridLayout()
self.btnLayout.setContentsMargins(0, 0, 0, 0)
self.btnBox.setLayout(self.btnLayout)
l = self.ui.canvas.ui.gridLayout
l.addWidget(self.btnBox, l.rowCount(), 0, 1, l.columnCount())

self.saveBtn = QtGui.QPushButton("Save ...")
self.saveBtn.clicked.connect(self.saveClicked)
self.btnLayout.addWidget(self.saveBtn, 0, 0)

self.clearBtn = QtGui.QPushButton("Clear All")
self.clearBtn.clicked.connect(lambda: self.clear(ask=True))
self.btnLayout.addWidget(self.clearBtn, 0, 1)

self.ui.canvas.sigItemTransformChangeFinished.connect(self.itemMoved)
#self.ui.exportSvgBtn.clicked.connect(self.exportSvg)
self.ui.atlasCombo.currentIndexChanged.connect(self.atlasComboChanged)
self.ui.normalizeBtn.clicked.connect(self.normalizeImages)
self.ui.tileShadingBtn.clicked.connect(self.rescaleImages)
Expand Down Expand Up @@ -110,10 +127,6 @@ def loadAtlas(self, name):
self.closeAtlas()

cls = atlas.getAtlasClass(name)
#if name == 'AuditoryCortex':
# obj = cls(canvas=self.getElement('Canvas'))
#else:
#obj = cls()
obj = cls()
ctrl = obj.ctrlWidget(host=self)
self.ui.atlasLayout.addWidget(ctrl, 0, 0)
Expand All @@ -125,16 +138,19 @@ def loadFileRequested(self, files):
return

for f in files:
if f.shortName().endswith('.mosaic'):
self.loadStateFile(f.name())
continue

if f in self.files: ## Do not allow loading the same file more than once
item = self.files[f]
item.show() # just show the file; but do not load it
continue

if f.isFile(): # add specified files
item = self.canvas.addFile(f)
item = self.addFile(f)
elif f.isDir(): # Directories are more complicated
if self.dataModel.dirType(f) == 'Cell': # If it is a cell, just add the cell "Marker" to the plot
# note: this breaks loading all images in Cell directory (need another way to do that)
item = self.canvas.addFile(f)
else: # in all other directory types, look for MetaArray files
filesindir = glob.glob(f.name() + '/*.ma')
Expand All @@ -143,32 +159,32 @@ def loadFileRequested(self, files):
fdh = DataManager.getFileHandle(fd) # open file to get handle.
except IOError:
continue # just skip file
item = self.canvas.addFile(fdh) # add it
self.amendFile(f, item)
item = self.addFile(fdh)
if len(filesindir) == 0: # add protocol sequences
item = self.canvas.addFile(f)
self.canvas.selectItem(item)
item = self.addFile(f)
self.canvas.autoRange()

def amendFile(self, f, item):
"""
f must be a file loaded through canvas.
Here we update the timestamp, the list of loaded files, and fix
the transform if necessary
def addFile(self, f, name=None, inheritTransform=True):
"""Load a file and add it to the canvas.

The new item will inherit the user transform from the previous item
(chronologocally) if it does not already have a user transform specified.
"""
item = self.canvas.addFile(f, name=name)
self.canvas.selectItem(item)

if isinstance(item, list):
item = item[0]

self.items[item] = f
self.files[f] = item
try:
item.timestamp = f.info()['__timestamp__']
except:
item.timestamp = None

#self.loaded.append(f)

## load or guess user transform for this item
if not item.hasUserTransform() and item.timestamp is not None:
if inheritTransform and not item.hasUserTransform() and item.timestamp is not None:
## Record the timestamp for this file, see what is the most recent transformation to copy
best = None
for i2 in self.items:
Expand All @@ -180,11 +196,11 @@ def amendFile(self, f, item):
if best is None or i2.timestamp > best.timestamp:
best = i2

if best is None:
return

trans = best.saveTransform()
item.restoreTransform(trans)
if best is not None:
trans = best.saveTransform()
item.restoreTransform(trans)

return item

def rescaleImages(self):
"""
Expand Down Expand Up @@ -303,8 +319,104 @@ def getLoadedFiles(self):
"""Return a list of all file handles that have been loaded"""
return self.items.values()

def clear(self, ask=True):
"""Remove all loaded data and reset to the default state.

If ask is True (and there are items loaded), then the user is prompted
before clearing. If the user declines, then this method returns False.
"""
if ask and len(self.items) > 0:
clear = QtGui.QMessageBox.question(None, "Warning", "Really clear all items?")
if not clear:
return False

self.ui.canvas.clear()
self.items.clear()
self.files.clear()
self.lastSaveFile = None
return True

def saveState(self, relativeTo=None):
"""Return a serializable representation of the current state of the MosaicEditor.

This includes the list of all items, their current visibility and
parameters, and the view configuration.
"""
items = list(self.items.keys())
items.sort(key=lambda i: i.zValue())

return OrderedDict([
('contents', 'MosaicEditor_save'),
('version', self._saveVersion),
('rootPath', relativeTo.name() if relativeTo is not None else ''),
('items', [item.saveState(relativeTo=relativeTo) for item in items]),
('view', self.ui.canvas.view.getState()),
])

def saveStateFile(self, filename):
dh = DataManager.getDirHandle(os.path.dirname(filename))
state = self.saveState(relativeTo=dh)
json.dump(state, open(filename, 'w'), indent=4, cls=Encoder)

def restoreState(self, state, rootPath=None):
if state.get('contents', None) != 'MosaicEditor_save':
raise TypeError("This does not appear to be MosaicEditor save data.")
if state['version'][0] > self._saveVersion[0]:
raise TypeError("Save data has version %d.%d, but this MosaicEditor only supports up to version %d.x." % (state['version'][0], state['version'][1], self._saveVersion[0]))

if not self.clear():
return

root = state['rootPath']
if root == '':
# data was stored with no root path; filenames should be absolute
root = None
else:
# data was stored with no root path; filenames should be relative to the loaded file
root = DataManager.getHandle(rootPath)

for itemState in state['items']:
fname = itemState['filename']
if root is None:
fh = DataManager.getHandle(fh)
else:
fh = root[fname]
item = self.addFile(fh, name=itemState['name'], inheritTransform=False)
item.restoreState(itemState)

self.ui.canvas.view.setState(state['view'])

def loadStateFile(self, filename):
state = json.load(open(filename, 'r'))
self.restoreState(state, rootPath=os.path.dirname(filename))

def saveClicked(self):
base = self.ui.fileLoader.baseDir()
if self.lastSaveFile is None:
path = base.name()
else:
path = self.lastSaveFile

filename = QtGui.QFileDialog.getSaveFileName(None, "Save mosaic file", path, "Mosaic files (*.mosaic)")
if filename == '':
return
if not filename.endswith('.mosaic'):
filename += '.mosaic'
self.lastSaveFile = filename

self.saveStateFile(filename)

def quit(self):
self.files = None
self.cells = None
self.items = None
self.ui.canvas.clear()


class Encoder(json.JSONEncoder):
"""Used to clean up state for JSON export.
"""
def default(self, o):
if isinstance(o, np.integer):
return int(o)

return json.JSONEncoder.default(o)
2 changes: 1 addition & 1 deletion acq4/devices/DAQGeneric/DaqChannelGui.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def __init__(self, *args):

if self.config['type'] == 'ao':
for s in self.getSpins():
s.setOpts(dec=True, range=[None, None], step=1.0, minStep=1e-12, siPrefix=True)
s.setOpts(dec=True, bounds=[None, None], step=1.0, minStep=1e-12, siPrefix=True)

self.daqUI.sigChanged.connect(self.daqChanged)
self.ui.waveGeneratorWidget.sigDataChanged.connect(self.updateWaves)
Expand Down
8 changes: 4 additions & 4 deletions acq4/modules/Camera/CameraWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,10 @@ def __init__(self, mod):
self.ui = SequencerTemplate()
self.ui.setupUi(self)

self.ui.zStartSpin.setOpts(value=100e-6, suffix='m', siPrefix=True, step=10e-6, precision=6)
self.ui.zEndSpin.setOpts(value=50e-6, suffix='m', siPrefix=True, step=10e-6, precision=6)
self.ui.zSpacingSpin.setOpts(minimum=1e-9, value=1e-6, suffix='m', siPrefix=True, dec=True, minStep=1e-9, step=0.5)
self.ui.intervalSpin.setOpts(minimum=0, value=1, suffix='s', siPrefix=True, dec=True, minStep=1e-3, step=1)
self.ui.zStartSpin.setOpts(value=100e-6, suffix='m', siPrefix=True, step=10e-6, decimals=6)
self.ui.zEndSpin.setOpts(value=50e-6, suffix='m', siPrefix=True, step=10e-6, decimals=6)
self.ui.zSpacingSpin.setOpts(min=1e-9, value=1e-6, suffix='m', siPrefix=True, dec=True, minStep=1e-9, step=0.5)
self.ui.intervalSpin.setOpts(min=0, value=1, suffix='s', siPrefix=True, dec=True, minStep=1e-3, step=1)

self.updateDeviceList()
self.ui.statusLabel.setText("[ stopped ]")
Expand Down
48 changes: 25 additions & 23 deletions acq4/modules/DataManager/FileDataView.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def setCurrentFile(self, file):
return
else:
image = False
data = file.read()
with pg.BusyCursor():
data = file.read()
if typ == 'ImageFile':
image = True
elif typ == 'MetaArray':
Expand All @@ -54,32 +55,33 @@ def setCurrentFile(self, file):
return


if image:
if self.currentType == 'image' and len(self.widgets) > 0:
try:
self.widgets[0].setImage(data, autoRange=False)
except:
print "widget types:", map(type, self.widgets)
raise
with pg.BusyCursor():
if image:
if self.currentType == 'image' and len(self.widgets) > 0:
try:
self.widgets[0].setImage(data, autoRange=False)
except:
print "widget types:", map(type, self.widgets)
raise
else:
self.clear()
w = pg.ImageView(self)
#print "add image:", w.ui.roiPlot.plotItem
#self.plots = [weakref.ref(w.ui.roiPlot.plotItem)]
self.addWidget(w)
w.setImage(data)
self.widgets.append(w)
self.currentType = 'image'
else:
self.clear()
w = pg.ImageView(self)
#print "add image:", w.ui.roiPlot.plotItem
#self.plots = [weakref.ref(w.ui.roiPlot.plotItem)]
w = pg.MultiPlotWidget(self)
self.addWidget(w)
w.setImage(data)
w.plot(data)
self.currentType = 'plot'
self.widgets.append(w)
self.currentType = 'image'
else:
self.clear()
w = pg.MultiPlotWidget(self)
self.addWidget(w)
w.plot(data)
self.currentType = 'plot'
self.widgets.append(w)
#print "add mplot:", w.mPlotItem.plots

#self.plots = [weakref.ref(p[0]) for p in w.mPlotItem.plots]
#print "add mplot:", w.mPlotItem.plots

#self.plots = [weakref.ref(p[0]) for p in w.mPlotItem.plots]

if (hasattr(data, 'implements') and data.implements('MetaArray')):
if self.dictWidget is None:
Expand Down
4 changes: 3 additions & 1 deletion acq4/modules/DataManager/FileInfoView.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ def focusLost(self, obj):
else:
return
#print "Update", field, val
self.current.setInfo({field: val})
info = self.current.info()
if field not in info or val != info[field]:
self.current.setInfo({field: val})

def clear(self):
#print "clear"
Expand Down
Loading