From 8a796ad01fcd66c8e49760f9660136b3b0f96426 Mon Sep 17 00:00:00 2001
From: Olivier Langella <olivier.langella@u-psud.fr>
Date: Wed, 12 Jun 2019 23:40:12 +0200
Subject: [PATCH] stronger tandem parameter file parser

---
 src/core/tandem_run/tandemparameters.cpp      | 181 +++++++++++++-----
 src/files/tandemparametersfile.cpp            |  33 ++--
 src/files/tandemparametersfile.h              |   5 +-
 .../edittandempresetdialog.cpp                |  24 ++-
 src/input/xtandemparamsaxhandler.cpp          |  71 +++++--
 src/input/xtandemparamsaxhandler.h            |  11 +-
 6 files changed, 238 insertions(+), 87 deletions(-)

diff --git a/src/core/tandem_run/tandemparameters.cpp b/src/core/tandem_run/tandemparameters.cpp
index 0a64767d3..872ebb490 100644
--- a/src/core/tandem_run/tandemparameters.cpp
+++ b/src/core/tandem_run/tandemparameters.cpp
@@ -85,24 +85,32 @@ TandemParameters::equals(const TandemParameters &other) const
 const QString
 TandemParameters::getLabelCategory(const QString &value) const
 {
+
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << value;
   return value.split(", ").at(0);
 }
 const QString &
 TandemParameters::getValue(const QString &label) const
 {
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << label;
   QMap<QString, QString>::const_iterator it = _map_label_value.constFind(label);
   if(it == _map_label_value.end())
     {
       throw pappso::ExceptionNotFound(
-        QObject::tr("X!Tandem preset label %1 not found in method %2")
+        QObject::tr("X!Tandem preset label \"%1\" not found in method \"%2\"")
           .arg(label)
           .arg(_method_name));
     }
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
   return it.value();
 }
 void
 TandemParameters::setParamLabelValue(const QString &label, const QString &value)
 {
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << label;
   // list path
   //<note type="input" label="list path, default
   // parameters">/gorgone/pappso/tmp/temp_condor_job24872841484824316495370334631825647/QExactive_analysis_FDR_nosemi.xml</note>
@@ -112,40 +120,47 @@ TandemParameters::setParamLabelValue(const QString &label, const QString &value)
     {
       return;
     }
-  if(label == "spectrum, path")
-    {
-      return;
-    }
 
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << label;
   if((label == "spectrum, parent monoisotopic mass error units") ||
      (label == "spectrum, fragment monoisotopic mass error units"))
     {
       if((value != "Da") && (value != "Daltons") && (value != "ppm"))
         {
           throw pappso::ExceptionNotPossible(
-            QObject::tr("%1 value must be Daltons or ppm (not %2)")
+            QObject::tr("\"%1\" value must be Daltons or ppm (not \"%2\")")
               .arg(label)
               .arg(value));
         }
     }
-  if((label == "spectrum, parent monoisotopic mass isotope error") ||
-     (label == "spectrum, use neutral loss window") ||
-     (label == "spectrum, use contrast angle") ||
-     (label == "protein, cleavage semi") ||
-     (label == "protein, quick acetyl") ||
-     (label == "protein, quick pyrolidone") || (label == "protein, stP bias") ||
-     (label == "scoring, cyclic permutation") ||
-     (label == "scoring, include reverse") || (label == "scoring, y ions") ||
-     (label == "scoring, b ions") || (label == "scoring, c ions") ||
-     (label == "scoring, z ions") || (label == "scoring, a ions") ||
-     (label == "scoring, x ions") || (label == "refine") ||
-     (label == "refine, use potential modifications for full refinement") ||
-     (label == "refine, cleavage semi") ||
-     (label == "refine, unanticipated cleavage") ||
-     (label == "refine, spectrum synthesis") ||
-     (label == "refine, point mutations") || (label == "output, mzid") ||
-     (label == "output, spectra") ||
-     (label == "spectrum, use noise suppression"))
+  else if((label == "spectrum, parent monoisotopic mass isotope error") ||
+          (label == "spectrum, use neutral loss window") ||
+          (label == "spectrum, use contrast angle") ||
+          (label == "protein, cleavage semi") ||
+          (label == "protein, quick acetyl") ||
+          (label == "protein, quick pyrolidone") ||
+          (label == "protein, stP bias") ||
+          (label == "scoring, cyclic permutation") ||
+          (label == "scoring, include reverse") ||
+          (label == "scoring, y ions") || (label == "scoring, b ions") ||
+          (label == "scoring, c ions") || (label == "scoring, z ions") ||
+          (label == "scoring, a ions") || (label == "scoring, x ions") ||
+          (label == "refine") ||
+          (label ==
+           "refine, use potential modifications for full refinement") ||
+          (label == "refine, cleavage semi") ||
+          (label == "refine, unanticipated cleavage") ||
+          (label == "refine, spectrum synthesis") ||
+          (label == "refine, point mutations") || (label == "output, mzid") ||
+          (label == "output, spectra") || (label == "output, proteins") ||
+          (label == "output, sequences") ||
+          (label == "output, one sequence copy") ||
+          (label == "output, parameters") || (label == "output, performance") ||
+          (label == "output, histograms") ||
+          (label == "output, path hashing") ||
+          (label == "spectrum, use noise suppression")||
+          (label == "spectrum, use noise suppression"))
     {
       if((value != "yes") && (value != "no"))
         {
@@ -154,19 +169,35 @@ TandemParameters::setParamLabelValue(const QString &label, const QString &value)
               .arg(label)
               .arg(value));
         }
+        /*
+ <note label="scoring, algorithm" type="input">k-score</note>
+  <note label="spectrum, use conditioning" type="input">no</note>
+  <note label="scoring, minimum ion count" type="input">1</note>
+*/
+
     }
 
