diff --git a/src/dataprovider/pumpcalibprovider.py b/src/dataprovider/pumpcalibprovider.py
deleted file mode 100644
index c3314066a2d96298e8e2d95ec2f4a65b08b430e5..0000000000000000000000000000000000000000
--- a/src/dataprovider/pumpcalibprovider.py
+++ /dev/null
@@ -1,107 +0,0 @@
-import pandas as pd
-import os
-import re
-
-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_files.sort()
-
-        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["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 + self.pump_id + "_calib_coef.csv",
-                         sep=",",
-                         parse_dates=["first_run_datetime", "apply_datetime"])
-        df["calib_id_str"] = df["first_run_datetime"].dt.strftime("%Y%m%d-%H%M")
-        df["calib_id_int"] = df.index
-        return df
-
-    def get_turning_df(self) -> pd.DataFrame:
-        # Keep only state-change-related files (like: 20190911_COMPUMP_state_changes.csv)
-        regex = re.compile(r'^[0-9]{8}_' + self.pump_id + '_state_changes.csv$')
-        state_files = list(filter(regex.search, self.all_files))
-        state_files.sort()
-
-        turning_df = pd.DataFrame()
-        for filename in state_files:
-            df = pd.read_csv(filepath_or_buffer=self.data_dir + filename,
-                             sep=",",
-                             parse_dates=["datetime"])
-            turning_df = turning_df.append(df)
-
-        turning_df = turning_df[turning_df["name"] != "direction"]
-        turning_df["value"] = pd.to_numeric(turning_df["value"])
-
-        # raw_rpm_df contains only the "change rpm" command values, at the time they were originally sent,
-        # not the moment they were applied.
-        raw_rpm_df = turning_df[turning_df["name"] == "rpm"]
-        raw_rpm_df = raw_rpm_df.drop(columns=["name"])
-        raw_rpm_df.rename(columns={"value": 'rpm'}, inplace=True)
-
-        # rpm_df contains the rpm value, timestamped at the moment they were applied, i.e. when the pump was actually
-        # turning.
-        rpm_df = pd.DataFrame()
-        last_start = None
-        for index, row in turning_df[turning_df["name"] == "turning"].iterrows():
-            if row["value"] == 1:
-                last_start = row["datetime"]
-                try:
-                    previous_rpm = turning_df.loc[(turning_df["name"] == "rpm")
-                                              & (turning_df["datetime"] < row["datetime"])].iloc[-1]["value"]
-                except IndexError:
-                    # Happens when the first line is turning=True, so RPM at that time is not known.
-                    previous_rpm = 0.0
-                rpm_df = rpm_df.append({"datetime": row["datetime"],
-                                        "rpm": previous_rpm},
-                                       ignore_index=True)
-            else:
-                rpm_df = rpm_df.append(raw_rpm_df.loc[(raw_rpm_df["datetime"] >= last_start)
-                                                      & (raw_rpm_df["datetime"] <= row["datetime"])])
-                rpm_df = rpm_df.append({"datetime": row["datetime"],
-                                        "rpm": 0},
-                                       ignore_index=True)
-
-        # Integrate to get the number of turns
-        rpm_df["turns"] = rpm_df["rpm"].shift(1) * rpm_df["datetime"].diff().dt.total_seconds() / 60
-        rpm_df["total_turns"] = rpm_df["turns"].cumsum()
-
-        return rpm_df
-
-    def get_mlmin_to_rpm_evol_df(self):
-        turning_df = self.get_turning_df()
-
-        runs_df = self.get_runs_df()
-        runs_df = runs_df[["start_time", "rpm", "flow"]]
-        runs_df["total_turns"] = 0
-        runs_df = runs_df.reset_index(drop=True)
-
-        for index, row in runs_df.iterrows():
-            last_known_total_turns = turning_df.loc[turning_df["datetime"] < row["start_time"]].iloc[-1]["total_turns"]
-            runs_df.at[index, 'total_turns'] = last_known_total_turns
-
-        return runs_df
\ No newline at end of file
diff --git a/src/main.py b/src/main.py
index 8d0d6438c39a1405c2be8cd029c25a5c07f5661a..89bc58fbb5747d04ab790963363822a1aef32a95 100755
--- a/src/main.py
+++ b/src/main.py
@@ -1,7 +1,6 @@
 #!../venv/bin/python3.7
 import sys
 from PyQt5.QtWidgets import QApplication
