Logo Search packages:      
Sourcecode: massxpert version File versions

massSearchDlg.cpp

/* massXpert - the true massist's program.
   --------------------------------------
   Copyright(C) 2006,2007 Filippo Rusconi

   http://www.massxpert.org/massXpert

   This file is part of the massXpert project.

   The massxpert project is the successor to the "GNU polyxmass"
   project that is an official GNU project package(see
   www.gnu.org). The massXpert project is not endorsed by the GNU
   project, although it is released ---in its entirety--- under the
   GNU General Public License. A huge part of the code in massXpert
   is actually a C++ rewrite of code in GNU polyxmass. As such
   massXpert was started at the Centre National de la Recherche
   Scientifique(FRANCE), that granted me the formal authorization to
   publish it under this Free Software License.

   This software is free software; you can redistribute it and/or
   modify it under the terms of the GNU  General Public
   License version 3, as published by the Free Software Foundation.
   

   This software 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 this software; if not, write to the

   Free Software Foundation, Inc.,

   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/


/////////////////////// Qt includes
#include <QMessageBox>


/////////////////////// Local includes
#include "massSearchDlg.hpp"
#include "application.hpp"


namespace massXpert
{

  MassSearchDlg::MassSearchDlg(QWidget *parent,
                        Polymer *polymer,
                        const CalcOptions &calcOptions,
                        IonizeRule *ionizeRule)
    : QDialog(parent),
      mp_polymer(polymer), 
      m_calcOptions(calcOptions),
      mp_ionizeRule(ionizeRule)
  {
    Q_ASSERT(parent);
    Q_ASSERT(mp_polymer && mp_ionizeRule);
  
    m_ui.setupUi(this);
  
    mp_editorWnd = static_cast<SequenceEditorWnd *>(parent);
  
    updateSelectionData();
    if (m_calcOptions.coordinateList().size() > 1)
      m_ui.currentSelectionRadioButton->setChecked(true);


    m_monoTolerance = 0;
    m_avgTolerance = 0;
  
    m_ionizeStart = 0;
    m_ionizeEnd  = 0;
  
    m_currentMass = 0;
    m_foundOligosCount = 0;

    m_abort = false;
    m_sequenceEmbedded = false;

    populateToleranceTypeComboBoxes();
  
    setupTreeViews();
  
    m_ui.ionizationStartSpinBox->setRange(-1000000000, 1000000000);
    m_ui.ionizationStartSpinBox->setValue(1);
  
    m_ui.ionizationEndSpinBox->setRange(-1000000000, 1000000000);
    m_ui.ionizationEndSpinBox->setValue(1);

    m_ui.massSearchProgressBar->setRange(0, 100);
    m_ui.massSearchProgressBar->setValue(0);
  
    m_ui.avgToleranceComboBox->setToolTip(tr("AMU: atom mass unit \n"
                                     "PCT: percent \n"
                                     "PPM: part per million"));
    m_ui.monoToleranceComboBox->setToolTip(tr("AMU: atom mass unit \n"
                                    "PCT: percent \n"
                                    "PPM: part per million"));
  
    m_ui.monoMassLineEdit->setText("1");
    m_ui.avgMassLineEdit->setText("1");


    // The tolerance when filtering mono/avg masses...
    QStringList stringList;
  
    stringList << tr("AMU") << tr("PCT") << tr("PPM");
  
    m_ui.monoFilterToleranceComboBox->insertItems(0, stringList);
  
    m_ui.monoFilterToleranceComboBox->setToolTip(tr("AMU: atom mass unit \n"
                                          "PCT: percent \n"
                                          "PPM: part per million"));
  
    m_ui.avgFilterToleranceComboBox->insertItems(0, stringList);
  
    m_ui.avgFilterToleranceComboBox->setToolTip(tr("AMU: atom mass unit \n"
                                         "PCT: percent \n"
                                         "PPM: part per million"));

    m_ui.monoFilterToleranceLineEdit->setText("1");
    m_ui.avgFilterToleranceLineEdit->setText("1");
  
    monoFilterAct = new QAction(tr("Toggle Mono Filtering"), this);
    monoFilterAct->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_M, Qt::Key_F));
    this->addAction(monoFilterAct);
    connect(monoFilterAct, 
           SIGNAL(triggered()), 
           this, 
           SLOT(monoFilterOptionsToggled()));

    m_ui.monoFilteringOptionsGroupBox->addAction(monoFilterAct);

    avgFilterAct = new QAction(tr("Toggle Avg Filtering"), this);
    avgFilterAct->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_A, Qt::Key_F));
    this->addAction(avgFilterAct);
    connect(avgFilterAct, 
           SIGNAL(triggered()), 
           this, 
           SLOT(avgFilterOptionsToggled()));

    m_ui.avgFilteringOptionsGroupBox->addAction(avgFilterAct);

    // When the dialog box is created it is created with the groupbox
    // unchecked.
    m_ui.monoFilteringOptionsFrame->setVisible(false);
    m_ui.avgFilteringOptionsFrame->setVisible(false);

    // When the filtering group box will be opened, the focus will be on
    // the first widget of the groupbox:
    mp_monoFocusWidget = m_ui.monoFilterSearchedLineEdit;
    mp_avgFocusWidget = m_ui.avgFilterSearchedLineEdit;



    // The results-exporting menus. ////////////////////////////////

    QStringList comboBoxItemList;

    comboBoxItemList 
      << tr("To Clipboard") 
      << tr("To File")
      << tr("Select File");
  
    m_ui.exportResultsComboBox->addItems(comboBoxItemList);
  
    connect(m_ui.exportResultsComboBox,
           SIGNAL(activated(int)),
           this,
           SLOT(exportResults(int)));

    mpa_resultsString = new QString();
  
    //////////////////////////////////// The results-exporting menus.
  

    QSettings settings 
     (static_cast<Application *>(qApp)->configSettingsFilePath(), 
       QSettings::IniFormat);
  
    settings.beginGroup("mass_search_dlg");

    restoreGeometry(settings.value("geometry").toByteArray());

    m_ui.oligomersSplitter->
      restoreState(settings.value("oligomersSplitter").toByteArray());
  
    m_ui.oligoDetailsSplitter->
      restoreState(settings.value("oligoDetailsSplitter").toByteArray());
  
    m_ui.oligoDetailsSplitter->
      restoreState(settings.value("treeviewsSplitter").toByteArray());
  
    settings.endGroup();


    connect(m_ui.searchPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(search()));

    connect(m_ui.abortPushButton, 
           SIGNAL(clicked()),
           this, 
           SLOT(abort()));

    connect(m_ui.updateCurrentSelectionDataPushButton,
           SIGNAL(clicked()),
           this,
           SLOT(updateSelectionData()));


    // MONO set of filtering widgets
    connect(m_ui.monoFilterSearchedLineEdit,
           SIGNAL(returnPressed()),
           this,
           SLOT(monoFilterSearched()));
  
    connect(m_ui.monoFilterErrorLineEdit,
           SIGNAL(returnPressed()),
           this,
           SLOT(monoFilterError()));

    connect(m_ui.monoFilterMonoMassLineEdit,
           SIGNAL(returnPressed()),
           this,
           SLOT(monoFilterMonoMass()));
  
    connect(m_ui.monoFilterAvgMassLineEdit,
           SIGNAL(returnPressed()),
           this,
           SLOT(monoFilterAvgMass()));
  
    connect(m_ui.monoFilteringOptionsGroupBox,
           SIGNAL(clicked(bool)),
           this,
           SLOT(monoFilterOptions(bool)));

    // AVG set of filtering widgets
    connect(m_ui.avgFilterSearchedLineEdit,
           SIGNAL(returnPressed()),
           this,
           SLOT(avgFilterSearched()));
  
    connect(m_ui.avgFilterErrorLineEdit,
           SIGNAL(returnPressed()),
           this,
           SLOT(avgFilterError()));

    connect(m_ui.avgFilterMonoMassLineEdit,
           SIGNAL(returnPressed()),
           this,
           SLOT(avgFilterMonoMass()));
  
    connect(m_ui.avgFilterAvgMassLineEdit,
           SIGNAL(returnPressed()),
           this,
           SLOT(avgFilterAvgMass()));
  
    connect(m_ui.avgFilteringOptionsGroupBox,
           SIGNAL(clicked(bool)),
           this,
           SLOT(avgFilterOptions(bool)));
  }


  MassSearchDlg::~MassSearchDlg()
  {
    delete mpa_resultsString;
  
    delete mpa_monoOligomerTreeViewModel;
  
    delete mpa_monoProxyModel;

    delete mpa_avgOligomerTreeViewModel;
  
    delete mpa_avgProxyModel;

    freeAllOligomerLists();
  }


  void 
  MassSearchDlg::closeEvent(QCloseEvent *event)
  {
    if (event)
      printf("%s", "");
  
    QSettings settings 
     (static_cast<Application *>(qApp)->configSettingsFilePath(), 
       QSettings::IniFormat);
  
    settings.beginGroup("mass_search_dlg");

    settings.setValue("geometry", saveGeometry());

    settings.setValue("oligomersSplitter", 
                   m_ui.oligomersSplitter->saveState());

    settings.setValue("oligoDetailsSplitter", 
                   m_ui.oligoDetailsSplitter->saveState());

    settings.setValue("treeviewsSplitter", 
                   m_ui.oligoDetailsSplitter->saveState());

    settings.endGroup();
  }


  SequenceEditorWnd *
  MassSearchDlg::editorWnd()
  {
    return mp_editorWnd;
  }


  bool
  MassSearchDlg::populateToleranceTypeComboBoxes()
  {
    QStringList stringList;
  
    stringList << tr("AMU") << tr("PCT") << tr("PPM");
  
    m_ui.monoToleranceComboBox->insertItems(0, stringList);
    m_ui.avgToleranceComboBox->insertItems(0, stringList);
  
    return true;
  }


  bool 
  MassSearchDlg::updateSelectionData()
  {
    // There might be more than one region selections. So get all
    // these coordinates !
      
    CoordinateList coordList;

    bool res = mp_editorWnd->mpa_editorGraphicsView->
      selectionIndices(&coordList);

    if (res)
      {
      // If there are more than one region selection or if there is
      // one region selection but spanning more than one monomer,
      // then set the target to be "current selected sequence".
      
      if(coordList.size() > 1)
        {
          // Apparently there are multiple regions selected.
          
          m_ui.currentSelectionLineEdit->
            setText(coordList.positionsAsText());

          m_calcOptions.setCoordinateList(coordList);
        }
      else
        {
          Coordinates *coordinates = coordList.first();
          
          if (coordinates->start() == coordinates->end())
            {
            // Construct a string with both the monomer code and
            // its position in the sequence.

            Polymer *polymer = mp_editorWnd->polymer();
            const Monomer *monomer = 
              polymer->monomerList().at(coordinates->start());
            
            QString text = tr("%1 at pos. %2")
              .arg(monomer->code())
              .arg(coordinates->start() + 1);
            
            m_ui.currentSelectionLineEdit->setText(text);
            }
          else
            {
            m_ui.currentSelectionLineEdit->
              setText(coordList.positionsAsText());
            }
          
          m_calcOptions.setCoordinateList(*coordinates);
        }
      }
    else
      {
      // There is no selection, set the "selection" to be the
      // whole sequence.
      
      Coordinates coordinates(0, mp_polymer->size() - 1);
      m_calcOptions.setCoordinateList(coordinates);
      
      m_ui.wholeSequenceRadioButton->setChecked(true);
      }
    
    // Return if there was a selection(multiple-region or not) or
    // not.
    return res;
  }
  

  bool
  MassSearchDlg::checkTolerance(int type)
  {
    int index = 0;
    double nominal = 0;
    bool ok = false;

    QString text;

    if (type & MXT_MASS_MONO)
      {
      index = m_ui.monoToleranceComboBox->currentIndex();
      text = m_ui.monoMassLineEdit->text();
      }
    else if (type & MXT_MASS_AVG)
      {
      index = m_ui.avgToleranceComboBox->currentIndex();
      text = m_ui.avgMassLineEdit->text();
      }
    else
      Q_ASSERT(0);
  
    if (text.isEmpty())
      return false;
  
    nominal = text.toDouble(&ok);

    if (!nominal && !ok)
      return false;

    return true;
  }

  bool
  MassSearchDlg::calculateTolerance(double value, int type)
  {
    int index = 0;
    double nominal = 0;

    bool ok = false;

    QString text;

  
    if (type & MXT_MASS_MONO)
      {
      index = m_ui.monoToleranceComboBox->currentIndex();
      text = m_ui.monoMassLineEdit->text();
      }
    else if (type & MXT_MASS_AVG)
      {
      index = m_ui.avgToleranceComboBox->currentIndex();
      text = m_ui.avgMassLineEdit->text();
      }
    else
      Q_ASSERT(0);
  
  
    nominal = text.toDouble(&ok);

    if (!nominal && !ok)
      return false;
  
    if (index == 0)
      {
      // MXT_MASS_TOLERANCE_AMU
  
      type & MXT_MASS_MONO ? 
        m_monoTolerance = nominal :
        m_avgTolerance = nominal;
      
      return true;
      }
    else if (index == 1)
      {
      // MXT_MASS_TOLERANCE_PCT

      type & MXT_MASS_MONO ? 
        m_monoTolerance = nominal *(value / 100) :
        m_avgTolerance = nominal *(value / 100);

      return true;
      }
    else if (index == 2)
      {
      // MXT_MASS_TOLERANCE_PPM

      type & MXT_MASS_MONO ? 
        m_monoTolerance = nominal *(value / 1000000) :
        m_avgTolerance = nominal *(value / 1000000);
      
      return true;
      }
    else
      Q_ASSERT(0);
  
    return false;
  }


  bool
  MassSearchDlg::parseMassText(int type)
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    Q_ASSERT(type & MXT_MASS_MONO || type & MXT_MASS_AVG);
  
    QString text;
  
    if (type & MXT_MASS_MONO)
      text = m_ui.monoMassTextEdit->toPlainText();
    else if (type & MXT_MASS_AVG)
      text = m_ui.avgMassTextEdit->toPlainText();
    else
      Q_ASSERT(0);

    QStringList splitList = text.split(QRegExp("\\s+"), 
                              QString::SkipEmptyParts);

    for (int iter = 0; iter < splitList.size(); ++iter)
      {
      bool ok = false;
      
      double value = locale.toDouble(splitList.at(iter), &ok);
      
      if(!value && !ok)
        {
          qDebug() << "Error in mass list";
        
          return false;
        }
      
      if(type & MXT_MASS_MONO)
        m_monoMassesList.append(value);
      else
        m_avgMassesList.append(value);
      }

    return true;
  }


  bool
  MassSearchDlg::searchMass(double value, 
                       const Coordinates &coordinates,
                       int type)
  {
    //    CalcOptions localCalcOptions(*mp_calcOptions);
    IonizeRule localIonizeRule(*mp_ionizeRule);
  
    int count = 0;
    int cycle = 0;
  
    Q_ASSERT(type & MXT_MASS_MONO || type & MXT_MASS_AVG);

    int startIndex = coordinates.start();
    int endIndex = coordinates.end();

    double maxValue = type & MXT_MASS_MONO ?
      value + m_monoTolerance :
      value + m_avgTolerance;
  
    double minValue = type & MXT_MASS_MONO ?
      value - m_monoTolerance :
      value - m_avgTolerance;
    
    if (minValue < 0)
      minValue = 0;
  
    m_currentMass = value;
    updateProgressDetails(type);
  
    for (int iter = startIndex; iter < endIndex + 1; ++iter)
      {
      if(m_abort)
        return true;

      for(int jter = 0; jter < endIndex + 1 - iter; ++jter)
        {
          // Note that the ionization starts from a low value and goes
          // to a higher value, that means that while this loop runs
          // for a given oligomer, the m/z ratio goes diminishing.
          
          for (int kter = m_ionizeStart; kter < m_ionizeEnd + 1; 
             ++kter, ++cycle)
            {
            ++m_testedOligosCount;
            
            if(cycle == 200)
              {
                cycle = 0;
                updateProgressDetails(type);
              }
            
            localIonizeRule.setLevel(kter);
            
            Oligomer oligomerTest(mp_polymer, "NOT_SET", Ponderable(),
                               localIonizeRule, false,
                               iter, iter + jter);
          
            oligomerTest.calculateMasses(&m_calcOptions);
            
            double mz = type & MXT_MASS_MONO ? 
              oligomerTest.mono() :
              oligomerTest.avg();
            
            if(mz < minValue)
              // Oligomer's m/z already too small. Break
              // immediately as this cannot get any better by
              // continuing to increase the ionization level.
              break;
            
            if(mz > maxValue)
              // Oligomer's m/z is still too big. Continue
              // incrementing the ionization level, so that its
              // m/z will decrease...
              continue;
            
            
            // At this point the oligomer has correct masses.

            Oligomer *oligomerNew = new Oligomer(oligomerTest);
            
            ++count;
            
            int totalCharge = localIonizeRule.charge() *
              localIonizeRule.level();
                        
            QString name = QString("%1-z%2#%3")
              .arg(value)
              .arg(totalCharge)
              .arg(count);
                        
            oligomerNew->setName(name);

            // Set the searched mz in a prop.
 
            DoubleProp *prop = new DoubleProp("SEARCHED_MZ",
                                       value);
            
            oligomerNew->appendProp(prop);
            
            // Set the error mz in a prop.

            double error = mz - value ;
            
            prop = new DoubleProp("ERROR_MZ", error);
            
            oligomerNew->appendProp(prop);
            
            type & MXT_MASS_MONO ? 
              mpa_monoOligomerTreeViewModel->addOligomer(oligomerNew) :
              mpa_avgOligomerTreeViewModel->addOligomer(oligomerNew);
            
            ++m_foundOligosCount;
            
            updateProgressDetails(type, false, oligomerNew);
            }
          // End of
          // for (int kter = m_ionizeStart; kter < m_ionizeEnd + 1; ++kter)
        }
      // End of 
      // for (int jter = 0; jter < endIndex + 1 - iter; ++jter)
      }
    // End of
    // for (int iter = startIndex; iter < endIndex + 1; ++iter)

    return true;
  }


  bool
  MassSearchDlg::searchMasses(int type)
  {
    if (!mp_polymer->size())
      return false;
  
    const CoordinateList &coordinateList = m_calcOptions.coordinateList();
    
    if (type & MXT_MASS_MONO)
      {
      for(int iter = 0; iter < m_monoMassesList.size(); ++iter)
        {
          double value = m_monoMassesList.at(iter);
        
          if (!calculateTolerance(value, MXT_MASS_MONO))
            return false;

          for (int iter = 0; iter < coordinateList.size(); ++iter)
            {
            if(!searchMass(value, *(coordinateList.at(iter)),
                         MXT_MASS_MONO))
              return false;
            
            m_ui.massSearchProgressBar->setValue(++m_progressValue);
            
            if(m_abort)
              return true;
            }
        }
      }
    else if (type & MXT_MASS_AVG)
      {
      for(int iter = 0; iter < m_avgMassesList.size(); ++iter)
        {
          double value = m_avgMassesList.at(iter);
        
          if (!calculateTolerance(value, MXT_MASS_AVG))
            return false;
        
          for (int iter = 0; iter < coordinateList.size(); ++iter)
            {
            if(!searchMass(value, *(coordinateList.at(iter)),
                         MXT_MASS_AVG))
              return false;
            
            m_ui.massSearchProgressBar->setValue(++m_progressValue);
            
            if(m_abort)
              return true;
            }
        }
      }
    else
      Q_ASSERT(0);
    
    return true;
  }


  void 
  MassSearchDlg::search()
  {
    // Update the options from the parent window.
    m_calcOptions = mp_editorWnd->calcOptions();
    
    // Update the currently selected region(s) if any in the sequence
    // editor.
    updateSelectionData();
    
    updateIonizationData();
  
    // Empty the treeviews and the lists of oligomers.
    mpa_monoOligomerTreeViewModel->removeAll();
    mpa_avgOligomerTreeViewModel->removeAll();
  
    emptyAllMassLists();

    m_abort = false;
    
    if (!parseMassText(MXT_MASS_MONO))
      {
      QMessageBox::warning 
       (this, 
         tr("massXpert - Polymer Mass Search"),
         tr("%1@%2\n"
             "Failed to parse the masses to search for MONO.")
         .arg(__FILE__)
         .arg(__LINE__),
         QMessageBox::Ok);

      return;
      }
  
    if (!parseMassText(MXT_MASS_AVG))
      {
      QMessageBox::warning 
       (this, 
         tr("massXpert - Polymer Mass Search"),
         tr("%1@%2\n"
             "Failed to parse the masses to search for AVG.")
         .arg(__FILE__)
         .arg(__LINE__),
         QMessageBox::Ok);

      return;
      }
  
    if (m_monoMassesList.size())
      {
      if(!checkTolerance(MXT_MASS_MONO))
        {
          QMessageBox::information(this, tr("massxpert - Mass Search"),
                              tr("Enter a valid MONO tolerance value"),
                              QMessageBox::Ok);
          return;
        }
      }
  
    if (m_avgMassesList.size())
      {
      if(!checkTolerance(MXT_MASS_AVG))
        {
          QMessageBox::information(this, tr("massxpert - Mass Search"),
                              tr("Enter a valid AVG tolerance value"),
                              QMessageBox::Ok);
          return;
        }
      }
  
    setCursor(Qt::WaitCursor);
  
    m_testedOligosCount = 0;
    m_foundOligosCount = 0;

    int massNumber = m_monoMassesList.size() + m_avgMassesList.size();
    m_progressValue = 0;
    m_ui.massSearchProgressBar->setRange(0, massNumber);
    
    updateProgressDetails(MXT_MASS_MONO, true);
    updateProgressDetails(MXT_MASS_AVG, true);

   Application *application = static_cast<Application *>(qApp);

    if (!searchMasses(MXT_MASS_MONO))
      {
      QMessageBox::warning 
       (this, 
         tr("massXpert - Polymer Mass Search"),
         tr("%1@%2\n"
             "Failed to search for the MONO masses.")
         .arg(__FILE__)
         .arg(__LINE__),
         QMessageBox::Ok);

      setCursor(Qt::ArrowCursor);
      updateMassSearchDetails();
      application->beep();

      return;
      }

    if (!searchMasses(MXT_MASS_AVG))
      {
      QMessageBox::warning 
       (this, 
         tr("massXpert - Polymer Mass Search"),
         tr("%1@%2\n"
             "Failed to search for the AVG masses.")
         .arg(__FILE__)
         .arg(__LINE__),
         QMessageBox::Ok);

      setCursor(Qt::ArrowCursor);
      updateMassSearchDetails();
      application->beep();

      return;
      }
  
    setCursor(Qt::ArrowCursor);

    updateMassSearchDetails();

    application->beep();
  }


  void
  MassSearchDlg::setupTreeViews()
  {
    // Model stuff all thought for sorting.
    mpa_monoOligomerTreeViewModel = 
      new MassSearchOligomerTreeViewModel(&m_monoOligomerList, this);

    mpa_avgOligomerTreeViewModel = 
      new MassSearchOligomerTreeViewModel(&m_avgOligomerList, this);
  
    mpa_monoProxyModel = new MassSearchOligomerTreeViewSortProxyModel(this);
    mpa_monoProxyModel->setSourceModel(mpa_monoOligomerTreeViewModel);
    mpa_monoProxyModel->setFilterKeyColumn(-1);

    mpa_avgProxyModel = new MassSearchOligomerTreeViewSortProxyModel(this);
    mpa_avgProxyModel->setSourceModel(mpa_avgOligomerTreeViewModel);
    mpa_avgProxyModel->setFilterKeyColumn(-1);

    m_ui.monoOligomerTreeView->setModel(mpa_monoProxyModel);
    m_ui.monoOligomerTreeView->setParentDlg(this);
    mpa_monoOligomerTreeViewModel->setTreeView(m_ui.monoOligomerTreeView);

    m_ui.avgOligomerTreeView->setModel(mpa_avgProxyModel);
    m_ui.avgOligomerTreeView->setParentDlg(this);
    mpa_avgOligomerTreeViewModel->setTreeView(m_ui.avgOligomerTreeView);
  }


  void
  MassSearchDlg::updateIonizationData()
  {
    m_ionizeStart = m_ui.ionizationStartSpinBox->value();
    m_ionizeEnd = m_ui.ionizationEndSpinBox->value();

    if (m_ionizeStart > m_ionizeEnd)
      {
      int temp = m_ionizeStart;
      m_ionizeStart = m_ionizeEnd;
      m_ionizeEnd = temp;
      }
  }


  void 
  MassSearchDlg::updateProgressDetails(int type, bool reset,
                              Oligomer *oligomer)
  {
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();
  
    if (reset)
      {
      m_ui.lastOligoNameLineEdit->setText("");
      m_ui.lastOligoCoordinatesLineEdit->setText("");
      m_ui.lastOligoMonoMassLineEdit->setText("");
      m_ui.lastOligoAvgMassLineEdit->setText("");
      
      m_ui.currentMassLineEdit->setText("");
      
      m_ui.lastOligoMassTypeLineEdit->setText("");
      
      m_ui.testedCountLabel->setText(QString().setNum(0));
      m_ui.foundCountLabel->setText(QString().setNum(0));
      
      m_ui.massSearchProgressBar->setValue(0);

      application->processEvents();

      return;
      }
  
    if (oligomer)
      {
      m_ui.lastOligoNameLineEdit->setText(oligomer->name());
      QString coordinates(tr("[ %1 - %2 ]")
                       .arg(oligomer->startIndex() + 1)
                       .arg(oligomer->endIndex() + 1));
      
      m_ui.lastOligoCoordinatesLineEdit->setText(coordinates);
      
      QString mass = oligomer->mono(locale);
      m_ui.lastOligoMonoMassLineEdit->setText(mass);
      
      mass = oligomer->avg(locale);
      m_ui.lastOligoAvgMassLineEdit->setText(mass);
      }
  
    m_ui.currentMassLineEdit->setText(QString().setNum(m_currentMass, 
                                            'g', 10));
  
    type & MXT_MASS_MONO ?
      m_ui.lastOligoMassTypeLineEdit->setText(tr("MONO")) :
      m_ui.lastOligoMassTypeLineEdit->setText(tr("AVG"));
  
    m_ui.testedCountLabel->setText(QString().setNum(m_testedOligosCount));
    m_ui.foundCountLabel->setText(QString().setNum(m_foundOligosCount));

    m_ui.massSearchProgressBar->setValue(m_progressValue);

    application->processEvents();
  }

  
  void
  MassSearchDlg::updateMassSearchDetails()
  {
    if (m_calcOptions.monomerEntities() & MXT_MONOMER_CHEMENT_MODIF)
      m_ui.modifsPixmapLabel->setPixmap(QPixmap(":/images/greenled.png"));
    else
      m_ui.modifsPixmapLabel->setPixmap(QPixmap(":/images/redled.png"));

    if (m_calcOptions.polymerEntities() & MXT_POLYMER_CHEMENT_LEFT_END_MODIF)
      m_ui.leftModifPixmapLabel->setPixmap(QPixmap(":/images/greenled.png"));
    else
      m_ui.leftModifPixmapLabel->setPixmap(QPixmap(":/images/redled.png"));

    if (m_calcOptions.polymerEntities() & MXT_POLYMER_CHEMENT_RIGHT_END_MODIF)
      m_ui.rightModifPixmapLabel->setPixmap(QPixmap(":/images/greenled.png"));
    else
      m_ui.rightModifPixmapLabel->setPixmap(QPixmap(":/images/redled.png"));
  }


  void
  MassSearchDlg::updateOligomerSequence(QString *text)
  {
    Q_ASSERT(text);
  
    m_ui.oligomerSequenceTextEdit->clear();
    m_ui.oligomerSequenceTextEdit->append(*text);
  }


  void 
  MassSearchDlg::freeAllOligomerLists()
  {
    while(!m_monoOligomerList.isEmpty())
      delete m_monoOligomerList.takeFirst();

    while(!m_avgOligomerList.isEmpty())
      delete m_avgOligomerList.takeFirst();
  }


  void 
  MassSearchDlg::emptyAllMassLists()
  {
    while(!m_monoMassesList.isEmpty())
      m_monoMassesList.removeFirst();

    while(!m_avgMassesList.isEmpty())
      m_avgMassesList.removeFirst();
  }


  void 
  MassSearchDlg::abort()
  {
    m_abort = true;
  }



  bool
  MassSearchDlg::calculateFilterTolerance(double mass, int massType)
  {
    // Get the tolerance that is in its lineEdit.
    QString text;
  
    if (massType == MXT_MASS_MONO)
      text = m_ui.monoFilterToleranceLineEdit->text();
    else if (massType == MXT_MASS_AVG)
      text = m_ui.avgFilterToleranceLineEdit->text();
    else
      Q_ASSERT(0);
  
    double tolerance = 0;
    bool ok = false;
  
    if (!text.isEmpty())
      {
      // Convert the string to a double.
      Application *application = static_cast<Application *>(qApp);
      QLocale locale = application->locale();

      ok = false;
      tolerance = locale.toDouble(text, &ok);
      
      if(!tolerance && !ok)
        return false;
      }
    else
      {
      m_filterTolerance = 0;
      }
    
    // What's the item currently selected in the comboBox?
    int index = 0;
  
    if (massType == MXT_MASS_MONO)
      index = m_ui.monoFilterToleranceComboBox->currentIndex();
    else if (massType == MXT_MASS_AVG)
      index = m_ui.avgFilterToleranceComboBox->currentIndex();
    else
      Q_ASSERT(0);
  
    if (index == 0)
      {
      // MXT_MASS_TOLERANCE_AMU
      m_filterTolerance = tolerance;
      }
    else if (index == 1)
      {
      // MXT_MASS_TOLERANCE_PCT
      m_filterTolerance =(tolerance / 100) * mass;
      }
    else if (index == 2)
      {
      // MXT_MASS_TOLERANCE_PPM
      m_filterTolerance =(tolerance / 1000000) * mass;
      }
    else
      Q_ASSERT(0);
  
    return true;
  }


  void 
  MassSearchDlg::monoFilterOptions(bool checked)
  {
    if (!checked)
      {
      mpa_monoProxyModel->setFilterKeyColumn(-1);
      
      mpa_monoProxyModel->applyNewFilter();

      m_ui.monoFilteringOptionsFrame->setVisible(false);
      }
    else
      {
      m_ui.monoFilteringOptionsFrame->setVisible(true);

      // In this case, set focus to the last focused widget in the
      // groupbox or the first widget in the groubox if this is the
      // first time the filtering is used.
      mp_monoFocusWidget->setFocus();
      }
  }


  void
  MassSearchDlg::monoFilterOptionsToggled()
  {
    bool isChecked = m_ui.monoFilteringOptionsGroupBox->isChecked();
  
    m_ui.monoFilteringOptionsGroupBox->setChecked(!isChecked);
    monoFilterOptions(!isChecked);
  }


  void 
  MassSearchDlg::avgFilterOptions(bool checked)
  {
    if (!checked)
      {
      mpa_avgProxyModel->setFilterKeyColumn(-1);
      
      mpa_avgProxyModel->applyNewFilter();
      
      m_ui.avgFilteringOptionsFrame->setVisible(false);
      }
    else
      {
      m_ui.avgFilteringOptionsFrame->setVisible(true);

      // In this case, set focus to the last focused widget in the
      // groupbox or the first widget in the groubox if this is the
      // first time the filtering is used.
      mp_avgFocusWidget->setFocus();
      }
  }


  void
  MassSearchDlg::avgFilterOptionsToggled()
  {
    bool isChecked = m_ui.avgFilteringOptionsGroupBox->isChecked();
  
    m_ui.avgFilteringOptionsGroupBox->setChecked(!isChecked);
    avgFilterOptions(!isChecked);
  }


  void 
  MassSearchDlg::monoFilterSearched()
  {
    // First off, we have to get the mass that is in the lineEdit.

    QString text = m_ui.monoFilterSearchedLineEdit->text();
  
    if (text.isEmpty())
      return;
    
    // Convert the string to a double.
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    bool ok = false;
    double mass = locale.toDouble(text, &ok);
  
    if (!mass && !ok)
      return;

    mpa_monoProxyModel->setSearchedFilter(mass);
  
    mpa_monoProxyModel->setFilterKeyColumn(0);
    mpa_monoProxyModel->applyNewFilter();

    mp_monoFocusWidget = m_ui.monoFilterSearchedLineEdit;
  }


  void 
  MassSearchDlg::avgFilterSearched()
  {
    // First off, we have to get the mass that is in the lineEdit.

    QString text = m_ui.avgFilterSearchedLineEdit->text();
  
    if (text.isEmpty())
      return;
  
    // Convert the string to a double.
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    bool ok = false;
    double mass = locale.toDouble(text, &ok);
  
    if (!mass && !ok)
      return;

    mpa_avgProxyModel->setSearchedFilter(mass);
  
    mpa_avgProxyModel->setFilterKeyColumn(0);
    mpa_avgProxyModel->applyNewFilter();

    mp_avgFocusWidget = m_ui.avgFilterSearchedLineEdit;
  }


  void 
  MassSearchDlg::monoFilterError()
  {
    // First off, we have to get the mass error that is in the lineEdit.

    QString text = m_ui.monoFilterErrorLineEdit->text();
  
    if (text.isEmpty())
      return;
  
    // Convert the string to a double.
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    bool ok = false;
    double mass = locale.toDouble(text, &ok);
  
    if (!mass && !ok)
      return;

    // At this point, depending on the item that is currently selected
    // in the comboBox, we'll have to actually compute the tolerance.

    if (!calculateFilterTolerance(mass, MXT_MASS_MONO))
      return ;

    mpa_monoProxyModel->setErrorFilter(mass);
    mpa_monoProxyModel->setTolerance(m_filterTolerance);
  
    mpa_monoProxyModel->setFilterKeyColumn(3);
    mpa_monoProxyModel->applyNewFilter();

    mp_monoFocusWidget = m_ui.monoFilterErrorLineEdit;
  }


  void 
  MassSearchDlg::avgFilterError()
  {
    // First off, we have to get the mass error that is in the lineEdit.

    QString text = m_ui.avgFilterErrorLineEdit->text();
  
    if (text.isEmpty())
      return;
  
    // Convert the string to a double.
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    bool ok = false;
    double mass = locale.toDouble(text, &ok);
  
    if (!mass && !ok)
      return;

    // At this point, depending on the item that is currently selected
    // in the comboBox, we'll have to actually compute the tolerance.

    if (!calculateFilterTolerance(mass, MXT_MASS_AVG))
      return ;

    mpa_avgProxyModel->setErrorFilter(mass);
    mpa_avgProxyModel->setTolerance(m_filterTolerance);
  
    mpa_avgProxyModel->setFilterKeyColumn(3);
    mpa_avgProxyModel->applyNewFilter();

    mp_avgFocusWidget = m_ui.avgFilterErrorLineEdit;
  }


  void 
  MassSearchDlg::monoFilterMonoMass()
  {
    // First off, we have to get the mass that is in the lineEdit.

    QString text = m_ui.monoFilterMonoMassLineEdit->text();
  
    if (text.isEmpty())
      return;
  
    // Convert the string to a double.
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    bool ok = false;
    double mass = locale.toDouble(text, &ok);
  
    if (!mass && !ok)
      return;

    // At this point, depending on the item that is currently selected
    // in the comboBox, we'll have to actually compute the tolerance.

    if (!calculateFilterTolerance(mass, MXT_MASS_MONO))
      return ;

    mpa_monoProxyModel->setMonoFilter(mass);
    mpa_monoProxyModel->setTolerance(m_filterTolerance);
  
    mpa_monoProxyModel->setFilterKeyColumn(4);
    mpa_monoProxyModel->applyNewFilter();

    mp_monoFocusWidget = m_ui.monoFilterMonoMassLineEdit;
  }


  void 
  MassSearchDlg::avgFilterMonoMass()
  {
    // First off, we have to get the mass that is in the lineEdit.

    QString text = m_ui.avgFilterMonoMassLineEdit->text();
  
    if (text.isEmpty())
      return;
  
    // Convert the string to a double.
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    bool ok = false;
    double mass = locale.toDouble(text, &ok);
  
    if (!mass && !ok)
      return;

    // At this point, depending on the item that is currently selected
    // in the comboBox, we'll have to actually compute the tolerance.

    if (!calculateFilterTolerance(mass, MXT_MASS_AVG))
      return ;

    mpa_avgProxyModel->setMonoFilter(mass);
    mpa_avgProxyModel->setTolerance(m_filterTolerance);
  
    mpa_avgProxyModel->setFilterKeyColumn(4);
    mpa_avgProxyModel->applyNewFilter();

    mp_avgFocusWidget = m_ui.avgFilterMonoMassLineEdit;
  }


  void 
  MassSearchDlg::monoFilterAvgMass()
  {
    // First off, we have to get the mass that is in the lineEdit.

    QString text = m_ui.monoFilterAvgMassLineEdit->text();
  
    if (text.isEmpty())
      return;
  
    // Convert the string to a double.
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    bool ok = false;
    double mass = locale.toDouble(text, &ok);
  
    if (!mass && !ok)
      return;

    // At this point, depending on the item that is currently selected
    // in the comboBox, we'll have to actually compute the tolerance.

    if (!calculateFilterTolerance(mass, MXT_MASS_MONO))
      return ;

    mpa_monoProxyModel->setAvgFilter(mass);
    mpa_monoProxyModel->setTolerance(m_filterTolerance);
  
    mpa_monoProxyModel->setFilterKeyColumn(5);
    mpa_monoProxyModel->applyNewFilter();

    mp_monoFocusWidget = m_ui.monoFilterAvgMassLineEdit;
  }


  void 
  MassSearchDlg::avgFilterAvgMass()
  {
    // First off, we have to get the mass that is in the lineEdit.

    QString text = m_ui.avgFilterAvgMassLineEdit->text();
  
    if (text.isEmpty())
      return;
  
    // Convert the string to a double.
    Application *application = static_cast<Application *>(qApp);
    QLocale locale = application->locale();

    bool ok = false;
    double mass = locale.toDouble(text, &ok);
  
    if (!mass && !ok)
      return;

    // At this point, depending on the item that is currently selected
    // in the comboBox, we'll have to actually compute the tolerance.

    if (!calculateFilterTolerance(mass, MXT_MASS_AVG))
      return ;

    mpa_avgProxyModel->setAvgFilter(mass);
    mpa_avgProxyModel->setTolerance(m_filterTolerance);
  
    mpa_avgProxyModel->setFilterKeyColumn(5);
    mpa_avgProxyModel->applyNewFilter();

    mp_avgFocusWidget = m_ui.avgFilterAvgMassLineEdit;
  }



  // The results-exporting functions. ////////////////////////////////
  // The results-exporting functions. ////////////////////////////////
  // The results-exporting functions. ////////////////////////////////
  void
  MassSearchDlg::exportResults(int index)
  {
    // Remember that we had set up the combobox with the following strings:
    // << tr("To &Clipboard") 
    // << tr("To &File")
    // << tr("&Select File");

    if (index == 0)
      {
      exportResultsClipboard();
      }
    else if (index == 1)
      {
      exportResultsFile();
      }
    else if (index == 2)
      {
      selectResultsFile();
      }
    else 
      Q_ASSERT(0);
  
  }


  void
  MassSearchDlg::prepareResultsTxtString()
  {
    mpa_resultsString->clear();
  
    *mpa_resultsString += QObject::tr("\n---------------------------\n"
                               "Mass Search: \n"
                               "---------------------------\n");
  
    bool monoSearched = true;
    bool avgSearched = true;

    // Should the oligomers have their sequence displayed?
    bool withSequence = m_ui.withSequenceCheckBox->isChecked();
      
    // Get the mono masses searched:
    QString masses = m_ui.monoMassTextEdit->toPlainText();
    if (!masses.isEmpty())
      {
      *mpa_resultsString += QObject::tr("\nSearched mono masses:\n"
                                 "%1\n")
        .arg(masses);
      monoSearched = false;
      }
  
    // The mono treeview:

    QString *text = 
      m_ui.monoOligomerTreeView->selectedOligomersAsPlainText(withSequence);

    *mpa_resultsString += *text;
    
    delete text;

    // Get the avg masses searched:
    masses = m_ui.avgMassTextEdit->toPlainText();
    if (!masses.isEmpty())
      {
      *mpa_resultsString += QObject::tr("\nSearched average masses:\n"
                                 "%1\n")
        .arg(masses);
      avgSearched = false;
      }
  
    // The avg treeview:
    
    text = m_ui.avgOligomerTreeView->selectedOligomersAsPlainText(withSequence);

    *mpa_resultsString += *text;
    
    delete text;
  }


  bool 
  MassSearchDlg::exportResultsClipboard()
  {
    prepareResultsTxtString();
  
    QClipboard *clipboard = QApplication::clipboard();

    clipboard->setText(*mpa_resultsString, QClipboard::Clipboard);
  
    return true;
  }


  bool 
  MassSearchDlg::exportResultsFile()
  {
    if (m_resultsFilePath.isEmpty())
      {
      if(!selectResultsFile())
        return false;
      }
  
    QFile file(m_resultsFilePath);
  
    if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
      {
      QMessageBox::information(0, 
                          tr("massXpert - Export Data"),
                          tr("Failed to open file in append mode."),
                          QMessageBox::Ok);
      return false;
      }
  
    QTextStream stream(&file);
    stream.setCodec("UTF-8");

    prepareResultsTxtString();
  
    stream << *mpa_resultsString;
  
    file.close();

    return true;
  }


  bool 
  MassSearchDlg::selectResultsFile()
  {
    m_resultsFilePath = 
      QFileDialog::getSaveFileName(this, tr("Select File To Export Data To"),
                            QDir::homePath(),
                            tr("Data files(*.dat *.DAT)"));
  
    if (m_resultsFilePath.isEmpty())
      return false;

    return true;
  }
  //////////////////////////////////// The results-exporting functions.
  //////////////////////////////////// The results-exporting functions.
  //////////////////////////////////// The results-exporting functions.

} // namespace massXpert

Generated by  Doxygen 1.6.0   Back to index