[Debichem-commits] [SCM] massXpert mass spectrometry suite: debian packaging branch, debian, updated. upstream/3.2.0-1-g5564507
Filippo Rusconi (Debian Maintainer)
rusconi-debian at laposte.net
Thu Nov 24 21:29:13 UTC 2011
The following commit has been merged in the debian branch:
commit 785f3626c0c6bd60ba5f17b11d580472b7e6cb06
Author: Filippo Rusconi (Debian Maintainer) <rusconi-debian at laposte.net>
Date: Sun Aug 14 16:25:17 2011 +0200
First implementation of the calculation of a spectrum made of isotopic cluster of a number of oligomers.
diff --git a/gui/calculatorWnd.cpp b/gui/calculatorWnd.cpp
index 37f04ca..d62df15 100644
--- a/gui/calculatorWnd.cpp
+++ b/gui/calculatorWnd.cpp
@@ -1166,6 +1166,7 @@ namespace massXpert
{
SpectrumCalculationDlg *dlg =
new SpectrumCalculationDlg(this,
+ 0 /* no polymer pointer in this casee */,
m_polChemDef.atomList(),
MXP_SPECTRUM_CALCULATION_MODE_CLUSTER);
diff --git a/gui/cleavageDlg.cpp b/gui/cleavageDlg.cpp
index de79c38..8e80cfc 100644
--- a/gui/cleavageDlg.cpp
+++ b/gui/cleavageDlg.cpp
@@ -49,6 +49,7 @@
#include "peakCentroid.hpp"
#include "peakShapeConfig.hpp"
#include "isotopicPatternCalculator.hpp"
+#include "spectrumCalculationDlg.hpp"
namespace massXpert
@@ -119,7 +120,8 @@ namespace massXpert
comboBoxItemList
<< tr("To Clipboard")
<< tr("To File")
- << tr("Select File");
+ << tr("Select File")
+ << tr("Calculate spectrum");
m_ui.exportResultsComboBox->addItems(comboBoxItemList);
@@ -797,6 +799,10 @@ bool
{
selectResultsFile();
}
+ else if (index == 3)
+ {
+ calculateSpectrum();
+ }
else
Q_ASSERT(0);
@@ -882,6 +888,29 @@ bool
return true;
}
+
+
+ bool
+ CleavageDlg::calculateSpectrum()
+ {
+ qDebug() << __FILE__ << __LINE__
+ << "calculateSpectrum";
+
+ SpectrumCalculationDlg *dlg =
+ new SpectrumCalculationDlg(this,
+ mp_polymer,
+ mp_polChemDef->atomList(),
+ MXP_SPECTRUM_CALCULATION_MODE_SPECTRUM);
+
+ // We now have to prepare the land for the calculations.
+
+ dlg->setOligomerList(&m_oligomerList);
+
+ dlg->show();
+
+ return true;
+ }
+
//////////////////////////////////// The results-exporting functions.
//////////////////////////////////// The results-exporting functions.
//////////////////////////////////// The results-exporting functions.
diff --git a/gui/cleavageDlg.hpp b/gui/cleavageDlg.hpp
index 9c8d5bd..4613132 100644
--- a/gui/cleavageDlg.hpp
+++ b/gui/cleavageDlg.hpp
@@ -114,6 +114,7 @@ namespace massXpert
bool exportResultsToClipboard();
bool exportResultsFile();
bool selectResultsFile();
+ bool calculateSpectrum();
//////////////////////////////////// The results-exporting functions.
public slots:
diff --git a/gui/fragmentOligomerTableView.cpp b/gui/fragmentOligomerTableView.cpp
index 5677f9b..0fe1c59 100644
--- a/gui/fragmentOligomerTableView.cpp
+++ b/gui/fragmentOligomerTableView.cpp
@@ -426,7 +426,15 @@ namespace massXpert
static_cast<FragmentOligomer *>(mp_oligomerList->at(row));
SequenceEditorWnd *editorWnd = mp_parentDlg->editorWnd();
-
+
+ // The formula is not correct by now. The fragmentation formula
+ // does not seem to be taken into account. However, it works fine
+ // for oligomers computed from cleavage.
+ //
+ // QString formula = oligomer->elementalComposition();
+ // qDebug() << __FILE__ << __LINE__
+ // << "Elemental composition: " << formula;
+
if (oligomer->startIndex() >= oligomer->polymer()->size() ||
oligomer->endIndex() >= oligomer->polymer()->size())
{
diff --git a/gui/spectrumCalculationDlg.cpp b/gui/spectrumCalculationDlg.cpp
index 8f49ea9..7f0b1dc 100644
--- a/gui/spectrumCalculationDlg.cpp
+++ b/gui/spectrumCalculationDlg.cpp
@@ -56,16 +56,19 @@ namespace massXpert
{
SpectrumCalculationDlg::SpectrumCalculationDlg
- (QWidget *parent, const QList<Atom *> &atomList,
+ (QWidget *parent,
+ const Polymer *polymer,
+ const QList<Atom *> &atomList,
SpectrumCalculationMode mode)
: QDialog(parent),
+ mp_polymer(polymer),
m_mode(mode),
m_atomList(atomList),
m_polChemDef(static_cast<CalculatorWnd *>(parent)->polChemDef())
{
Q_ASSERT(parent);
- setWindowTitle("massXpert: Isotopic pattern calculator");
+ setWindowTitle("massXpert: Spectrum Calculator");
m_aborted = false;
@@ -76,9 +79,13 @@ namespace massXpert
m_validationErrors = MXP_VALIDATION_FORMULA_ERRORS;
m_filePath = "";
-
+
m_ui.setupUi(this);
+ // Set the oligomer list pointer to 0, so that we know if it was
+ // set or not later.
+ mp_oligomerList = 0;
+
setupDialog();
QSettings settings
@@ -118,6 +125,26 @@ namespace massXpert
this,
SLOT(fwhmEdited(const QString &)));
+ connect(m_ui.monoRadioButton,
+ SIGNAL(toggled(bool)),
+ this,
+ SLOT(massTypeRadioButtonToggled(bool)));
+
+ connect(m_ui.avgRadioButton,
+ SIGNAL(toggled(bool)),
+ this,
+ SLOT(massTypeRadioButtonToggled(bool)));
+
+ connect(m_ui.avgRadioButton,
+ SIGNAL(toggled(bool)),
+ this,
+ SLOT(massTypeRadioButtonToggled(bool)));
+
+ connect(m_ui.isotopicClusterCheckBox,
+ SIGNAL(toggled(bool)),
+ this,
+ SLOT(isotopicClusterCheckBoxToggled(bool)));
+
connect(m_ui.executePushButton,
SIGNAL(clicked()),
this,
@@ -166,6 +193,16 @@ namespace massXpert
void
+ SpectrumCalculationDlg::setOligomerList(OligomerList *list)
+ {
+ if(!list)
+ qFatal("Fatal error at %s@%d. Aborting.",__FILE__, __LINE__);
+
+ mp_oligomerList = list;
+ }
+
+
+ void
SpectrumCalculationDlg::setupDialog()
{
// By default we want a gaussian-type shape.
@@ -204,25 +241,52 @@ namespace massXpert
// Now, depending on the kind of operation required for the
// dialog, adapt some behaviour.
+
if(m_mode == MXP_SPECTRUM_CALCULATION_MODE_CLUSTER)
{
// In isotopic cluster calculation mode, the m/z calculated
// starting from the formula and the charge is of course mono!
- // Thus, we set it checked and disable mono and avg.
+ // Thus, we set it checked and disable the enclosing group box.
m_ui.monoRadioButton->setChecked(true);
- m_ui.monoRadioButton->setDisabled(true);
- m_ui.avgRadioButton->setDisabled(true);
+ m_ui.massTypeGroupBox->setDisabled(true);
+
+ // Of course, the computeIsotopicClusterCheckBox should be
+ // checked and disabled.
+ m_ui.isotopicClusterCheckBox->setChecked(true);
+ m_ui.isotopicClusterCheckBox->setDisabled(true);
}
-
+ else if(m_mode == MXP_SPECTRUM_CALCULATION_MODE_SPECTRUM)
+ {
+ // In spectrum mode, the formula, z and m/z are not active.
+ m_ui.mzGroupBox->setDisabled(true);
+ // By default, we work on mono masses.
+ m_withMonoMass= true;
+ m_ui.monoRadioButton->setChecked(m_withMonoMass);
+
+ // By default, we do not want isotopic cluster calculations.
+ m_withCluster = false;
+ m_ui.isotopicClusterCheckBox->setChecked(m_withCluster);
+ }
+ }
-}
-
bool
SpectrumCalculationDlg::fetchValidateInputData()
{
+ if(m_mode == MXP_SPECTRUM_CALCULATION_MODE_CLUSTER)
+ return fetchValidateInputDataIsotopicClusterMode();
+ else if(m_mode == MXP_SPECTRUM_CALCULATION_MODE_SPECTRUM)
+ return fetchValidateInputDataSpectrumMode();
+ else
+ return false;
+ }
+
+
+ bool
+ SpectrumCalculationDlg::fetchValidateInputDataIsotopicClusterMode()
+ {
Application *application = static_cast<Application *>(qApp);
// The ionization stuff, the formula for which the isotopic
@@ -255,9 +319,9 @@ namespace massXpert
if (!m_formula.deepAtomCopy(m_atomList))
{
QMessageBox::warning(0,
- tr("massXpert: Isotopic Pattern Calculation"),
- tr("Failed to deep-copy atom list."),
- QMessageBox::Ok);
+ tr("massXpert: Spectrum Calculator"),
+ tr("Failed to deep-copy atom list."),
+ QMessageBox::Ok);
return false;
}
@@ -296,9 +360,9 @@ namespace massXpert
.arg(m_formula.formula())
.arg(m_charge)
.arg(application->locale().
- toString(m_mono, 'f', MXP_OLIGOMER_DEC_PLACES))
+ toString(m_mono, 'f', MXP_OLIGOMER_DEC_PLACES))
.arg(application->locale().
- toString(m_avg, 'f', MXP_OLIGOMER_DEC_PLACES))
+ toString(m_avg, 'f', MXP_OLIGOMER_DEC_PLACES))
.arg(totAtoms)
.arg(totIsotopes);
else
@@ -351,7 +415,6 @@ namespace massXpert
// Set the maximum number of peaks in the isotopic curve.
m_maximumPeaks = m_ui.maximumPeaksSpinBox->value();
- QString fwhmString = m_ui.fwhmLineEdit->text();
// Set the minimum probability each isotopic peak must have to be
// retained in the final curve.
@@ -364,7 +427,7 @@ namespace massXpert
if(!minProb && !ok)
{
QMessageBox::warning(0,
- tr("massXpert: Isotopic Pattern Calculation"),
+ tr("massXpert: Spectrum Calculator"),
tr("Please, fix the minimum probability."),
QMessageBox::Ok);
@@ -375,9 +438,115 @@ namespace massXpert
return true;
}
+
+
+ bool
+ SpectrumCalculationDlg::fetchValidateInputDataSpectrumMode()
+ {
+ // The ionization stuff, the formula for which the isotopic
+ // pattern is to be calculated, the mz ratio (in m_mono) all have
+ // been checked previously by automated procedures (see the
+ // "changed" slots). We have to make sure that either the
+ // resolution or the FWHM values are OK. All the other bits must
+ // be clear. Only either the RESOLUTION or the FWHM bit might be
+ // set.
+
+ int testBitset = 0;
+ testBitset |= MXP_VALIDATION_RESOLUTION_ERRORS;
+ testBitset |= MXP_VALIDATION_FWHM_ERRORS;
+
+ // debugPutStdErrBitset(__FILE__, __LINE__,
+ // testBitset, "testBitset");
+
+ if(m_validationErrors == testBitset)
+ return false;
+
+ // We do not care of the formula in our spectrum calculation
+ // situation. Each oligomer from a cleavage contains a chemical
+ // composition formula that we'll use each time.
+
+ // We still have to fetch a number of parameters.
+ // Are we working on the mono or the avg masses of the oligomers?
+
+ m_withMonoMass = m_ui.monoRadioButton->isChecked();
+
+ // Get to know if we want gaussian or lorentzian shapes.
+ if(m_ui.gaussianRadioButton->isChecked())
+ {
+ m_config.setPeakShapeType(MXP_PEAK_SHAPE_TYPE_GAUSSIAN);
+ }
+ else
+ {
+ m_config.setPeakShapeType(MXP_PEAK_SHAPE_TYPE_LORENTZIAN);
+ }
+
+ // At this point we have to sort out wether the user wants to use
+ // the resolution or the FWHM for the calculations. This is
+ // automatically known by looking at which value is 0 (see the
+ // corresponding changed() slots).
+
+ // Get the points value.
+ m_config.setPointNumber(m_ui.pointNumberSpinBox->value());
+
+ // How about setting the increment, that is the size of the gap
+ // between two points ? If it is not set (its value is 0), then
+ // increment is fwhm() / m_pointNumber;
+
+ // First however, see if the user wants to use the FWHM value or
+ // the resolution.
+
+ if(m_config.fwhm())
+ {
+ // FWHM is not zero, which means the user has set a value for
+ // it. Keep it.
+ }
+ else
+ {
+ // We cannot compute fwhm starting from the resolution because
+ // we cannot know what is the m/z of the oligomers beforehand.
+
+ // All we can check is that resolution is non-zero.
+
+ if(m_resolution <= 0)
+ {
+ QMessageBox::warning(0,
+ tr("massXpert: Spectrum Calculator"),
+ tr("Please, fix the resolution or the FWHM."),
+ QMessageBox::Ok);
+
+ return false;
+ }
+ }
+
+ // Set the maximum number of peaks in the isotopic curve.
+ m_maximumPeaks = m_ui.maximumPeaksSpinBox->value();
+
+ // Set the minimum probability each isotopic peak must have to be
+ // retained in the final curve.
+
+ QString minProbString = m_ui.minimumProbabilityLineEdit->text();
+ bool ok = false;
+
+ double minProb = minProbString.toDouble(&ok);
+
+ if(!minProb && !ok)
+ {
+ QMessageBox::warning(0,
+ tr("massXpert: Spectrum Calculator"),
+ tr("Please, fix the minimum probability."),
+ QMessageBox::Ok);
+
+ return false;
+ }
+
+ m_minimumProbability = minProb;
+
+ return true;
+ }
-// Returns false if formula is bad or aborts if calculation fails..
+
+ // Returns false if formula is bad or aborts if calculation fails..
bool
SpectrumCalculationDlg::fetchFormulaMass(double *mono, double *avg)
{
@@ -478,6 +647,35 @@ namespace massXpert
return true;
}
+ void
+ SpectrumCalculationDlg::massTypeRadioButtonToggled(bool checked)
+ {
+ Q_UNUSED(checked);
+
+ m_withMonoMass = m_ui.monoRadioButton->isChecked();
+
+ // If the mass type is average, then, of course, no isotopic
+ // cluster calculation can be required.
+
+ if(!m_withMonoMass)
+ m_ui.isotopicClusterCheckBox->setChecked(false);
+ }
+
+ void
+ SpectrumCalculationDlg::isotopicClusterCheckBoxToggled(bool checked)
+ {
+ m_withCluster = checked;
+
+ if(checked)
+ {
+ // If the isotopic cluster is to be computed for each oligomer,
+ // then that means necessarily that the mass is mono!
+
+ m_withMonoMass = true;
+ m_ui.monoRadioButton->setChecked(true);
+ }
+ }
+
void
SpectrumCalculationDlg::formulaEdited(const QString &text)
@@ -596,11 +794,6 @@ namespace massXpert
void
SpectrumCalculationDlg::resolutionChanged(int value)
{
- // We only handle the automatic recalculations on the basis of
- // this change if we are in a isotopic cluster calculation task.
- if(m_mode != MXP_SPECTRUM_CALCULATION_MODE_CLUSTER)
- return;
-
// If the value changed, that means that the user wants the
// resolution to be taken into account for calculation of the peak
// width, and not the FWHM. Only if resolution is set to 0, FWHM
@@ -637,8 +830,15 @@ namespace massXpert
// Clear the bit as there is no error here.
m_validationErrors &= ~MXP_VALIDATION_RESOLUTION_ERRORS;
+ // We only handle the automatic recalculations on the basis of
+ // this change if we are in a isotopic cluster calculation task
+ // because only in that case do we know before starting the
+ // calculation what will be the mz.
+ if(m_mode != MXP_SPECTRUM_CALCULATION_MODE_CLUSTER)
+ return;
+
// We can try to compute the fwhm value corresponding to the
- // current m_mono (m/z, really) value and the resolution.
+ // current mono m/z value and the resolution.
double mono;
double avg;
@@ -678,11 +878,6 @@ namespace massXpert
void
SpectrumCalculationDlg::fwhmEdited(const QString &text)
{
- // We only handle the automatic recalculations on the basis of
- // this change if we are in a isotopic cluster calculation task.
- if(m_mode != MXP_SPECTRUM_CALCULATION_MODE_CLUSTER)
- return;
-
// Show what's the value of the errors.
// debugPutStdErrBitset(__FILE__, __LINE__,
// m_validationErrors,
@@ -749,6 +944,13 @@ namespace massXpert
// m_validationErrors,
// "m_validationErrors @ EXIT fwhmEdited");
+ // We only handle the automatic recalculation of the increment on
+ // the basis of this change if we are in a isotopic cluster
+ // calculation task because only in this case do we know the mono
+ // mz value.
+ if(m_mode != MXP_SPECTRUM_CALCULATION_MODE_CLUSTER)
+ return;
+
updateIncrement();
return;
@@ -771,7 +973,7 @@ namespace massXpert
if(!res)
{
QMessageBox::warning(0,
- tr("massXpert - Isotopic Pattern Calculation"),
+ tr("massXpert - Spectrum Calculator"),
tr("Failed to fetch the mz ratio."),
QMessageBox::Ok);
@@ -863,6 +1065,22 @@ namespace massXpert
void
SpectrumCalculationDlg::execute()
{
+ // We might be called to perform two different things:
+ //
+ // 1. Calculate a single istotopic cluster pattern.
+ //
+ // 2. Calculate a spectrum for a whole set of oligomers.
+
+ if(m_mode == MXP_SPECTRUM_CALCULATION_MODE_CLUSTER)
+ return executeCluster();
+ else if(m_mode == MXP_SPECTRUM_CALCULATION_MODE_SPECTRUM)
+ return executeSpectrum();
+ }
+
+
+ void
+ SpectrumCalculationDlg::executeCluster()
+ {
Application *application = static_cast<Application *>(qApp);
// Clear the textEdit widget so that we can start out-putting text
@@ -880,7 +1098,7 @@ namespace massXpert
if(!fetchValidateInputData())
{
QMessageBox::warning(0,
- tr("massXpert - Isotopic Pattern Calculation"),
+ tr("massXpert - Spectrum Calculator"),
tr("Please fix the input data first."),
QMessageBox::Ok);
return;
@@ -898,15 +1116,19 @@ namespace massXpert
if (isUsingLocale)
text->append(tr("FWHM: %1 \t Max. peaks %2 "
"\t Min. probability: %3\n\n")
- .arg(application->locale().toString(m_config.fwhm(), 'f', 4))
+ .arg(application->locale().toString(m_config.fwhm(),
+ 'f', 4))
.arg(application->locale().toString(m_maximumPeaks))
- .arg(application->locale().toString(m_minimumProbability, 'f', 15)));
+ .arg(application->locale().toString(m_minimumProbability,
+ 'f', 15)));
else
text->append(tr("FWHM: %1 \t Max. peaks %2 "
"\t Min. probability: %3\n\n")
- .arg(QString().setNum(m_config.fwhm(), 'f', 4))
+ .arg(QString().setNum(m_config.fwhm(),
+ 'f', 4))
.arg(QString().setNum(m_maximumPeaks))
- .arg(QString().setNum(m_minimumProbability, 'f', 15)));
+ .arg(QString().setNum(m_minimumProbability,
+ 'f', 15)));
m_ui.resultTextEdit->append(*text);
@@ -924,22 +1146,21 @@ namespace massXpert
connect(calculator,
SIGNAL(isotopicCalculationProgressValueChanged(int)),
this,
- SLOT(isotopicCalculationProgressValueChanged(int)));
+ SLOT(spectrumCalculationProgressValueChanged(int)));
connect(calculator,
SIGNAL(isotopicCalculationMessageChanged(QString)),
this,
- SLOT(isotopicCalculationMessageChanged(QString)));
+ SLOT(spectrumCalculationMessageChanged(QString)));
connect(this,
SIGNAL(isotopicCalculationAborted()),
calculator,
- SLOT(isotopicCalculationAborted()));
+ SLOT(spectrumCalculationAborted()));
// Perform the calculation...
-
- calculator->calculateSpectrum();
+ calculator->sumPeakShapes();
// Get the list of peaks as "1251.14 0.025" pairs.
text = calculator->peakCentroidListAsString();
@@ -968,7 +1189,7 @@ namespace massXpert
// QPointF instances in the calculator and send them either to the
// file or to the text edit widget.
- const QList<QPointF *> &spectrumPoints = calculator->spectrum();
+ const QList<QPointF *> &spectrumPoints = calculator->pointList();
QString dataString;
if(!m_filePath.isEmpty())
@@ -981,7 +1202,7 @@ namespace massXpert
if(!file.open(QFile::WriteOnly | QFile::Truncate))
{
QMessageBox::warning(this,
- tr("massXpert - Isotopic Pattern Calculation"),
+ tr("massXpert - Spectrum Calculator"),
tr("Failed to export the isotopic pattern "
"data to file."),
QMessageBox::Ok);
@@ -1027,6 +1248,287 @@ namespace massXpert
delete calculator;
}
+
+ void
+ SpectrumCalculationDlg::executeSpectrum()
+ {
+ // Verify that there are oligomers in the list.
+
+ if(!mp_oligomerList)
+ return;
+
+ if(mp_oligomerList->isEmpty())
+ return;
+
+ if(!fetchValidateInputData())
+ {
+ QMessageBox::warning(0,
+ tr("massXpert - Spectrum Calculator"),
+ tr("Please fix the input data first."),
+ QMessageBox::Ok);
+ return;
+ }
+
+ double minMz = 1000000000;
+ double maxMz = 0;
+ double curMz = 0;
+
+ // List of lists of QPointF, that is list of spectra.
+ QList<QList<QPointF *> *> pointListList;
+
+ // For each list of QPointF, that is for each spectrum, store the
+ // increment that was used to perform the calculation, as this is
+ // going to be needed later when performing the final spectrum
+ // summing merge.
+
+ QList<double> incrementList;
+
+ for(int iter = 0,
+ size = mp_oligomerList->size(); iter < size; ++iter)
+ {
+ Oligomer *oligomer = mp_oligomerList->at(iter);
+
+ // 1. Does the user want a isotopic cluster calculation for
+ // each oligomer in the list? If so we have to manage a list
+ // of IsotopicPatternCalculator instances.
+
+ if(m_withCluster)
+ {
+ // Since we have to perform an isotopic cluster
+ // calculation, retrieve the elemental composition.
+ StringProp *prop =
+ static_cast<StringProp *>(oligomer->
+ prop("ELEMENTAL_COMPOSITION"));
+
+ if(!prop)
+ qFatal("Fatal error at %s@%d. Aborting.",__FILE__, __LINE__);
+
+ QString *formulaString = static_cast<QString *>(prop->data());
+
+ Formula formula(*formulaString);
+
+ // We want to validate the formula and in the mean time
+ // construct the list of all the AtomCount objects(first
+ // param true), and since the formula is never reused we
+ // do not need to reset (second param false). m_atomList
+ // is a reference to the atom list of the polymer
+ // chemistry definition currently used in the caller
+ // calculator window.
+ if(!formula.validate(m_atomList, true, false))
+ {
+ m_ui.inputDataFeedbackLineEdit->setText(tr("Formula error"));
+
+ return;
+ }
+
+ double mono = oligomer->mono();
+ double charge = oligomer->charge();
+
+ // Because we have the mono m/z, we can compute the fwhm:
+ double fwhm = (mono / m_resolution);
+ m_config.setFwhm(fwhm);
+
+ double increment = (MXP_FWHM_PEAK_SPAN_FACTOR * fwhm) /
+ m_config.pointNumber();
+
+ // But we have to take into account the charge:
+ if(charge)
+ increment = increment / charge;
+
+ m_config.setIncrement(increment);
+
+ qDebug() << __FILE__ << __LINE__
+ << "index:" << iter << "\n"
+ << "formula: " << formula.formula() << "\n"
+ << "charge:" << charge << "\n"
+ << "mono m/z:" << mono << "\n"
+ << "avg m/z:" << oligomer->avg() << "\n"
+ << "resolution:" << m_resolution << "\n"
+ << "fwhm:" << fwhm << "\n"
+ << "Whole config:" << m_config.config();
+
+ IsotopicPatternCalculator *calculator =
+ new IsotopicPatternCalculator(formula, charge,
+ m_maximumPeaks,
+ m_minimumProbability,
+ m_atomList, m_config);
+
+ // Perform the calculation...
+ QList<QPointF *> &pointList = calculator->sumPeakShapes();
+
+ if(pointList.isEmpty())
+ qFatal("Fatal error at %s@%d.Aborting.", __FILE__, __LINE__);
+
+ // What's the first point of that spectrum? Store the
+ // smallest value for the full spectrum constitution
+ // later-on.
+ curMz = calculator->firstPoint()->x();
+ minMz = (curMz < minMz ? curMz : minMz);
+
+ // What's the last point of that spectrum? Store the
+ // greatest value for the full spectrum constitution
+ // later-on.
+ curMz = calculator->lastPoint()->x();
+ maxMz = (curMz > maxMz ? curMz : maxMz);
+
+ QList<QPointF *> *newPointList = new QList<QPointF *>;
+
+ calculator->transferPoints(newPointList);
+ pointListList.append(newPointList);
+
+ // Store along with the point list, the increment that was
+ // used for that calculation. We'll need it later when
+ // computing the whole spectrum.
+
+ incrementList.append(m_config.increment());
+
+ // At this point we have the points, we can delete the
+ // calculator.
+ delete calculator;
+ }
+ else
+ {
+ // Not asking for an isotopic cluster to be computed for
+ // each oligomer. We still have one alternative: either
+ // mono mz or avg mz should be used as centroid to compute
+ // the peak shape.
+
+ }
+ }
+ // End of
+ // for(int iter = 0,
+ // size = mp_oligomerList->size(); iter < size; ++iter)
+
+ // At this point, with one method or the other, we should have
+ // as many allocated QList<QPointF *> * instances as there are
+ // oligomers. Make that sanity check.
+
+ if(pointListList.size() < mp_oligomerList->size())
+ {
+ qDebug() << __FILE__ << __LINE__
+ << "Generated less unitary spectra than "
+ "there are oligomers.";
+ }
+ else
+ {
+ qDebug() << __FILE__ << __LINE__
+ << "Done generating the unitary spectra for each oligomer.";
+ }
+
+
+ // To compute the spectrum, we have to summ all the points of
+ // all the pointLists together. We know that the start of the
+ // mz axis is at minMz and the end is at maxMz.
+
+ QList<QPointF *> finalSpectrum;
+
+ curMz = minMz;
+
+ while(curMz <= maxMz)
+ {
+ qDebug() << __FILE__ << __LINE__
+ << "Handling mz value:" << curMz;
+
+ // curMz now has a mz value for which we have to sum all the
+ // intensities in each pointList.
+
+ double summedIntensity = 0;
+
+ // Iterate in each spectrum of the list of spectra (that
+ // is each point list of the list of point lists and seek
+ // the intensity at curMz. when found add that intensity
+ // to summedIntensity.
+
+ double increment = 0;
+
+ for(int jter = 0,
+ jSize = pointListList.size(); jter < jSize; ++jter)
+ {
+ increment = incrementList.at(jter);
+
+ QList<QPointF *> *curList = pointListList.at(jter);
+
+ // We are iterating in the list of points of a
+ // spectrum. What is the intensity of the point at x=curMz
+ // ? We provide a tolerance for x corresponding to
+ // (increment / 2).
+
+ for(int kter = 0,
+ kSize = curList->size(); kter < kSize; ++kter)
+ {
+ QPointF *point = curList->at(kter);
+
+ double mz = point->x();
+
+ if(mz <= (curMz + increment / 2) &&
+ mz >= (curMz - increment / 2))
+ {
+ summedIntensity += point->y();
+
+ break;
+ }
+ // Else, go on to next point. If not point is
+ // found at all, then, ok, we do not increment the
+ // summedIntensity variable.
+ }
+ // At this point we have finished iterating in a given
+ // spectrum (that is a point list).
+ }
+ // We have finished iterarting in all the point
+ // lists. Make a point (curMz,summedIntensity).
+
+ QPointF *newPoint = new QPointF(curMz, summedIntensity);
+
+ finalSpectrum.append(newPoint);
+
+ qDebug() << __FILE__ << __LINE__
+ << "Added new point:"
+ << "x:" << newPoint->x() << "," << "y:" << newPoint->y()
+ << "\n";
+
+ curMz += increment;
+ }
+ // End of while(curMz <= maxMz). That is, we have finished
+ // creating (x,y) pairs for the whole x axis, that is the mz
+ // ratio axis.
+
+ qDebug() << __FILE__ << __LINE__
+ << "Ended the creation of the final spectrum.";
+
+
+ // We have a bunch of data to free.
+
+ QPointF *point = 0;
+
+ for(int iter = 0,
+ iSize = pointListList.size(); iter < iSize; ++iter)
+ {
+ QList<QPointF *> *curList = pointListList.at(iter);
+
+ foreach(point, *curList)
+ delete point;
+
+ curList->clear();
+
+ delete curList;
+ }
+
+ qDebug() << __FILE__ << __LINE__
+ << "Done freeing up material.";
+
+ foreach(point, finalSpectrum)
+ {
+ qDebug() << point->x() << " " << point->y();
+
+ delete point;
+ }
+
+ finalSpectrum.clear();
+ }
+
+
+
+
void
SpectrumCalculationDlg::spectrumCalculationProgressValueChanged
diff --git a/gui/spectrumCalculationDlg.hpp b/gui/spectrumCalculationDlg.hpp
index c593196..8a194f8 100644
--- a/gui/spectrumCalculationDlg.hpp
+++ b/gui/spectrumCalculationDlg.hpp
@@ -52,6 +52,7 @@
#include "formula.hpp"
#include "peakShape.hpp"
#include "globals.hpp"
+#include "oligomerList.hpp"
namespace massXpert
@@ -80,10 +81,16 @@ namespace massXpert
private:
Ui::SpectrumCalculationDlg m_ui;
+ // This pointer might be 0 if this dialog window is called from
+ // the XpertCalc window.
+ const Polymer *mp_polymer;
+
SpectrumCalculationMode m_mode;
-
+
const QList<Atom *> &m_atomList;
-
+
+ OligomerList *mp_oligomerList;
+
int m_validationErrors;
QString m_filePath;
@@ -97,7 +104,10 @@ namespace massXpert
PeakShapeConfig m_config;
int m_charge;
-
+
+ bool m_withMonoMass;
+ bool m_withCluster;
+
const PolChemDef &m_polChemDef;
QString m_resultsString;
@@ -121,6 +131,8 @@ namespace massXpert
bool fetchMzRatio(double * = 0, double * = 0);
bool fetchValidateInputData();
+ bool fetchValidateInputDataIsotopicClusterMode();
+ bool fetchValidateInputDataSpectrumMode();
void setInErrorStatus(const QString &);
@@ -130,23 +142,32 @@ namespace massXpert
void debugPutStdErrBitset(QString /*file*/, int /*line*/,
int = 0 /*value*/,
const QString & = QString() /*descString*/);
-
-
+
+ void executeCluster();
+ void executeSpectrum();
+
private slots:
+ void massTypeRadioButtonToggled(bool);
+ void isotopicClusterCheckBoxToggled(bool);
+
void formulaEdited(const QString &);
void chargeChanged(int);
void pointsChanged(int);
void resolutionChanged(int);
void fwhmEdited(const QString &);
+
void execute();
void abort();
void outputFile();
public:
SpectrumCalculationDlg(QWidget *parent,
+ const Polymer *,
const QList<Atom *> &,
SpectrumCalculationMode);
~SpectrumCalculationDlg();
+ void setOligomerList(OligomerList *);
+
signals:
void spectrumCalculationAborted();
diff --git a/gui/ui/spectrumCalculationDlg.ui b/gui/ui/spectrumCalculationDlg.ui
index dbce5ff..a3e96d1 100644
--- a/gui/ui/spectrumCalculationDlg.ui
+++ b/gui/ui/spectrumCalculationDlg.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>622</width>
- <height>337</height>
+ <height>348</height>
</rect>
</property>
<property name="windowTitle">
@@ -45,14 +45,14 @@
<property name="title">
<string>Input data</string>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QGroupBox" name="mzConfigGroupBox">
+ <layout class="QGridLayout" name="gridLayout_11">
+ <item row="0" column="0" rowspan="2">
+ <widget class="QGroupBox" name="mzGroupBox">
<property name="title">
- <string>m/z config.</string>
+ <string>m/z</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0" colspan="4">
+ <item row="0" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_3">
@@ -80,7 +80,7 @@
</property>
</widget>
</item>
- <item row="1" column="1" colspan="3">
+ <item row="1" column="1" colspan="2">
<widget class="QSpinBox" name="chargeSpinBox">
<property name="minimum">
<number>1</number>
@@ -100,23 +100,32 @@
</property>
</widget>
</item>
- <item row="2" column="1" colspan="3">
+ <item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="monoMzRatioLineEdit"/>
</item>
- <item row="3" column="0">
- <spacer name="horizontalSpacer">
+ <item row="3" column="1">
+ <spacer name="verticalSpacer_2">
<property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>25</width>
- <height>20</height>
+ <width>20</width>
+ <height>40</height>
</size>
</property>
</spacer>
</item>
- <item row="3" column="1">
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="massTypeGroupBox">
+ <property name="title">
+ <string>Mass type</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
<widget class="QRadioButton" name="monoRadioButton">
<property name="text">
<string>Mono</string>
@@ -126,78 +135,46 @@
</property>
</widget>
</item>
- <item row="3" column="2">
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="3" column="3">
+ <item row="0" column="1">
<widget class="QRadioButton" name="avgRadioButton">
<property name="text">
<string>Avg</string>
</property>
</widget>
</item>
- <item row="3" column="4">
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="isotopicClusterCheckBox">
+ <property name="text">
+ <string>Isotopic cluster</string>
</property>
- </spacer>
+ </widget>
</item>
</layout>
</widget>
</item>
- <item row="0" column="1" rowspan="2">
- <widget class="QGroupBox" name="spectrumConfigGroupBox">
+ <item row="1" column="1" rowspan="2">
+ <widget class="QGroupBox" name="spectrumGroupBox">
<property name="title">
- <string>Spectrum config.</string>
+ <string>Spectrum</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
- <item row="3" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Min. probability:</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_6">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="gaussianRadioButton">
<property name="text">
- <string>Max. &peaks:</string>
+ <string>gaussian</string>
</property>
- <property name="buddy">
- <cstring>maximumPeaksSpinBox</cstring>
+ <property name="checked">
+ <bool>true</bool>
</property>
</widget>
</item>
- <item row="4" column="1">
- <widget class="QSpinBox" name="maximumPeaksSpinBox">
- <property name="toolTip">
- <string>Maximum number of peaks that must be calculated</string>
- </property>
- <property name="minimum">
- <number>20</number>
- </property>
- <property name="maximum">
- <number>100000</number>
- </property>
- <property name="value">
- <number>20</number>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="lorentzianRadioButton">
+ <property name="text">
+ <string>lorentzian</string>
</property>
</widget>
</item>
@@ -221,23 +198,6 @@
</property>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QRadioButton" name="gaussianRadioButton">
- <property name="text">
- <string>gaussian</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QRadioButton" name="lorentzianRadioButton">
- <property name="text">
- <string>lorentzian</string>
- </property>
- </widget>
- </item>
<item row="2" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
@@ -255,6 +215,13 @@
</property>
</widget>
</item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Min. probability:</string>
+ </property>
+ </widget>
+ </item>
<item row="3" column="1">
<widget class="QLineEdit" name="minimumProbabilityLineEdit">
<property name="toolTip">
@@ -262,26 +229,39 @@
</property>
</widget>
</item>
- <item row="5" column="1">
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Max. &peaks:</string>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
+ <property name="buddy">
+ <cstring>maximumPeaksSpinBox</cstring>
</property>
- </spacer>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QSpinBox" name="maximumPeaksSpinBox">
+ <property name="toolTip">
+ <string>Maximum number of peaks that must be calculated</string>
+ </property>
+ <property name="minimum">
+ <number>20</number>
+ </property>
+ <property name="maximum">
+ <number>100000</number>
+ </property>
+ <property name="value">
+ <number>20</number>
+ </property>
+ </widget>
</item>
</layout>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="resolutionConfigGroupBox">
+ <item row="2" column="0">
+ <widget class="QGroupBox" name="resolutionGroupBox">
<property name="title">
- <string>Resolution config.</string>
+ <string>Resolution</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
@@ -434,6 +414,19 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
+ <item row="2" column="1">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
</item>
diff --git a/lib/isotopicPatternCalculator.cpp b/lib/isotopicPatternCalculator.cpp
index 7c0aebb..d3f894c 100644
--- a/lib/isotopicPatternCalculator.cpp
+++ b/lib/isotopicPatternCalculator.cpp
@@ -144,7 +144,7 @@ namespace massXpert
freeClearPeakCentroidList();
freeClearTempPeakCentroidList();
freeClearPeakShapeList();
- freeClearSpectrum();
+ freeClearPointList();
}
@@ -164,9 +164,9 @@ namespace massXpert
const QList<QPointF *> &
- IsotopicPatternCalculator::spectrum() const
+ IsotopicPatternCalculator::pointList() const
{
- return m_spectrum;
+ return m_pointList;
}
@@ -236,12 +236,12 @@ namespace massXpert
void
- IsotopicPatternCalculator::freeClearSpectrum()
+ IsotopicPatternCalculator::freeClearPointList()
{
- while(!m_spectrum.isEmpty())
- delete m_spectrum.takeFirst();
+ while(!m_pointList.isEmpty())
+ delete m_pointList.takeFirst();
- m_spectrum.clear();
+ m_pointList.clear();
}
@@ -349,10 +349,10 @@ namespace massXpert
QList<QPointF *> &
- IsotopicPatternCalculator::calculateSpectrum()
+ IsotopicPatternCalculator::sumPeakShapes()
{
- // Clear the spectrum.
- freeClearSpectrum();
+ // Clear the point list.
+ freeClearPointList();
// Make sure that we have computed each individual peak shape for
// the centroids. If not, then do it first.
@@ -362,7 +362,7 @@ namespace massXpert
if(!peakShapeListSize)
{
if(!calculatePeakShapes())
- return m_spectrum;
+ return m_pointList;
peakShapeListSize = m_peakShapeList.size();
}
@@ -380,10 +380,10 @@ namespace massXpert
// curves.
// Peak shapes should be generated from left to right in the
- // spectrum view, that is from lowest mz to higest mz. So,
- // logically, the first point of the first peak shape should be
- // the point of lowest mz. Likewise, the last point of the last
- // peak shape should be the highest mz.
+ // pointList spectral view, that is from lowest mz to higest
+ // mz. So, logically, the first point of the first peak shape
+ // should be the point of lowest mz. Likewise, the last point of
+ // the last peak shape should be the highest mz.
PeakShape *peakShape = 0;
QPointF *point = 0;
@@ -434,10 +434,10 @@ namespace massXpert
}
#endif
- // At this point we know that our mass spectrum should range
- // [minMz -- maxMz]. We can perform the actual sum of all the peak
- // shapes. The result of the sum should go into the spectrum list
- // of points.
+ // At this point we know that our mass point list (the spectral
+ // view of the isotopic cluster) should range [minMz -- maxMz]. We
+ // can perform the actual sum of all the peak shapes. The result
+ // of the sum should go into the spectral list of points.
double curMz = minMz;
@@ -461,24 +461,24 @@ namespace massXpert
QPointF *point = new QPointF(curMz, summedIntensity);
- m_spectrum.append(point);
+ m_pointList.append(point);
curMz += m_config.increment();
}
- return m_spectrum;
+ return m_pointList;
}
QString *
- IsotopicPatternCalculator::spectrumAsString() const
+ IsotopicPatternCalculator::pointListAsString() const
{
QString *text = new QString();
- for(int iter = 0, size = m_spectrum.size();
+ for(int iter = 0, size = m_pointList.size();
iter < size ; ++iter)
{
- QPointF *point = m_spectrum.at(iter);
+ QPointF *point = m_pointList.at(iter);
text->append(QString().setNum(point->x(), 'f', 10));
text->append(" ");
@@ -489,6 +489,54 @@ namespace massXpert
return text;
}
+
+ QList<QPointF *> *
+ IsotopicPatternCalculator::duplicatePointList() const
+ {
+ QList<QPointF *> *pointList = new QList<QPointF *>;
+
+ for(int iter = 0, size = m_pointList.size();
+ iter < size ; ++iter)
+ {
+ QPointF *point = new QPointF(*(m_pointList.at(iter)));
+ pointList->append(point);
+ }
+
+ return pointList;
+ }
+
+
+ int
+ IsotopicPatternCalculator::transferPoints(QList<QPointF *> *pointList)
+ {
+ if(!pointList)
+ qFatal("Fatal error at %s@%d.Aborting.", __FILE__, __LINE__);
+
+ int count = 0;
+
+ while(m_pointList.size())
+ {
+ pointList->append(m_pointList.takeFirst());
+ ++count;
+ }
+
+ return count;
+ }
+
+
+ QPointF *
+ IsotopicPatternCalculator::firstPoint() const
+ {
+ return m_pointList.first();
+ }
+
+
+ QPointF *
+ IsotopicPatternCalculator::lastPoint() const
+ {
+ return m_pointList.last();
+ }
+
int
IsotopicPatternCalculator::accountAtomCount(const AtomCount *atomCount)
diff --git a/lib/isotopicPatternCalculator.hpp b/lib/isotopicPatternCalculator.hpp
index bb8ed44..ca97dcf 100644
--- a/lib/isotopicPatternCalculator.hpp
+++ b/lib/isotopicPatternCalculator.hpp
@@ -59,7 +59,7 @@ namespace massXpert
const QList<Atom *> &m_atomRefList;
- QList<QPointF *> m_spectrum;
+ QList<QPointF *> m_pointList;
PeakShapeConfig m_config;
@@ -80,7 +80,7 @@ namespace massXpert
void freeClearPeakCentroidList();
void freeClearTempPeakCentroidList();
void freeClearPeakShapeList();
- void freeClearSpectrum();
+ void freeClearPointList();
int accountAtomCount(const AtomCount *);
int updatePeakCentroidListWithAtom(const Atom *);
@@ -105,12 +105,17 @@ namespace massXpert
const QList<PeakCentroid *> &peakCentroidList() const;
QString *peakCentroidListAsString() const;
- const QList<QPointF *> &spectrum() const;
- QString *spectrumAsString() const;
+ const QList<QPointF *> &pointList() const;
+ QString *pointListAsString() const;
+ QList<QPointF *> *duplicatePointList() const;
+ int transferPoints(QList<QPointF *> *);
+
+ QPointF *firstPoint() const;
+ QPointF *lastPoint() const;
int calculatePeakCentroids();
int calculatePeakShapes();
- QList<QPointF *> &calculateSpectrum();
+ QList<QPointF *> &sumPeakShapes();
signals:
--
massXpert mass spectrometry suite: debian packaging
More information about the Debichem-commits
mailing list