diff --git a/src/core/identification_sources/identificationdatasource.cpp b/src/core/identification_sources/identificationdatasource.cpp
index 4ae412c977c2f2c588b069903d58410c7318b7d7..dfdfe885dc665934bcdac0242d76ec0033d35857 100644
--- a/src/core/identification_sources/identificationdatasource.cpp
+++ b/src/core/identification_sources/identificationdatasource.cpp
@@ -142,7 +142,7 @@ const QVariant IdentificationDataSource::getIdentificationEngineStatistics(Ident
 }
 
 pappso::SpectrumSp IdentificationDataSource::getSpectrumSp(unsigned int scan_number) const {
-    if (_ms_run_sp.get()->getMzFormat() == MzFormat::MGF) {
+    if (_ms_run_sp.get()->getMzFormat() == pappso::MzFormat::MGF) {
         scan_number = scan_number-1;
     }
     pappso::SpectrumSp spectrum_sp = SpectrumStore::getSpectrumSpFromMsRunSp(_ms_run_sp.get(), scan_number);
diff --git a/src/core/msrun.cpp b/src/core/msrun.cpp
index 79fe42606498632e8fa238189c12aac165f0c6b8..6ff532309cf476e7599a6860e381b6fb031ad092 100644
--- a/src/core/msrun.cpp
+++ b/src/core/msrun.cpp
@@ -32,61 +32,17 @@
 #include "msrun.h"
 #include <QFileInfo>
 
-MsRun::MsRun(const QString & location) {
-    _xml_id = location;
-    _location = location;
+MsRun::MsRun(const QString & location):pappso::MsRunId(location) {
     QFileInfo fileinfo(location);
-    _name = fileinfo.baseName();
 }
 
-MsRun::MsRun(const MsRun& other) {
-    _xml_id = other._xml_id;
-    _location = other._location;
-    _name = other._name;
-    _mz_format=other._mz_format;
+MsRun::MsRun(const MsRun& other):pappso::MsRunId(other) {
     _param_stats = other._param_stats;
 }
 
 MsRun::~MsRun() {
 }
 
-
-void MsRun::setSampleName(const QString & name) {
-    _name = name;
-}
-const QString & MsRun::getSampleName() const {
-    return _name;
-}
-
-void MsRun::setFilename(const QString filename) {
-    _location = filename;
-    QFileInfo file_info(filename);
-    QString extension = file_info.suffix();
-    _mz_format = MzFormat::unknown;
-    if (extension.toLower() == "mzxml") {
-        _mz_format = MzFormat::mzXML;
-    }
-    else if (extension.toLower() == "mgf") {
-        _mz_format = MzFormat::MGF;
-    }
-    else if (extension.toLower() == "mzml") {
-        _mz_format = MzFormat::mzML;
-    }
-}
-void MsRun::setXmlId(const QString xmlid) {
-    _xml_id = xmlid;
-}
-const QString & MsRun::getXmlId() const {
-    return _xml_id;
-}
-const QString & MsRun::getFilename() const {
-    return _location;
-}
-
-MzFormat MsRun::getMzFormat() const {
-    return _mz_format;
-}
-
 void MsRun::setMsRunStatistics(MsRunStatistics param, const QVariant& value) {
     _param_stats.insert(std::pair<MsRunStatistics, QVariant>(param, value));
 }
@@ -103,9 +59,3 @@ const QVariant MsRun::getMsRunStatistics(MsRunStatistics param) const {
         return QVariant();
     }
 }
-
-/*
-void MsRun::setMzFormat(MzFormat mz_format) {
-    _mz_format = mz_format;
-}
-*/
diff --git a/src/core/msrun.h b/src/core/msrun.h
index e56bbc469104b035df43c396496cc2870be8b2fb..f6429edb0d873bf3ac99551d5bbeb4b4661a17b3 100644
--- a/src/core/msrun.h
+++ b/src/core/msrun.h
@@ -35,29 +35,19 @@
 #include <memory>
 #include <QString>
 #include <QVariant>
+#include <pappsomspp/msrun/msrunid.h>
 #include "../utils/types.h"
 
 class MsRun;
 typedef std::shared_ptr<MsRun> MsRunSp;
 
-class MsRun
+class MsRun:public pappso::MsRunId
 {
 public:
     MsRun(const QString & location);
     MsRun(const MsRun& other);
     ~MsRun();
     
-    void setFilename(const QString filename);
-    void setSampleName(const QString & name);
-    void setXmlId(const QString xmlid);
-    
-    const QString & getFilename() const;
-    const QString & getSampleName() const;
-    const QString & getXmlId() const;
-    
-    MzFormat getMzFormat() const;
-    //void setMzFormat(MzFormat mz_format);
-    
            
     /** \brief set MS run statistics
      * any statistics on this MS run file
@@ -74,10 +64,6 @@ public:
     virtual const std::map<MsRunStatistics, QVariant> & getMsRunStatisticsMap() const;
 
 private :
-    QString _xml_id;
-    QString _location;
-    QString _name;
-    MzFormat _mz_format=MzFormat::mzXML;
     std::map<MsRunStatistics, QVariant> _param_stats;
 };
 
diff --git a/src/gui/xic_view/xic_box/xicbox.cpp b/src/gui/xic_view/xic_box/xicbox.cpp
index 2dbb525125c085525333ad79ff456d863dde29bb..8180f0dd80cf424b47fa43dc1bd064527bc7596e 100644
--- a/src/gui/xic_view/xic_box/xicbox.cpp
+++ b/src/gui/xic_view/xic_box/xicbox.cpp
@@ -230,7 +230,7 @@ void XicBox::setPeptideEvidenceInMsRun(const PeptideEvidence * p_peptide_evidenc
 
 }
 
-void XicBox::setXic(std::vector< pappso::XicSp> xic_sp_list) {
+void XicBox::setXic(std::vector< pappso::MsRunXicSp> xic_sp_list) {
     qDebug() << "XicBox::setXic begin " << xic_sp_list.size();
     ui->xic_widget->clear();
     for (int i=0; i < xic_sp_list.size(); i++) {
@@ -361,7 +361,7 @@ void XicBox::setIsotopeMassList(std::vector<pappso::PeptideNaturalIsotopeAverage
         _natural_isotope_list.push_back({nullptr, natural_isotope_average, nullptr, nullptr});
     }
 
-    emit loadXic(_msrun_sp, mass_list, _p_xic_window->getXicExtractPrecision(), XicExtractMethod::max);
+    emit loadXic(_msrun_sp, mass_list, _p_xic_window->getXicExtractPrecision(), pappso::XicExtractMethod::max);
 
     //histogram
     QCPBars * theoretical_ratio = new QCPBars(ui->histo_widget->xAxis, ui->histo_widget->yAxis);
@@ -417,7 +417,7 @@ void XicBox::reExtractXic() {
     for (const XicBoxNaturalIsotope & xic_isotope: _natural_isotope_list) {
         mass_list.push_back(xic_isotope.peptide_natural_isotope_sp.get()->getMz());
     }
-    emit loadXic(_msrun_sp, mass_list, _p_xic_window->getXicExtractPrecision(), XicExtractMethod::max);
+    emit loadXic(_msrun_sp, mass_list, _p_xic_window->getXicExtractPrecision(), pappso::XicExtractMethod::max);
     qDebug() << "XicBox::reExtractXic end";
 }
 
diff --git a/src/gui/xic_view/xic_box/xicbox.h b/src/gui/xic_view/xic_box/xicbox.h
index 91eac5074d1624a045ad8997c792f620cf7cfa27..f16ed3333459dd7092c8fc9fbd37cf9495c6fe37 100644
--- a/src/gui/xic_view/xic_box/xicbox.h
+++ b/src/gui/xic_view/xic_box/xicbox.h
@@ -35,7 +35,7 @@
 #include "../../../utils/types.h"
 #include "../../../core/peptideevidence.h"
 #include "../xicwindow.h"
-#include <pappsomspp/xic/xic.h>
+#include <pappsomspp/xicextractor/msrunxic.h>
 #include <pappsomspp/peptide/peptidenaturalisotopelist.h>
 #include <qcustomplot.h>
 
@@ -66,12 +66,12 @@ public:
     void setPeptideEvidenceInMsRun(const PeptideEvidence * p_peptide_evidence, MsRunSp msrun_sp);
     
 signals :
-    void loadXic(MsRunSp p_msrun, std::vector<pappso::mz> mz_list, pappso::PrecisionP precision, XicExtractMethod method);
+    void loadXic(MsRunSp p_msrun, std::vector<pappso::mz> mz_list, pappso::PrecisionP precision, pappso::XicExtractMethod method);
     void computeIsotopeMassList(pappso::PeptideSp peptide_sp, unsigned int charge, pappso::PrecisionP precision, double minimum_isotope_pattern_ratio);
 private slots:
     void remove();
     void reExtractXic();
-    void setXic(std::vector< pappso::XicSp> xic_sp_list);
+    void setXic(std::vector< pappso::MsRunXicSp> xic_sp_list);
     void setIsotopeMassList(std::vector<pappso::PeptideNaturalIsotopeAverageSp> isotope_mass_list);
     void error(QString error_message);
     void extractXicInOtherMsRun();
diff --git a/src/gui/xic_view/xicworkerthread.cpp b/src/gui/xic_view/xicworkerthread.cpp
index 32ac2202fc18c53292b1bd676c532cadf0c6d0cf..db6b3593ed33f3890b9cd1d84a8f585b5cad5835 100644
--- a/src/gui/xic_view/xicworkerthread.cpp
+++ b/src/gui/xic_view/xicworkerthread.cpp
@@ -32,14 +32,14 @@
 #include <pappsomspp/peptide/peptidenaturalisotopelist.h>
 #include <pappsomspp/pappsoexception.h>
 
-void XicWorkerThread::doXicLoad(MsRunSp p_msrun, std::vector<pappso::mz> mz_list, pappso::PrecisionP precision, XicExtractMethod method) {
+void XicWorkerThread::doXicLoad(MsRunSp p_msrun, std::vector<pappso::mz> mz_list, pappso::PrecisionP precision, pappso::XicExtractMethod method) {
 
     try {
         std::vector<pappso::MassRange> mass_list;
         for (pappso::mz mass:mz_list) {
             mass_list.push_back(pappso::MassRange(mass, precision));
         }
-        std::vector<pappso::XicSp> xic_sp_list = SpectrumStore::getXicSpFromMsRunSp(p_msrun.get(), mass_list, method);
+        std::vector<pappso::MsRunXicSp> xic_sp_list = SpectrumStore::getXicSpFromMsRunSp(p_msrun.get(), mass_list, method);
 
         emit xicLoaded(xic_sp_list);
 
diff --git a/src/gui/xic_view/xicworkerthread.h b/src/gui/xic_view/xicworkerthread.h
index 6d4c294af67b886880e61b2860d3ecf7010c0f70..cdc6e7fa67250f45ef007bc9145e5a7c898143a0 100644
--- a/src/gui/xic_view/xicworkerthread.h
+++ b/src/gui/xic_view/xicworkerthread.h
@@ -29,7 +29,7 @@
 #ifndef XICWORKERTHREAD_H
 #define XICWORKERTHREAD_H
 
-#include <pappsomspp/xic/xic.h>
+#include <pappsomspp/xicextractor/msrunxic.h>
 #include <pappsomspp/peptide/peptidenaturalisotopelist.h>
 #include<QObject>
 #include "../../core/msrun.h"
@@ -40,11 +40,11 @@ class XicWorkerThread : public QObject
 public:
 
 public slots:
-    void doXicLoad(MsRunSp p_msrun, std::vector<pappso::mz> mz_list, pappso::PrecisionP precision, XicExtractMethod method);
+    void doXicLoad(MsRunSp p_msrun, std::vector<pappso::mz> mz_list, pappso::PrecisionP precision, pappso::XicExtractMethod method);
     void doComputeIsotopeMassList(pappso::PeptideSp peptide_sp, unsigned int charge, pappso::PrecisionP precision, double minimum_isotope_pattern_ratio);
 
 signals:
-    void xicLoaded(std::vector<pappso::XicSp> xic_sp_list);
+    void xicLoaded(std::vector<pappso::MsRunXicSp> xic_sp_list);
     void isotopeMassListComputed(std::vector<pappso::PeptideNaturalIsotopeAverageSp> isotope_mass_list);
     void operationFailed(QString error);
 
diff --git a/src/main.cpp b/src/main.cpp
index 0ccd5ce684417962e06ec7601c8ff5bb283099fa..52d22fccefc4e6ceb857a5d604fd08447beea983 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -39,9 +39,9 @@ int main(int argc, char *argv[])
     qRegisterMetaType<TandemRunBatch>("TandemRunBatch");
     qRegisterMetaType<std::vector<pappso::mz>>("std::vector<pappso::mz>");
     qRegisterMetaType<pappso::PrecisionP>("pappso::PrecisionP");
-    qRegisterMetaType<std::vector<pappso::XicSp>>("std::vector<pappso::XicSp>");
+    qRegisterMetaType<std::vector<pappso::MsRunXicSp>>("std::vector<pappso::MsRunXicSp>");
     qRegisterMetaType<pappso::PeptideSp>("pappso::PeptideSp");
-    qRegisterMetaType<XicExtractMethod>("XicExtractMethod");
+    qRegisterMetaType<pappso::XicExtractMethod>("pappso::XicExtractMethod");
     qRegisterMetaType<pappso::SpectrumSp>("pappso::SpectrumSp");
     qRegisterMetaType<MsRunSp>("MsRunSp");
     qRegisterMetaType<std::vector<pappso::PeptideNaturalIsotopeAverageSp>>("std::vector<pappso::PeptideNaturalIsotopeAverageSp>");
diff --git a/src/output/masschroqml.cpp b/src/output/masschroqml.cpp
index a5a4e3f50880da8e87ef02e925a9c59bb99515aa..ac070fda9462a5900bf871aadee98891cdc59fad 100644
--- a/src/output/masschroqml.cpp
+++ b/src/output/masschroqml.cpp
@@ -126,7 +126,7 @@ void MassChroQml::write(ProjectSp sp_project) {
         //<data_file id="samp0" format="mzxml" path="bsa1.mzXML" type="centroid" />
         _output_stream->writeStartElement("data_file");
         _output_stream->writeAttribute("id",msrun.get()->getXmlId());
-        if(msrun.get()->getMzFormat() == MzFormat::mzXML) {
+        if(msrun.get()->getMzFormat() == pappso::MzFormat::mzXML) {
             _output_stream->writeAttribute("format","mzxml");
         }
         _output_stream->writeAttribute("path",msrun.get()->getFilename());
diff --git a/src/utils/readspectrum.cpp b/src/utils/readspectrum.cpp
index 0bc49b518a4ba74666e5b3e21e1e727c5eb69435..6c8e03314676ef1bb8fd879f6d4abaeb6f76ebf4 100644
--- a/src/utils/readspectrum.cpp
+++ b/src/utils/readspectrum.cpp
@@ -30,6 +30,7 @@
 #include <QString>
 #include <pappsomspp/spectrum/spectrum.h>
 #include <pappsomspp/exception/exceptionnotfound.h>
+#include <pappsomspp/xicextractor/msrunxicextractorfactory.h>
 
 #include <pwiz/data/common/cv.hpp>
 #include <pwiz_tools/common/FullReaderList.hpp>
@@ -78,85 +79,6 @@ pwiz::msdata::MSDataFile * getPwizMSDataFile(const QString & filename) {
     return dataFile;
 }
 
-void getXicFromPwizMSDataFile(pwiz::msdata::MSDataFile * p_ms_data_file, std::vector< pappso::Xic> & xic_list, const std::vector<pappso::MassRange> & mass_range_list,  XicExtractMethod method) {
-    qDebug() << "getXicFromPwizMSDataFile begin mass_range_list.size()=" << mass_range_list.size() << " xic_list.size()=" << xic_list.size();
-    std::string env;
-    env=setlocale(LC_ALL,"");
-    setlocale(LC_ALL,"C");
-
-
-
-
-    const pwiz::msdata::SpectrumList * p_spectrum_list = p_ms_data_file->run.spectrumListPtr.get();
-    std::size_t spectrum_list_size = p_spectrum_list->size();
-    pwiz::msdata::SpectrumPtr spectrum;
-
-    std::vector<XicElement> peak_for_mass;
-    for (const pappso::MassRange & mass_range: mass_range_list) {
-        peak_for_mass.push_back(XicElement());
-        qDebug() << "getXicFromPwizMSDataFile begin mass_range=" << mass_range.getMz();
-    }
-
-    bool ms1 = false;
-
-    for (std::size_t i=0; i < spectrum_list_size; i++) {
-        spectrum = p_spectrum_list->spectrum(i, false);
-        unsigned int ms_level(QString(spectrum->cvParam(pwiz::msdata::MS_ms_level).value.c_str()).toUInt());
-//qDebug() << "getXicFromPwizMSDataFile ms_level" << ms_level;
-        if (ms_level == 1) {
-            ms1 = true;
-            spectrum = p_spectrum_list->spectrum(i, true);
-            for (XicElement & peak: peak_for_mass) {
-                peak.rt = QString(spectrum->scanList.scans[0].cvParam(pwiz::msdata::MS_scan_start_time).value.c_str()).toDouble();
-                peak.intensity = 0;
-            }
-
-            vector<pwiz::msdata::MZIntensityPair> pairs;
-            spectrum->getMZIntensityPairs(pairs);
-
-            // iterate through the m/z-intensity pairs
-            for (vector<pwiz::msdata::MZIntensityPair>::const_iterator it=pairs.begin(), end=pairs.end(); it!=end; ++it)
-            {
-                //qDebug() << "getXicFromPwizMSDataFile it->mz " << it->mz << " it->intensity" << it->intensity;
-                for (int i=0; i < mass_range_list.size(); i++) {
-                    if (mass_range_list[i].contains(it->mz)) {
-                        if (method == XicExtractMethod::max) {
-                            if (peak_for_mass[i].intensity < it->intensity) {
-                                peak_for_mass[i].intensity = it->intensity;
-                            }
-                        }
-                        else {
-                            peak_for_mass[i].intensity += it->intensity;
-                        }
-                    }
-                }
-            }
-
-            for (int i=0; i < mass_range_list.size(); i++) {
-                //qDebug() << "getXicFromPwizMSDataFile push_back " << peak_for_mass[i].rt;
-                xic_list[i].push_back(peak_for_mass[i]);
-            }
-        }
-
-    }
-
-
-    if (ms1 == false) {
-        throw pappso::PappsoException(QObject::tr("error extracting XIC: no MS level 1 in data file"));
-    }
-
-    for (int i=0; i < xic_list.size(); i++) {
-        xic_list[i] .sortByRetentionTime();
-
-        //qDebug() << "getXicFromPwizMSDataFile end " << xic_list[i].size();
-    }
-    qDebug() << "getXicFromPwizMSDataFile end";
-
-
-    setlocale(LC_ALL,env.c_str());
-
-}
-
 pappso::QualifiedSpectrum getQualifiedSpectrumFromPwizMSDataFile(pwiz::msdata::MSDataFile * p_ms_data_file, unsigned int scan_num) {
     unsigned int precursor_charge_state=0;
 
@@ -394,7 +316,7 @@ pappso::SpectrumSp SpectrumStore::getSpectrumSpFromMsRunSp(MsRun * msrun, unsign
         return spectrum.getOriginalSpectrumSp();
     }
     spectrum = getQualifiedSpectrumFromPwizMSDataFile(p_msdatafile, scan_num);
-    if (msrun->getMzFormat() == MzFormat::MGF) {
+    if (msrun->getMzFormat() == pappso::MzFormat::MGF) {
         if (spectrum.getRtInSeconds() == 0) {
             spectrum = getQualifiedSpectrumFromPwizMSDataFile(p_msdatafile, scan_num-1);
         }
@@ -403,25 +325,21 @@ pappso::SpectrumSp SpectrumStore::getSpectrumSpFromMsRunSp(MsRun * msrun, unsign
 
 }
 
-std::vector<pappso::XicSp> SpectrumStore::getXicSpFromMsRunSp(MsRun * p_msrun, const std::vector<pappso::MassRange> & mass_range_list, XicExtractMethod method) {
+std::vector<pappso::MsRunXicSp> SpectrumStore::getXicSpFromMsRunSp(MsRun * p_msrun, const std::vector<pappso::MassRange> & mass_range_list, pappso::XicExtractMethod method) {
     qDebug() << "SpectrumStore::getXicSpFromMsRunSp begin" ;
-    std::vector<pappso::XicSp> xic_sp_list;
+    std::vector<pappso::MsRunXicSp> xic_sp_list;
     if (p_msrun == nullptr) {
         qDebug() << "SpectrumStore::getXicSpFromMsRunSp ERROR p_msrun == nullptr " ;
         throw pappso::ExceptionNotFound(QObject::tr("SpectrumStore::getXicSpFromMsRunSp ERROR p_msrun == nullptr"));
         //return spectrum;
     }
+    
     pwiz::msdata::MSDataFile * p_msdatafile = findPwizMSDataFile(p_msrun);
 
     if (p_msdatafile != nullptr) {
-        std::vector<Xic> xic_list;
-        xic_list.resize(mass_range_list.size());
-        getXicFromPwizMSDataFile(p_msdatafile, xic_list, mass_range_list, method);
-
-        for (const Xic & xic:xic_list) {
-            xic_sp_list.push_back( xic.makeXicSp());
-        }
-        //qDebug() << "SpectrumStore::getXicSpFromMsRunSp end"  <<  xic_sp.get()->size();
+        pappso::MsRunXicExtractorSp extractor = pappso::MsRunXicExtractorFactory::getInstance().buildMsRunXicExtractorPwizSp(*p_msrun);
+        extractor->setXicExtractMethod(method);
+        return extractor.get()->getMsRunXicSpList(mass_range_list);
     }
     return (xic_sp_list);
 }
diff --git a/src/utils/readspectrum.h b/src/utils/readspectrum.h
index 84c1752c0ac7d43691605386edc3f365a9e786b3..3680a07296651fef852b63025260e175404a0558 100644
--- a/src/utils/readspectrum.h
+++ b/src/utils/readspectrum.h
@@ -26,7 +26,7 @@
 
 #include <QString>
 #include <pappsomspp/spectrum/qualifiedspectrum.h>
-#include <pappsomspp/xic/xic.h>
+#include <pappsomspp/xicextractor/msrunxic.h>
 #include <map>
 #include "../core/msrun.h"
 
@@ -43,7 +43,7 @@ class MSDataFile;
 class SpectrumStore {
 public:
     static pappso::SpectrumSp getSpectrumSpFromMsRunSp(MsRun * p_msrun, unsigned int scan_num);
-    static std::vector<pappso::XicSp> getXicSpFromMsRunSp(MsRun * p_msrun, const std::vector<pappso::MassRange> & mass_range_list, XicExtractMethod method);
+    static std::vector<pappso::MsRunXicSp> getXicSpFromMsRunSp(MsRun * p_msrun, const std::vector<pappso::MassRange> & mass_range_list, pappso::XicExtractMethod method);
     /** @brief try to find MS run statistics
      */
     static void checkMsRunStatistics(MsRun *);
diff --git a/src/utils/types.h b/src/utils/types.h
index a4c17d75f6525632e0a6b8eb3ff5491958e2f0c5..0809820b3e497bb4468fe6e44480f8bea351187d 100644
--- a/src/utils/types.h
+++ b/src/utils/types.h
@@ -91,15 +91,6 @@ enum class MsRunStatistics: std::int8_t {
 
 
 
-/** \def XixExtactMethod method to extract Xic
- *
- */
-enum class XicExtractMethod: std::int8_t {
-    sum=1, ///< sum of intensities
-    max=2 ///< maximum of intensities
-};
-
-
 /** \def ProjectMode separate each samples or combine all
  *
  */
@@ -119,17 +110,6 @@ enum class GroupingType {
 };
 
 
-/** \def MzFormat mz data file format types
- *
- */
-
-enum class MzFormat: std::int8_t {
-    unknown=0, ///< unknown format
-    mzML=1, ///< mzML
-    mzXML=2, ///< mzXML
-    MGF=3, ///< Mascot format
-};
-
 /** \def ValidationState
  *
  */