-from PyQt5.QtCore import QThread
 
 from config import Config
 
@@ -10,7 +9,6 @@ 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
@@ -35,9 +33,6 @@ 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
@@ -45,7 +40,7 @@ picpump_prvd = PumpCalibProvider("PICPUMP", config)
 
 conductcalib_uim = ConductCalibUim(conduct_prvd, main_window_ui, config)
 explo_uim = ExploUim(explo_prvd, main_window_ui, config, main_window.stab_windows)
-pump_uim = PumpCalibUim(compump_prvd, colpump_prvd, picpump_prvd, main_window_ui, config)
+pump_uim = PumpCalibUim(main_window_ui, config)
 
 ########################################################################################################################
 # LAUNCH APPLICATION
diff --git a/src/uim/pumpcalibuim.py b/src/uim/pumpcalibuim.py
index 6dc1ec7b5adc6c1f9f94ac580daecdf63f2db1f5..d913718f8e5d61fe6729b7b5d03b63b7f42c85d5 100644
--- a/src/uim/pumpcalibuim.py
+++ b/src/uim/pumpcalibuim.py
@@ -1,63 +1,54 @@
-import datetime
-import re
 from math import atan, degrees
 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
-from cfatools.provider.pump_calib import PumpCalibReader
+from cfatools.logreader.pump_calib import PumpCalibReader
+import cfatools.processor.pump as pump_proc
 
-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):
+    def __init__(self, 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.pump_reader = self.set_current_pump_reader()
         self.main_ui.pump_combobox_pump.currentTextChanged.connect(self.change_pump)
         self.change_pump(self.main_ui.pump_combobox_pump.currentText())
 
         self.runs_df = pd.DataFrame()
         self.coef_df = pd.DataFrame()
 
-    def set_current_pump_prvd(self, pump_text: str = None) -> PumpCalibProvider:
+    def set_current_pump_reader(self, pump_text: str = None) -> PumpCalibReader:
         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
             self.pump_reader = PumpCalibReader(self.config.read("DATA_SOURCE", "absolute_root_dir"), "COMPUMP")
         elif pump_text == "Collector pump":
-            self.pump_prvd = self.colpump_prvd
             self.pump_reader = PumpCalibReader(self.config.read("DATA_SOURCE", "absolute_root_dir"), "COLPUMP")
         elif pump_text == "Picarro pump":
-            self.pump_prvd = self.picpump_prvd
             self.pump_reader = PumpCalibReader(self.config.read("DATA_SOURCE", "absolute_root_dir"), "PICPUMP")
         else:
             raise ValueError("Impossible to assign a Provider from text [" + pump_text + "]")
 
-        return self.pump_prvd
+        return self.pump_reader
 
     def change_pump(self, pump_text: str = None):
-        self.set_current_pump_prvd(pump_text)
+        self.set_current_pump_reader(pump_text)
         self.runs_df = self.pump_reader.get_runs_df()
         self.coef_df = self.pump_reader.get_coef_df()
         self.__update_runs_plot__(self.runs_df, self.coef_df)
-        self.__update_evol_plot__(self.pump_prvd.get_mlmin_to_rpm_evol_df())
+
+        turns_history_df = pump_proc.get_turns_history_df(
+            rpm_history_df=self.pump_reader.get_state_changes_df("rpm"),
+            turning_history_df=self.pump_reader.get_state_changes_df("turning")
+        )
+        evol_df = pump_proc.get_mlmin_to_rpm_evol_df(turns_history_df=turns_history_df, runs_df=self.runs_df)
+        self.__update_evol_plot__(evol_df)
 
     ####################################################################
     # Plot