diff --git a/pyqt/mainwindow.ui b/pyqt/mainwindow.ui index ea0e8e85cad6ee316fb9a20bd56906aeef3e6332..3e7d29f56e7389f372a1be926985a3419521814e 100644 --- a/pyqt/mainwindow.ui +++ b/pyqt/mainwindow.ui @@ -24,7 +24,7 @@ </rect> </property> <property name="currentIndex"> - <number>0</number> + <number>2</number> </property> <widget class="QWidget" name="tab_explo"> <attribute name="title"> @@ -450,6 +450,56 @@ </property> </widget> </widget> + <widget class="QWidget" name="tab_pumpcalib"> + <attribute name="title"> + <string>Pump calibration</string> + </attribute> + <widget class="QComboBox" name="pump_combobox_pump"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>111</width> + <height>22</height> + </rect> + </property> + <item> + <property name="text"> + <string>Common pump</string> + </property> + </item> + <item> + <property name="text"> + <string>Collector pump</string> + </property> + </item> + <item> + <property name="text"> + <string>Picarro pump</string> + </property> + </item> + </widget> + <widget class="PlotWidget" name="pump_graphicsview_runs"> + <property name="geometry"> + <rect> + <x>10</x> + <y>40</y> + <width>831</width> + <height>431</height> + </rect> + </property> + </widget> + <widget class="PlotWidget" name="pump_graphicsview_repro"> + <property name="geometry"> + <rect> + <x>10</x> + <y>490</y> + <width>831</width> + <height>431</height> + </rect> + </property> + </widget> + </widget> </widget> </widget> <widget class="QMenuBar" name="menubar"> diff --git a/src/dataprovider/pumpcalibprovider.py b/src/dataprovider/pumpcalibprovider.py new file mode 100644 index 0000000000000000000000000000000000000000..07d7d17ecc99a53ba8a8500393a5e4840e31989f --- /dev/null +++ b/src/dataprovider/pumpcalibprovider.py @@ -0,0 +1,48 @@ +import pandas as pd +import numpy as np +import datetime +import os +import re + +import utils +from config import Config + + +class PumpCalibProvider: + + def __init__(self, pump_id: str, config: Config): + self.pump_id = pump_id + self.data_dir = config.read("DATA_SOURCE", "absolute_root_dir") + "/pump_calibration/" + pump_id + "/" + + # Get all files in Pump's calib data directory + self.all_files = os.listdir(self.data_dir) + + def get_runs_df(self) -> pd.DataFrame: + # Keep only runs-related files (like: 20191010-064649_COLPUMP_calib_runs.csv) + regex = re.compile(r'^[0-9]{8}-[0-9]{6}_' + self.pump_id + '_calib_runs.csv$') + runs_files = list(filter(regex.search, self.all_files)) + + runs_df = pd.DataFrame() + calib_id_int = 0 + for filename in runs_files: + df = pd.read_csv(filepath_or_buffer=self.data_dir + filename, + sep=",", + parse_dates=["start_time", "end_time"]) + df["start_time"] = df["start_time"].dt.tz_localize('UTC') + df["end_time"] = df["end_time"].dt.tz_localize('UTC') + df["calib_id_str"] = df["start_time"].iloc[0].strftime("%Y%m%d-%H%M") + df["calib_id_int"] = calib_id_int + calib_id_int += 1 + runs_df = runs_df.append(df) + + return runs_df + + def get_coef_df(self) -> pd.DataFrame: + df = pd.read_csv(filepath_or_buffer=self.data_dir + "COLPUMP_calib_coef.csv", + sep=",", + parse_dates=["first_run_datetime", "apply_datetime"]) + df["first_run_datetime"] = df["first_run_datetime"].dt.tz_localize('UTC') + df["apply_datetime"] = df["apply_datetime"].dt.tz_localize('UTC') + df["calib_id_str"] = df["first_run_datetime"].dt.strftime("%Y%m%d-%H%M") + df["calib_id_int"] = df.index + return df diff --git a/src/gui/uimainwindow.py b/src/gui/uimainwindow.py index 2322e2334cdc65eaa500e40002ed28867c795206..ffdf390afbf346508430c2919eeb6ae89035d020 100644 --- a/src/gui/uimainwindow.py +++ b/src/gui/uimainwindow.py @@ -175,6 +175,21 @@ class Ui_MainWindow(object): self.conduct_pushbutton_save_csv.setGeometry(QtCore.QRect(440, 50, 101, 30)) self.conduct_pushbutton_save_csv.setObjectName("conduct_pushbutton_save_csv") self.tabWidget.addTab(self.tab_conductcalib, "") + self.tab_pumpcalib = QtWidgets.QWidget() + self.tab_pumpcalib.setObjectName("tab_pumpcalib") + self.pump_combobox_pump = QtWidgets.QComboBox(self.tab_pumpcalib) + self.pump_combobox_pump.setGeometry(QtCore.QRect(10, 10, 111, 22)) + self.pump_combobox_pump.setObjectName("pump_combobox_pump") + self.pump_combobox_pump.addItem("") + self.pump_combobox_pump.addItem("") + self.pump_combobox_pump.addItem("") + self.pump_graphicsview_runs = PlotWidget(self.tab_pumpcalib) + self.pump_graphicsview_runs.setGeometry(QtCore.QRect(10, 40, 831, 431)) + self.pump_graphicsview_runs.setObjectName("pump_graphicsview_runs") + self.pump_graphicsview_repro = PlotWidget(self.tab_pumpcalib) + self.pump_graphicsview_repro.setGeometry(QtCore.QRect(10, 490, 831, 431)) + self.pump_graphicsview_repro.setObjectName("pump_graphicsview_repro") + self.tabWidget.addTab(self.tab_pumpcalib, "") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1355, 20)) @@ -207,7 +222,7 @@ class Ui_MainWindow(object): self.menubar.addAction(self.menuInstrument.menuAction()) self.retranslateUi(MainWindow) - self.tabWidget.setCurrentIndex(0) + self.tabWidget.setCurrentIndex(2) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): @@ -272,6 +287,10 @@ class Ui_MainWindow(object): self.conduct_pushbutton_load_run.setText(_translate("MainWindow", "Load calib")) self.conduct_pushbutton_save_csv.setText(_translate("MainWindow", "Save as CSV")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_conductcalib), _translate("MainWindow", "Conductometry Calibration")) + self.pump_combobox_pump.setItemText(0, _translate("MainWindow", "Common pump")) + self.pump_combobox_pump.setItemText(1, _translate("MainWindow", "Collector pump")) + self.pump_combobox_pump.setItemText(2, _translate("MainWindow", "Picarro pump")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_pumpcalib), _translate("MainWindow", "Pump calibration")) self.menuInstrument.setTitle(_translate("MainWindow", "Expert mode")) self.action_debuglog.setText(_translate("MainWindow", "Debug Log")) self.action_collector.setText(_translate("MainWindow", "Fration collector")) diff --git a/src/main.py b/src/main.py index 349bfa7a4147533b910fac1989b89922895ac3eb..b9509aaf5201b0b1a93141e61e846ab7e1536a59 100755 --- a/src/main.py +++ b/src/main.py @@ -10,9 +10,11 @@ from gui.mainwindow import MainWindow from dataprovider.conductcalibprovider import ConductCalibProvider from dataprovider.exploprovider import ExploProvider from dataprovider.picarroprovider import PicarroProvider +from dataprovider.pumpcalibprovider import PumpCalibProvider from uim.conductcalibuim import ConductCalibUim from uim.explouim import ExploUim +from uim.pumpcalibim import PumpCalibUim ######################################################################################################################## # CONFIG @@ -33,6 +35,9 @@ main_window_ui = main_window.main_ui conduct_prvd = ConductCalibProvider() picarro_prvd = PicarroProvider(config) explo_prvd = ExploProvider(picarro_prvd) +compump_prvd = PumpCalibProvider("COMPUMP", config) +colpump_prvd = PumpCalibProvider("COLPUMP", config) +picpump_prvd = PumpCalibProvider("PICPUMP", config) ######################################################################################################################## # GUI MANAGERS @@ -40,6 +45,7 @@ explo_prvd = ExploProvider(picarro_prvd) conductcalib_uim = ConductCalibUim(conduct_prvd, main_window_ui, config) explo_uim = ExploUim(explo_prvd, main_window_ui, config) +pump_uim = PumpCalibUim(compump_prvd, colpump_prvd, picpump_prvd, main_window_ui, config) ######################################################################################################################## # LAUNCH APPLICATION diff --git a/src/uim/pumpcalibim.py b/src/uim/pumpcalibim.py new file mode 100644 index 0000000000000000000000000000000000000000..b1e320eebce253d89e26fa346373ec625033085e --- /dev/null +++ b/src/uim/pumpcalibim.py @@ -0,0 +1,83 @@ +import datetime +import re +import pyqtgraph as pg +from PyQt5.QtWidgets import * +from PyQt5.QtGui import QColor +from PyQt5.QtCore import * +import pandas as pd +import numpy as np +from pandas.api.types import is_numeric_dtype + +import utils +from config import Config +from dataprovider.pumpcalibprovider import PumpCalibProvider +from gui.uimainwindow import Ui_MainWindow + + +class PumpCalibUim: + + def __init__(self, + compump_prvd: PumpCalibProvider, colpump_prvd: PumpCalibProvider, picpump_prvd: PumpCalibProvider, + main_ui: Ui_MainWindow, config: Config): + self.main_ui = main_ui + self.compump_prvd = compump_prvd + self.colpump_prvd = colpump_prvd + self.picpump_prvd = picpump_prvd + self.config = config + + self.pump_prvd = self.set_current_pump_prvd() + self.main_ui.pump_combobox_pump.currentTextChanged.connect(self.change_pump) + + self.runs_df = pd.DataFrame() + self.coef_df = pd.DataFrame() + + self.__initialize_runs_plot__() + + def set_current_pump_prvd(self, pump_text: str = None) -> PumpCalibProvider: + if pump_text is None: + pump_text = self.main_ui.pump_combobox_pump.currentText() + + if pump_text == "Common pump": + self.pump_prvd = self.compump_prvd + elif pump_text == "Collector pump": + self.pump_prvd = self.colpump_prvd + elif pump_text == "Picarro pump": + self.pump_prvd = self.picpump_prvd + else: + raise ValueError("Impossible to assign a Provider from text [" + pump_text + "]") + + return self.pump_prvd + + def change_pump(self, pump_text: str = None): + self.set_current_pump_prvd(pump_text) + self.runs_df = self.pump_prvd.get_runs_df() + self.coef_df = self.pump_prvd.get_coef_df() + self.__update_runs_plot__(self.runs_df, self.coef_df) + + + #################################################################### + # Plot + + def __initialize_runs_plot__(self) -> None: + + self.plot_item = pg.PlotItem() + self.main_ui.pump_graphicsview_runs.setCentralItem(self.plot_item) + self.runs_points_list = [] + + def __update_runs_plot__(self, runs_df: pd.DataFrame, coef_df: pd.DataFrame) -> None: + + color_map = pg.ColorMap(pos=[runs_df["calib_id_int"].min(), + runs_df["calib_id_int"].max()], + color=[[0, 0, 255], [0, 255, 0]]) + brushes = [pg.mkBrush(color=color) for color in color_map.mapToQColor(runs_df["calib_id_int"])] + + runs_points = pg.ScatterPlotItem(runs_df["rpm"], + runs_df["flow"], + size=5, + brush=brushes) + + self.plot_item.addItem(runs_points) + + # Add linear regression line + # self.linear_line = pg.PlotCurveItem() + # plot_item.addItem(self.linear_line)