+  else if((label == "spectrum, parent monoisotopic mass error minus") ||
+          (label == "spectrum, parent monoisotopic mass error plus") ||
+          (label == "spectrum, dynamic range") ||
+          (label == "spectrum, minimum parent m+h") ||
+          (label == "protein, cleavage C-terminal mass change") ||
+          (label == "protein, cleavage N-terminal mass change") ||
+          (label == "protein, C-terminal residue modification mass") ||
+          (label == "protein, N-terminal residue modification mass") ||
+          (label == "refine, maximum valid expectation value") ||
+          (label == "spectrum, fragment monoisotopic mass error") ||
+          (label == "spectrum, neutral loss mass") ||
+          (label == "spectrum, neutral loss window") ||
+          (label == "spectrum, minimum fragment mz") ||
+          (label == "output, maximum valid expectation value") ||
+          (label == "output, maximum valid protein expectation value")
+
+
+  )
 
-  if((label == "spectrum, parent monoisotopic mass error minus") ||
-     (label == "spectrum, parent monoisotopic mass error plus") ||
-     (label == "spectrum, dynamic range") ||
-     (label == "spectrum, minimum parent m+h") ||
-     (label == "protein, cleavage C-terminal mass change") ||
-     (label == "protein, cleavage N-terminal mass change") ||
-     (label == "protein, C-terminal residue modification mass") ||
-     (label == "protein, N-terminal residue modification mass") ||
-     (label == "refine, maximum valid expectation value"))
     {
+
       bool ok;
       QString value_bis = value.simplified();
       if(value_bis.isEmpty())
@@ -177,49 +208,105 @@ TandemParameters::setParamLabelValue(const QString &label, const QString &value)
       if(!ok)
         { // not an integer
           throw pappso::ExceptionNotPossible(
-            QObject::tr("%1 value must be a number (not %2)")
+            QObject::tr("\"%1\" value must be a number (not \"%2\")")
               .arg(label)
               .arg(value));
         }
     }
