diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d5792ccec54c774c44dc52af29fcc49aa00935c1..0bef08e37d57e76da690b1e96044e4c6edac53a5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -116,6 +116,7 @@ SET(XTPCPP_SRCS
   ./gui/protein_list_view/proteintablemodel.cpp
   ./gui/protein_list_view/proteintableproxymodel.cpp
   ./gui/waiting_message_dialog/waitingmessagedialog.cpp
+  ./gui/workerthread.cpp
 )
 
 SET (GUI_UIS
@@ -156,6 +157,7 @@ SET(XTPCPP_MOC_HDRS
   ./gui/protein_list_view/proteintableproxymodel.h
   ./gui/protein_view/proteinwindow.h
   ./gui/waiting_message_dialog/waitingmessagedialog.h
+  ./gui/workerthread.h
 )
 
 
diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp
index b3ccefa3754361698711273ef7a6421498fe193b..9b206119250681af301009be7fe5b7e20930471f 100644
--- a/src/gui/mainwindow.cpp
+++ b/src/gui/mainwindow.cpp
@@ -21,7 +21,6 @@
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and implementation
 ******************************************************************************/
 
-#include <QDockWidget>
 #include <QSettings>
 #include <QFileDialog>
 #include <QMessageBox>
@@ -31,101 +30,11 @@
 
 #include "ui_main.h"
 #include <pappsomspp/pappsoexception.h>
-#include <odsstream/odsdocwriter.h>
 #include <pappsomspp/fasta/fastaoutputstream.h>
-#include "../output/masschroqml.h"
-#include "../output/ods/odsexport.h"
 #include "../utils/utils.h"
+#include "workerthread.h"
 
 
-void XtpLoaderThread::doXpipFileLoad(QString filename) {
-    qDebug() << "XtpLoaderThread::doXpipFileLoad begin "<< filename;
-    try {
-        QFileInfo new_xpip_file;
-        new_xpip_file.setFile(filename);
-        emit loadingMessage(tr("loading XPIP file"));
-
-        XpipFile xpip_file(new_xpip_file);
-        ProjectSp project_sp = xpip_file.getProjectSp();
-
-        emit projectReady(project_sp);
-
-    }
-    catch (pappso::PappsoException & error) {
-        emit projectNotReady(tr("Error while reading XPIP file :\n%1").arg(error.qwhat()));
-    }
-
-    qDebug() << "XtpLoaderThread::doXpipFileLoad end";
-}
-
-
-void XtpLoaderThread::doGrouping(ProjectSp project_sp) {
-    try {
-        emit loadingMessage(tr("grouping proteins"));
-        project_sp.get()->startGrouping();
-        emit loadingMessage(tr("grouping proteins finished"));
-        emit groupingFinished();
-    }
-    catch (pappso::PappsoException & error) {
-        emit operationFailed(tr("Error while grouping :\n%1").arg(error.qwhat()));
-    }
-}
-void XtpLoaderThread::doWritingOdsFile(QString filename, ProjectSp project_sp) {
-
-    try {
-        emit loadingMessage(tr("writing ODS file, please wait"));
-        OdsDocWriter writer(filename);
-        OdsExport export_ods(project_sp.get());
-        export_ods.write(&writer);
-        writer.close();
-        emit operationFinished();
-    }
-    catch (pappso::PappsoException & error) {
-        emit operationFailed(tr("Error while writing ODS file :\n%1").arg(error.qwhat()));
-    }
-}
-
-
-void XtpLoaderThread::doWritingMassChroqFile(QString filename, ProjectSp project_sp) {
-
-    try {
-        emit loadingMessage(tr("writing MassChroqML file, please wait"));
-        MassChroQml output(filename);
-        output.write(project_sp);
-        output.close();
-        emit operationFinished();
-    }
-    catch (pappso::PappsoException & error) {
-        emit operationFailed(tr("Error while writing MassChroqML file :\n%1").arg(error.qwhat()));
-    }
-}
-        
-void XtpLoaderThread::doLoadingResults(bool is_individual, AutomaticFilterParameters param, QStringList file_list) {
-
-    qDebug() << "XtpLoaderThread::doLoadingResults begin ";
-    try {
-        if (file_list.size() == 0) {
-            throw pappso::PappsoException(QObject::tr("file list is empty"));
-        }
-        ProjectSp project_sp = Project().makeProjectSp();
-        project_sp.get()->setCombineMode(!is_individual);
-
-        for (QString filename : file_list) {
-            emit loadingMessage(tr("loading result file %1").arg(filename));
-            project_sp.get()->readResultFile(filename);
-        }
-
-        emit loadingMessage(tr("filtering proteins"));
-        project_sp.get()->updateAutomaticFilters(param);
-        emit projectReady(project_sp);
-
-    }
-    catch (pappso::PappsoException & error) {
-        emit projectNotReady(tr("Error while reading result files :\n%1").arg(error.qwhat()));
-    }
-    qDebug() << "XtpLoaderThread::doLoadingResults end ";
-}
-
 MainWindow::MainWindow(QWidget *parent):
     QMainWindow(parent),
     ui(new Ui::Main)
@@ -133,7 +42,7 @@ MainWindow::MainWindow(QWidget *parent):
     ui->setupUi(this);
     setWindowTitle(QString("%1 %2").arg(SOFTWARE_NAME).arg(XTPCPP_VERSION));
 
-    XtpLoaderThread *worker = new XtpLoaderThread;
+    WorkerThread *worker = new WorkerThread;
     worker->moveToThread(&workerThread);
     /*
     */
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h
index 05ae3339121423ba9ac28428819e52d081e49c67..2c9251a444ba41a8ddd97f3af14acd881cba9ce4 100644
--- a/src/gui/mainwindow.h
+++ b/src/gui/mainwindow.h
@@ -26,7 +26,6 @@
 #define MAINWINDOW_H
 
 #include <QMainWindow>
-#include <QThread>
 #include <QFileInfo>
 #include <QCloseEvent>
 #include <pappsomspp/types.h>
@@ -35,7 +34,6 @@
 #include <pwiz/data/msdata/MSDataFile.hpp>
 #include "../utils/readspectrum.h"
 #include "core/project.h"
-#include "files/xpipfile.h"
 #include "project_view/projectwindow.h"
 #include "load_results_dialog/loadresultsdialog.h"
 #include "export_spreadsheet_dialog/exportspreadsheetdialog.h"
@@ -47,34 +45,6 @@ namespace Ui {
 class Main;
 }
 
-
-class XtpLoaderThread : public QObject
-{
-    Q_OBJECT
-public:
-
-
-protected:
-
-    void closeEvent(QCloseEvent *event);
-
-public slots:
-    void doXpipFileLoad(QString filename);
-    void doLoadingResults(bool is_individual, AutomaticFilterParameters param, QStringList file_list);
-    void doWritingOdsFile(QString filename, ProjectSp project_sp);
-    void doWritingMassChroqFile(QString filename, ProjectSp project_sp);
-    void doGrouping(ProjectSp project_sp);
-
-
-signals:
-    void loadingMessage(QString message);
-    void projectReady(ProjectSp project_sp);
-    void projectNotReady(QString error);
-    void groupingFinished();
-    void operationFinished();
-    void operationFailed(QString error);
-};
-
 class MainWindow: public QMainWindow {
     Q_OBJECT
     QThread workerThread;
diff --git a/src/gui/workerthread.cpp b/src/gui/workerthread.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ec64fb940957a6709d2a465e4423c3654b97c634
--- /dev/null
+++ b/src/gui/workerthread.cpp
@@ -0,0 +1,123 @@
+/**
+ * \file /gui/workerthread.cpp
+ * \date 8/5/2017
+ * \author Olivier Langella
+ * \brief worker thread
+ */
+
+/*******************************************************************************
+* Copyright (c) 2017 Olivier Langella <olivier.langella@u-psud.fr>.
+*
+* This file is part of XTPcpp.
+*
+*     XTPcpp is free software: you can redistribute it and/or modify
+*     it under the terms of the GNU General Public License as published by
+*     the Free Software Foundation, either version 3 of the License, or
+*     (at your option) any later version.
+*
+*     XTPcpp is distributed in the hope that it will be useful,
+*     but WITHOUT ANY WARRANTY; without even the implied warranty of
+*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*     GNU General Public License for more details.
+*
+*     You should have received a copy of the GNU General Public License
+*     along with XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
+*
+* Contributors:
+*     Olivier Langella <olivier.langella@u-psud.fr> - initial API and implementation
+******************************************************************************/
+
+#include "workerthread.h"
+#include <odsstream/odsdocwriter.h>
+#include <pappsomspp/pappsoexception.h>
+#include "../output/masschroqml.h"
+#include "../output/ods/odsexport.h"
+#include "files/xpipfile.h"
+
+void WorkerThread::doXpipFileLoad(QString filename) {
+    qDebug() << "WorkerThread::doXpipFileLoad begin "<< filename;
+    try {
+        QFileInfo new_xpip_file;
+        new_xpip_file.setFile(filename);
+        emit loadingMessage(tr("loading XPIP file"));
+
+        XpipFile xpip_file(new_xpip_file);
+        ProjectSp project_sp = xpip_file.getProjectSp();
+
+        emit projectReady(project_sp);
+
+    }
+    catch (pappso::PappsoException & error) {
+        emit projectNotReady(tr("Error while reading XPIP file :\n%1").arg(error.qwhat()));
+    }
+
+    qDebug() << "WorkerThread::doXpipFileLoad end";
+}
+
+
+void WorkerThread::doGrouping(ProjectSp project_sp) {
+    try {
+        emit loadingMessage(tr("grouping proteins"));
+        project_sp.get()->startGrouping();
+        emit loadingMessage(tr("grouping proteins finished"));
+        emit groupingFinished();
+    }
+    catch (pappso::PappsoException & error) {
+        emit operationFailed(tr("Error while grouping :\n%1").arg(error.qwhat()));
+    }
+}
+void WorkerThread::doWritingOdsFile(QString filename, ProjectSp project_sp) {
+
+    try {
+        emit loadingMessage(tr("writing ODS file, please wait"));
+        OdsDocWriter writer(filename);
+        OdsExport export_ods(project_sp.get());
+        export_ods.write(&writer);
+        writer.close();
+        emit operationFinished();
+    }
+    catch (pappso::PappsoException & error) {
+        emit operationFailed(tr("Error while writing ODS file :\n%1").arg(error.qwhat()));
+    }
+}
+
+
+void WorkerThread::doWritingMassChroqFile(QString filename, ProjectSp project_sp) {
+
+    try {
+        emit loadingMessage(tr("writing MassChroqML file, please wait"));
+        MassChroQml output(filename);
+        output.write(project_sp);
+        output.close();
+        emit operationFinished();
+    }
+    catch (pappso::PappsoException & error) {
+        emit operationFailed(tr("Error while writing MassChroqML file :\n%1").arg(error.qwhat()));
+    }
+}
+        
+void WorkerThread::doLoadingResults(bool is_individual, AutomaticFilterParameters param, QStringList file_list) {
+
+    qDebug() << "WorkerThread::doLoadingResults begin ";
+    try {
+        if (file_list.size() == 0) {
+            throw pappso::PappsoException(QObject::tr("file list is empty"));
+        }
+        ProjectSp project_sp = Project().makeProjectSp();
+        project_sp.get()->setCombineMode(!is_individual);
+
+        for (QString filename : file_list) {
+            emit loadingMessage(tr("loading result file %1").arg(filename));
+            project_sp.get()->readResultFile(filename);
+        }
+
+        emit loadingMessage(tr("filtering proteins"));
+        project_sp.get()->updateAutomaticFilters(param);
+        emit projectReady(project_sp);
+
+    }
+    catch (pappso::PappsoException & error) {
+        emit projectNotReady(tr("Error while reading result files :\n%1").arg(error.qwhat()));
+    }
+    qDebug() << "WorkerThread::doLoadingResults end ";
+}
diff --git a/src/gui/workerthread.h b/src/gui/workerthread.h
new file mode 100644
index 0000000000000000000000000000000000000000..87617697de98d05664e634e03e3dbd1ad031d2a3
--- /dev/null
+++ b/src/gui/workerthread.h
@@ -0,0 +1,65 @@
+/**
+ * \file /gui/workerthread.h
+ * \date 8/5/2017
+ * \author Olivier Langella
+ * \brief worker thread
+ */
+
+/*******************************************************************************
+* Copyright (c) 2017 Olivier Langella <olivier.langella@u-psud.fr>.
+*
+* This file is part of XTPcpp.
+*
+*     XTPcpp is free software: you can redistribute it and/or modify
+*     it under the terms of the GNU General Public License as published by
+*     the Free Software Foundation, either version 3 of the License, or
+*     (at your option) any later version.
+*
+*     XTPcpp is distributed in the hope that it will be useful,
+*     but WITHOUT ANY WARRANTY; without even the implied warranty of
+*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*     GNU General Public License for more details.
+*
+*     You should have received a copy of the GNU General Public License
+*     along with XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
+*
+* Contributors:
+*     Olivier Langella <olivier.langella@u-psud.fr> - initial API and implementation
+******************************************************************************/
+
+#ifndef WORKERTHREAD_H
+#define WORKERTHREAD_H
+
+#include <QThread>
+#include <QCloseEvent>
+#include "../core/automaticfilterparameters.h"
+#include "../core/project.h"
+
+class WorkerThread : public QObject
+{
+    Q_OBJECT
+public:
+
+
+protected:
+
+    void closeEvent(QCloseEvent *event);
+
+public slots:
+    void doXpipFileLoad(QString filename);
+    void doLoadingResults(bool is_individual, AutomaticFilterParameters param, QStringList file_list);
+    void doWritingOdsFile(QString filename, ProjectSp project_sp);
+    void doWritingMassChroqFile(QString filename, ProjectSp project_sp);
+    void doGrouping(ProjectSp project_sp);
+
+
+signals:
+    void loadingMessage(QString message);
+    void projectReady(ProjectSp project_sp);
+    void projectNotReady(QString error);
+    void groupingFinished();
+    void operationFinished();
+    void operationFailed(QString error);
+};
+
+#endif // WORKERTHREAD_H