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

PR: Migrate code to calculate the MRC to the new calc tool api #406

Merged
merged 43 commits into from
Mar 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9d2d476
Move recession module within hydrocalc module
jnsebgosselin Mar 3, 2022
cc266c5
Add a new MasterRecessionCalcTool to the recession module
jnsebgosselin Mar 3, 2022
8540645
Move _setup_mrc_tool to MasterRecessionCalcTool
jnsebgosselin Mar 3, 2022
bea840b
Move add_mrcperiod to MasterRecessionCalcTool
jnsebgosselin Mar 3, 2022
a074a14
Move method to draw the mrc to MasterRecessionCalcTool
jnsebgosselin Mar 3, 2022
c3b9eb4
Move show_mrc_results to MasterRecessionCalcTool
jnsebgosselin Mar 3, 2022
50d3b24
WLCalc: emir signal when wldset is set
jnsebgosselin Mar 3, 2022
d4b5e67
MasterRecessionCalcTool: connect sig_wldset_changed to _on_wldset_cha…
jnsebgosselin Mar 3, 2022
6471d87
Register navigation and select tools
jnsebgosselin Mar 3, 2022
a880c38
Setup the mrc selector
jnsebgosselin Mar 3, 2022
8e2af0e
Add load_mrc_from_wldset method
jnsebgosselin Mar 3, 2022
a59262f
Install MRC tool in WLCalc
jnsebgosselin Mar 3, 2022
c9490f6
Complete MRC tool installation
jnsebgosselin Mar 3, 2022
c0cc443
WLCalc: remove is_all_btn_raised
jnsebgosselin Mar 3, 2022
c5dde7d
Create a new WLCalcVSpanHighlighter
jnsebgosselin Mar 4, 2022
e0ff853
Move all MRC logic to MasterRecessionCalcTool
jnsebgosselin Mar 4, 2022
6a0b1fd
Rename a file
jnsebgosselin Mar 4, 2022
79bbaa7
Add a clear API for WLCalcAxesWidget
jnsebgosselin Mar 4, 2022
21c5ae6
Move save_mrc_tofile to MasterRecessionCalcTool
jnsebgosselin Mar 4, 2022
d1541c1
Update imports
jnsebgosselin Mar 4, 2022
b8270da
Change wlcalc tools installation order
jnsebgosselin Mar 4, 2022
d0a5d78
Fix draw mrc when date format changes
jnsebgosselin Mar 4, 2022
3661067
Rename btn_MRCalc -> btn_calc_mrc
jnsebgosselin Mar 4, 2022
3115ced
Rename _btn_MRCalc_isClicked -> calculate_mrc
jnsebgosselin Mar 4, 2022
44e6c78
Move calculate_mrc and fix save_mrc_tofile
jnsebgosselin Mar 4, 2022
c63548d
Update test_hydrocalc
jnsebgosselin Mar 4, 2022
d2e6858
WLCalc: fix xycoord draw
jnsebgosselin Mar 4, 2022
456432c
WLCalcAxesWidgetBase: set active to False in init
jnsebgosselin Mar 4, 2022
c768176
Fix remove mrc axes widget activation
jnsebgosselin Mar 4, 2022
2572f27
Rename btn_addpeak -> btn_add_period
jnsebgosselin Mar 4, 2022
df638e8
Rename btn_delpeak -> btn_del_period
jnsebgosselin Mar 4, 2022
60ef56c
Rename some widgets to make code clearer
jnsebgosselin Mar 4, 2022
091a6a0
Update imports
jnsebgosselin Mar 4, 2022
a05058c
Fixing noob mistake of settings mutable as defaults...
jnsebgosselin Mar 4, 2022
bb33a9c
Change attr names to avoid clash with matplolib subclass
jnsebgosselin Mar 4, 2022
5e1aacc
WLCalc: get rid of sig_wldset_changed logic
jnsebgosselin Mar 4, 2022
0d99c11
BRFManager: define class attrs in init
jnsebgosselin Mar 4, 2022
49553d3
Use waitExposed instead of waitForWindowShown
jnsebgosselin Mar 4, 2022
3b5cc8d
Use waitExposed instead of waitForWindowShown
jnsebgosselin Mar 5, 2022
0b69aa1
Change how sig_new_mrc is connectd to hydroprint
jnsebgosselin Mar 5, 2022
1b338bf
Explicitly close hydrocalc in tests to avoid errors in other tests
jnsebgosselin Mar 5, 2022
d3f743f
Try to fix tests (try#1)
jnsebgosselin Mar 5, 2022
ee42fb8
Fix WLCalc __init__
jnsebgosselin Mar 5, 2022
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
462 changes: 44 additions & 418 deletions gwhat/HydroCalc2.py

Large diffs are not rendered by default.

13 changes: 9 additions & 4 deletions gwhat/brf_mod/kgs_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,18 @@ class BRFManager(WLCalcTool):
__tooltip__ = ("A tool to evaluate the barometric "
"response function of wells.")

# Whether it is the first time showEvent is called.
_first_show_event = True

def __init__(self, wldset=None, parent=None):
super().__init__(parent)
self._bp_and_et_lags_are_linked = False
# Whether it is the first time showEvent is called.
self._first_show_event = True

# The WLCalc instance to which this tool is registered.
self.wlcalc = None

# The water level dataset currently registered to this tool.
self.wldset = None

self._bp_and_et_lags_are_linked = False
self._previous_toggled_navig_and_select_tool = None
self.kgs_brf_installer = None

Expand Down
2 changes: 1 addition & 1 deletion gwhat/gwrecharge/tests/test_gwrecharge_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def figstackmanager(qtbot):
figstackmanager = FigureStackManager()
qtbot.addWidget(figstackmanager)
figstackmanager.show()
qtbot.waitForWindowShown(figstackmanager)
qtbot.waitExposed(figstackmanager)
return figstackmanager


Expand Down
203 changes: 158 additions & 45 deletions gwhat/hydrocalc/axeswidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

# ---- Standard library imports
from typing import Any, Callable
from abc import abstractmethod

# ---- Third party imports
import numpy as np
Expand All @@ -21,17 +22,164 @@
from matplotlib.widgets import AxesWidget


class WLCalcVSpanSelector(AxesWidget, QObject):
sig_span_selected = QSignal(tuple)
class WLCalcAxesWidgetBase(AxesWidget, QObject):
"""
Basic functionality for WLCalc axes widgets.

def __init__(self, ax: Axes, wlcalc: QWidget,
useblit: bool = True, onselected: Callable = None,
axvspan_color: str = 'red', axvline_color: str = 'black'):
WARNING: Don't override any methods or attributes present here unless you
know what you are doing.
"""

def __init__(self, ax: Axes, wlcalc: QWidget):
AxesWidget.__init__(self, ax)
QObject.__init__(self)
self.useblit = self.canvas.supports_blit
self.visible = True
self.useblit = useblit and self.canvas.supports_blit
self.wlcalc = wlcalc
self.__artists = []
self.__visible = {}
super().set_active(False)

def set_active(self, active):
"""Set whether the axes widget is active."""
self.set_axeswidget_active(active)
super().set_active(active)
self.wlcalc.draw()

def register_artist(self, artist):
"""Register given artist."""
self.__artists.append(artist)
self.__visible[artist] = False

def clear(self):
"""
Clear the selector.

This method must be called by the canvas BEFORE making a copy of
the canvas background.
"""
for artist in self.__artists:
self.__visible[artist] = artist.get_visible()
artist.set_visible(False)

def restore(self):
"""
Restore the selector.

This method must be called by the canvas AFTER a copy has been made
of the canvas background.
"""
for artist in self.__artists:
artist.set_visible(self.__visible[artist])
self._update()

def _update(self):
for artist in self.__artists:
self.ax.draw_artist(artist)
return False


class WLCalcAxesWidget(WLCalcAxesWidgetBase):
"""
WLCalc axes widget class.

All axes widgets *must* inherit this class and reimplement its interface.
"""

@abstractmethod
def set_axeswidget_active(active):
pass

@abstractmethod
def onmove(self, event):
"""Handler that is called when the mouse cursor moves."""
pass

@abstractmethod
def onpress(self, event):
"""Handler that is called when a mouse button is pressed."""
pass

@abstractmethod
def onrelease(self, event):
"""Handler that is called when a mouse button is released."""
pass


class WLCalcVSpanHighlighter(WLCalcAxesWidget):
sig_span_clicked = QSignal(float)

def __init__(self, ax: Axes, wlcalc: QWidget, tracked_axvspans: list,
onclicked: Callable = None, highlight_color: str = 'red'):
super().__init__(ax, wlcalc)
self.tracked_axvspans = tracked_axvspans

if onclicked is not None:
self.sig_span_clicked.connect(onclicked)

# Axes span highlight.
self.axvspan_highlight = ax.axvspan(
0, 1, visible=False, color=highlight_color, linewidth=1,
ls='-', alpha=0.3)
self.register_artist(self.axvspan_highlight)

# ---- WLCalcAxesWidgetBase interface
def set_axeswidget_active(self, active):
self.axvspan_highlight.xy = [
[np.inf, 1], [np.inf, 0], [np.inf, 0], [np.inf, 1]]
self.axvspan_highlight.set_visible(active)

def onmove(self, event):
"""Handler to draw the selector when the mouse cursor moves."""
if self.ignore(event):
return
if not self.canvas.widgetlock.available(self):
return
if not self.visible:
return

if event.xdata is None:
self.axvspan_highlight.set_visible(False)
self._update()
return

for axvspan in self.tracked_axvspans:
if not axvspan.get_visible():
continue

xy_data = axvspan.xy
x_data = [xy[0] for xy in xy_data]
xdata_min = min(x_data)
xdata_max = max(x_data)
if event.xdata >= xdata_min and event.xdata <= xdata_max:
self.axvspan_highlight.set_visible(True)
self.axvspan_highlight.xy = [[xdata_min, 1],
[xdata_min, 0],
[xdata_max, 0],
[xdata_max, 1]]
break
else:
self.axvspan_highlight.set_visible(False)
self._update()

def onpress(self, event):
"""Handler for the button_press_event event."""
if event.button != 1 or not event.xdata:
return
self.sig_span_clicked.emit(
event.xdata - self.wlcalc.dt4xls2mpl * self.wlcalc.dformat)
self.onmove(event)

def onrelease(self, event):
pass


class WLCalcVSpanSelector(WLCalcAxesWidget):
sig_span_selected = QSignal(tuple)

def __init__(self, ax: Axes, wlcalc: QWidget, onselected: Callable = None,
axvspan_color: str = 'red', axvline_color: str = 'black'):
super().__init__(ax, wlcalc)

if onselected is not None:
self.sig_span_selected.connect(onselected)
Expand All @@ -40,20 +188,19 @@ def __init__(self, ax: Axes, wlcalc: QWidget,
ax.get_xbound()[0], ax.get_xbound()[0], visible=False,
color=axvspan_color, linewidth=1, ls='-', animated=self.useblit,
alpha=0.1)
self.register_artist(self.axvspan)

self.axvline = ax.axvline(
ax.get_ybound()[0], visible=False, color=axvline_color,
linewidth=1, ls='--', animated=self.useblit)
self.register_artist(self.axvline)

self._onpress_xdata = []
self._onpress_button = None
self._onrelease_xdata = []
super().set_active(False)

def set_active(self, active):
"""
Set whether the selector is active.
"""
# ---- WLCalcAxesWidgetBase interface
def set_axeswidget_active(self, active):
self._onpress_xdata = []
self._onpress_button = None
self._onrelease_xdata = []
Expand All @@ -67,36 +214,7 @@ def set_active(self, active):
[np.inf, 1]]
self.axvspan.set_visible(active)

super().set_active(active)
self.wlcalc.draw()

def clear(self):
"""
Clear the selector.

This method must be called by the canvas BEFORE making a copy of
the canvas background.
"""
self.__axvspan_visible = self.axvspan.get_visible()
self.__axvline_visible = self.axvline.get_visible()
self.axvspan.set_visible(False)
self.axvline.set_visible(False)

def restore(self):
"""
Restore the selector.

This method must be called by the canvas AFTER a copy has been made
of the canvas background.
"""
self.axvspan.set_visible(self.__axvspan_visible)
self.ax.draw_artist(self.axvspan)

self.axvline.set_visible(self.__axvline_visible)
self.ax.draw_artist(self.axvline)

def onpress(self, event):
"""Handler for the button_press_event event."""
if event.button == 1 and event.xdata:
if self._onpress_button in [None, event.button]:
self._onpress_button = event.button
Expand Down Expand Up @@ -179,8 +297,3 @@ def onmove(self, event):
self.axvline.set_visible(False)
self.axvspan.set_visible(False)
self._update()

def _update(self):
self.ax.draw_artist(self.axvline)
self.ax.draw_artist(self.axvspan)
return False
File renamed without changes.
Loading