-
-
-  if((label == "spectrum, maximum parent charge") ||
-     (label == "spectrum, total peaks") ||
-     (label == "spectrum, minimum peaks") ||
-     (label == "spectrum, sequence batch size") ||
-     (label == "spectrum, threads") ||
-     (label == "scoring, minimum ion count") ||
-     (label == "scoring, maximum missed cleavage sites"))
+  else if((label == "protein, cleavage site") ||
+          (label == "protein, modified residue mass file") ||
+          (label == "residue, modification mass") ||
+          (label == "residue, modification mass 1") ||
+          (label == "residue, modification mass 2") ||
+          (label == "residue, potential modification mass") ||
+          (label == "residue, potential modification mass 1") ||
+          (label == "residue, potential modification mass 2") ||
+          (label == "residue, potential modification motif") ||
+          (label == "residue, potential modification motif 1") ||
+          (label == "residue, potential modification motif 2") ||
+          (label == "refine, potential N-terminus modifications") ||
+          (label == "refine, potential C-terminus modifications") ||
+          (label == "refine, modification mass") ||
+          (label == "refine, modification mass 1") ||
+          (label == "refine, modification mass 2") ||
+          (label == "refine, potential modification mass") ||
+          (label == "refine, potential modification mass 1") ||
+          (label == "refine, potential modification mass 2") ||
+          (label == "refine, potential modification motif") ||
+          (label == "refine, potential modification motif 1") ||
+          (label == "refine, potential modification motif 2") ||
+          (label == "output, sort results by") ||
+          (label == "output, xsl path")||
+          (label == "spectrum, path"))
+    {
+      // string
+    }
+  else if((label == "spectrum, maximum parent charge") ||
+          (label == "spectrum, total peaks") ||
+          (label == "spectrum, minimum peaks") ||
+          (label == "spectrum, sequence batch size") ||
+          (label == "spectrum, threads") ||
+          (label == "scoring, minimum ion count") ||
+          (label == "scoring, maximum missed cleavage sites")||
+          (label == "output, histogram column width"))
     {
+
       bool ok;
       value.toInt(&ok);
       if(!ok)
         { // not an integer
           throw pappso::ExceptionNotPossible(
-            QObject::tr("%1 value must be an integer (not %2)")
+            QObject::tr("\"%1\" value must be an integer (not \"%2\")")
               .arg(label)
               .arg(value));
         }
     }
-  if(label == "spectrum, fragment mass type")
+  else if(label == "spectrum, fragment mass type")
     {
       if((value != "monoisotopic") && (value != "average"))
         {
           throw pappso::ExceptionNotPossible(
-            QObject::tr("%1 value must be monoisotopic or average (not %2)")
+            QObject::tr(
+              "\"%1\" value must be monoisotopic or average (not \"%2\")")
               .arg(label)
               .arg(value));
         }
     }
+  // tandem input parameter label "output, results" for value "valid" not known.
+
+  else if(label == "output, results")
+    {
+      /*
+    if((value != "all") && (value != "valid"))
+      {
+        throw pappso::ExceptionNotPossible(
+          QObject::tr("\"%1\" value must be valid or all (not \"%2\")")
+            .arg(label)
+            .arg(value));
+      }
+      */
+    }
+  else
+    {
+
+      throw pappso::ExceptionNotPossible(
+        QObject::tr(
+          "tandem input parameter label \"%1\" for value \"%2\" not known.")
+          .arg(label)
+          .arg(value));
+    }
+
 
   // text "protein, cleavage site" "protein, modified residue mass file"
   // "residue, modification mass"  || (label == "refine, potential N-terminus
   // modifications") || (label == "refine, potential C-terminus modifications")
   // spectrum, neutral loss mass
   // spectrum, neutral loss window
-
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << label;
   _map_label_value.insert(label, value);
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << label;
 }
 void
 TandemParameters::setMethodName(const QString &method)
diff --git a/src/files/tandemparametersfile.cpp b/src/files/tandemparametersfile.cpp
index 68c82d692..65545954e 100644
--- a/src/files/tandemparametersfile.cpp
+++ b/src/files/tandemparametersfile.cpp
@@ -39,7 +39,9 @@
 TandemParametersFile::TandemParametersFile(const QString &fasta_source)
   : _param_source(fasta_source)
 {
-  qDebug() << "TandemParametersFile::TandemParametersFile " << fasta_source;
+
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << fasta_source;
 }
 TandemParametersFile::TandemParametersFile(const QFileInfo &fasta_source)
   : _param_source(fasta_source)
@@ -143,17 +145,17 @@ TandemParametersFile::setTandemParameters(const TandemParameters &parameters)
 }
 
 TandemParameters
-TandemParametersFile::getTandemParameters() const
+TandemParametersFile::getTandemParameters()
 {
-  qDebug() << "TandemParametersFile::getTandemParameters begin";
+
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
   TandemParameters parameters;
   XtandemParamSaxHandler *parser = new XtandemParamSaxHandler(&parameters);
 
   QXmlSimpleReader simplereader;
   simplereader.setContentHandler(parser);
   simplereader.setErrorHandler(parser);
-
-  qDebug() << "TandemParametersFile::getTandemParameters '"
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
            << _param_source.absoluteFilePath() << "'";
   parameters.setMethodName(getMethodName());
 
@@ -162,14 +164,18 @@ TandemParametersFile::getTandemParameters() const
 
   if(simplereader.parse(xmlInputSource))
     {
-      qDebug() << "TandemParametersFile::getTandemParameters parse ok";
+      m_isTandemParameterFile = parser->isTandemParameter();
+      qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+               << m_isTandemParameterFile;
+      // parameters.getValue("spectrum, parent monoisotopic mass error units");
+      qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
       qfile.close();
       delete parser;
     }
   else
     {
-
-      qDebug() << "TandemParametersFile::getTandemParameters parse error";
+      qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
+      m_isTandemParameterFile = parser->isTandemParameter();
       qfile.close();
 
       throw pappso::PappsoException(
@@ -182,7 +188,7 @@ TandemParametersFile::getTandemParameters() const
 }
 
 bool
-TandemParametersFile::isTandemPresetFile() const
+TandemParametersFile::isTandemPresetFile()
 {
 
   if(this->exists())
@@ -191,15 +197,20 @@ TandemParametersFile::isTandemPresetFile() const
       try
         {
           TandemParameters param = getTandemParameters();
+
+          if(!m_isTandemParameterFile)
+            return false;
           param.getValue("spectrum, threads");
         }
       catch(pappso::ExceptionNotFound &error)
         {
-          return false;
+          if(!m_isTandemParameterFile)
+            return false;
         }
       catch(pappso::PappsoException &error)
         {
-          return false;
+          if(!m_isTandemParameterFile)
+            return false;
         }
       return true;
     }
diff --git a/src/files/tandemparametersfile.h b/src/files/tandemparametersfile.h
index ae2e2f58f..cdd6e2b1d 100644
--- a/src/files/tandemparametersfile.h
+++ b/src/files/tandemparametersfile.h
@@ -52,11 +52,11 @@ class TandemParametersFile
 
   /** @brief tells if this file is really a tandem preset file
    */
-  bool isTandemPresetFile() const;
+  bool isTandemPresetFile();
 
   /** @brief read tandem parameters from XML file
    */
-  TandemParameters getTandemParameters() const;
+  TandemParameters getTandemParameters();
 
   /** @brief write tandem parameters  to XML file
    */
@@ -72,6 +72,7 @@ class TandemParametersFile
 
   private:
   QFileInfo _param_source;
+  bool m_isTandemParameterFile = false;
 };
 
 #endif // TANDEMPARAMETERSFILE_H
diff --git a/src/gui/edit/edit_tandem_preset_dialog/edittandempresetdialog.cpp b/src/gui/edit/edit_tandem_preset_dialog/edittandempresetdialog.cpp
index e9128c4b9..2f73aa430 100644
--- a/src/gui/edit/edit_tandem_preset_dialog/edittandempresetdialog.cpp
+++ b/src/gui/edit/edit_tandem_preset_dialog/edittandempresetdialog.cpp
@@ -167,6 +167,7 @@ EditTandemPresetDialog::doLoad()
   int index = ui->preset_combo_box->currentIndex();
   if(index != -1)
     { // -1 for not found
+      qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
       TandemParametersFile *p_tandem_preset_file = new TandemParametersFile(
         ui->preset_combo_box->itemData(index).value<QString>());
       if(p_tandem_preset_file->isTandemPresetFile())
@@ -182,8 +183,23 @@ EditTandemPresetDialog::doLoad()
             }
 
           _p_tandem_preset_file = p_tandem_preset_file;
-          _tandem_params        = _p_tandem_preset_file->getTandemParameters();
-          populate();
+          try
+            {
+              qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
+              _tandem_params = _p_tandem_preset_file->getTandemParameters();
+              qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
+              populate();
+            }
+          catch(pappso::PappsoException &error)
+            {
+              qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
+              QMessageBox::warning(
+                this,
+                tr("Error :"),
+                tr("Error reading %1 X!Tandem parameter file:\n %2")
+                  .arg(p_tandem_preset_file->getAbsoluteFilePath())
+                  .arg(error.qwhat()));
+            }
         }
       else
         {
@@ -834,7 +850,7 @@ EditTandemPresetDialog::readUi()
 void
 EditTandemPresetDialog::populate()
 {
-  qDebug() << "EditTandemPresetDialog::populate begin";
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
   try
     {
       ui->method_name_line_edit->setText(_tandem_params.getMethodName());
@@ -1314,7 +1330,7 @@ EditTandemPresetDialog::populate()
     {
       QMessageBox::warning(this, tr("Error in parameters :"), error.qwhat());
     }
-  qDebug() << "EditTandemPresetDialog::populate end";
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
 }
 
 void
diff --git a/src/input/xtandemparamsaxhandler.cpp b/src/input/xtandemparamsaxhandler.cpp
index 08b9feed0..cdbfe4fe8 100644
--- a/src/input/xtandemparamsaxhandler.cpp
+++ b/src/input/xtandemparamsaxhandler.cpp
@@ -48,7 +48,11 @@ XtandemParamSaxHandler::~XtandemParamSaxHandler()
 {
 }
 
-
+bool
+XtandemParamSaxHandler::isTandemParameter() const
+{
+  return m_isTandemParameter;
+}
 bool
 XtandemParamSaxHandler::startElement(const QString &namespaceURI,
                                      const QString &localName,
@@ -67,12 +71,18 @@ XtandemParamSaxHandler::startElement(const QString &namespaceURI,
         {
           if(qName != "bioml")
             {
-              _errorStr =
-                QObject::tr("ERROR in XtandemParamSaxHandler::startElement "
+              _errorStr = QObject::tr(
+                            "ERROR in XtandemParamSaxHandler::startElement "
                             "root tag %1 is not <bioml>")
-                  .arg(qName);
+                            .arg(qName);
+              m_isTandemParameter = false;
               return false;
             }
+          else
+            {
+
+              m_isTandemParameter = true;
+            }
         }
       // startElement_group
 
@@ -84,16 +94,18 @@ XtandemParamSaxHandler::startElement(const QString &namespaceURI,
     }
   catch(pappso::PappsoException exception_pappso)
     {
-      _errorStr = QObject::tr("ERROR in XtandemParamSaxHandler::startElement "
-                              "tag %1, PAPPSO exception:\n%2")
+      _errorStr = QObject::tr(
+                    "ERROR in XtandemParamSaxHandler::startElement "
+                    "tag %1, PAPPSO exception:\n%2")
                     .arg(qName)
                     .arg(exception_pappso.qwhat());
       return false;
     }
   catch(std::exception exception_std)
     {
-      _errorStr = QObject::tr("ERROR in XtandemParamSaxHandler::startElement "
-                              "tag %1, std exception:\n%2")
+      _errorStr = QObject::tr(
+                    "ERROR in XtandemParamSaxHandler::startElement "
+                    "tag %1, std exception:\n%2")
                     .arg(qName)
                     .arg(exception_std.what());
       return false;
@@ -119,16 +131,18 @@ XtandemParamSaxHandler::endElement(const QString &namespaceURI,
     }
   catch(pappso::PappsoException exception_pappso)
     {
-      _errorStr = QObject::tr("ERROR in XtandemParamSaxHandler::endElement tag "
-                              "%1, PAPPSO exception:\n%2")
+      _errorStr = QObject::tr(
+                    "ERROR in XtandemParamSaxHandler::endElement tag "
+                    "%1, PAPPSO exception:\n%2")
                     .arg(qName)
                     .arg(exception_pappso.qwhat());
       return false;
     }
   catch(std::exception exception_std)
     {
-      _errorStr = QObject::tr("ERROR in XtandemParamSaxHandler::endElement tag "
-                              "%1, std exception:\n%2")
+      _errorStr = QObject::tr(
+                    "ERROR in XtandemParamSaxHandler::endElement tag "
+                    "%1, std exception:\n%2")
                     .arg(qName)
                     .arg(exception_std.what());
       return false;
@@ -144,12 +158,14 @@ XtandemParamSaxHandler::endElement(const QString &namespaceURI,
 bool
 XtandemParamSaxHandler::error(const QXmlParseException &exception)
 {
-  _errorStr = QObject::tr("Parse error at line %1, column %2 :\n"
-                          "%3")
+  _errorStr = QObject::tr(
+                "Parse error at line %1, column %2 :\n"
+                "%3")
                 .arg(exception.lineNumber())
                 .arg(exception.columnNumber())
                 .arg(exception.message());
-  qDebug() << "XtandemParamSaxHandler::error " << _errorStr;
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << _errorStr;
   return false;
 }
 
@@ -157,12 +173,14 @@ XtandemParamSaxHandler::error(const QXmlParseException &exception)
 bool
 XtandemParamSaxHandler::fatalError(const QXmlParseException &exception)
 {
-  _errorStr = QObject::tr("Parse error at line %1, column %2 :\n"
-                          "%3")
+  _errorStr = QObject::tr(
+                "Parse error at line %1, column %2 :\n"
+                "%3")
                 .arg(exception.lineNumber())
                 .arg(exception.columnNumber())
                 .arg(exception.message());
-  qDebug() << "XtandemParamSaxHandler::fatalError " << _errorStr;
+  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+           << _errorStr;
   return false;
 }
 
@@ -223,8 +241,21 @@ XtandemParamSaxHandler::endElement_note()
   //    _current_label << " " << _current_text.simplified();
   if(!_current_label.isEmpty())
     {
-      _p_tandem_parameters->setParamLabelValue(_current_label,
-                                               _current_text.simplified());
+      try
+        {
+          _p_tandem_parameters->setParamLabelValue(_current_label,
+                                                   _current_text.simplified());
+        }
+      catch(pappso::PappsoException &exception)
+        {
+          _errorStr =
+            QObject::tr("Error reading tandem input parameter \"%1\" :\n%2")
+              .arg(_current_label)
+              .arg(exception.qwhat());
+          qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
+                   << _errorStr;
+          return false;
+        }
     }
   return true;
 }
diff --git a/src/input/xtandemparamsaxhandler.h b/src/input/xtandemparamsaxhandler.h
index 398f516ca..a15489998 100644
--- a/src/input/xtandemparamsaxhandler.h
+++ b/src/input/xtandemparamsaxhandler.h
@@ -41,10 +41,13 @@ class XtandemParamSaxHandler : public QXmlDefaultHandler
   XtandemParamSaxHandler(TandemParameters *p_tandem_parameters);
   ~XtandemParamSaxHandler();
 
-  bool startElement(const QString &namespaceURI, const QString &localName,
-                    const QString &qName, const QXmlAttributes &attributes);
+  bool startElement(const QString &namespaceURI,
+                    const QString &localName,
+                    const QString &qName,
+                    const QXmlAttributes &attributes);
 
-  bool endElement(const QString &namespaceURI, const QString &localName,
+  bool endElement(const QString &namespaceURI,
+                  const QString &localName,
                   const QString &qName);
 
   bool startDocument();
@@ -58,6 +61,7 @@ class XtandemParamSaxHandler : public QXmlDefaultHandler
 
   QString errorString() const;
 
+  bool isTandemParameter() const;
   private:
   bool startElement_note(QXmlAttributes attributes);
   bool endElement_note();
@@ -70,6 +74,7 @@ class XtandemParamSaxHandler : public QXmlDefaultHandler
   QString _current_text;
 
   QString _current_label;
+  bool m_isTandemParameter = false;
 };
 
 #endif // XTANDEMPARAMSAXHANDLER_H
-- 
GitLab