[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:28:42 UTC 2011
The following commit has been merged in the debian branch:
commit 906f095351bbee84ff8af2b66929d36ded05d72a
Author: Filippo Rusconi (Debian Maintainer) <rusconi-debian at laposte.net>
Date: Thu Jun 16 23:23:09 2011 +0200
First buildable version for the reimplementation of the isotopic pattern calculation stuff. Still lots to do.
diff --git a/gui/application.qrc b/gui/application.qrc
index 8337116..f3d0145 100644
--- a/gui/application.qrc
+++ b/gui/application.qrc
@@ -1,5 +1,5 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
+<RCC>
+ <qresource>
<file>images/copy.png</file>
<file>images/cut.png</file>
<file>images/new.png</file>
@@ -10,5 +10,7 @@
<file>images/redled.png</file>
<file>images/splashscreen.png</file>
<file>images/massxpert-icon-32.png</file>
-</qresource>
+ <file>images/smile-bad.png</file>
+ <file>images/smile-fine.png</file>
+ </qresource>
</RCC>
diff --git a/gui/calculatorWnd.hpp b/gui/calculatorWnd.hpp
index 83be5c0..629ea02 100644
--- a/gui/calculatorWnd.hpp
+++ b/gui/calculatorWnd.hpp
@@ -93,7 +93,7 @@ namespace massXpert
bool initialize();
- const PolChemDef & polChemDef();
+ const PolChemDef &polChemDef();
QString polChemDefName();
void updateWindowTitle();
diff --git a/gui/isotopicPatternCalculationDlg.cpp b/gui/isotopicPatternCalculationDlg.cpp
index 7dbc785..1728fe7 100644
--- a/gui/isotopicPatternCalculationDlg.cpp
+++ b/gui/isotopicPatternCalculationDlg.cpp
@@ -78,22 +78,42 @@ namespace massXpert
IsotopicPatternCalculationDlg::IsotopicPatternCalculationDlg
(QWidget *parent, const QList<Atom *> &atomList)
- : QDialog(parent), m_atomList(atomList)
+ : QDialog(parent), m_atomList(atomList),
+ m_polChemDef(static_cast<CalculatorWnd *>(parent)->polChemDef())
{
Q_ASSERT(parent);
m_aborted = false;
+
+ // When the window is created the formula line edit is empty, so
+ // at least that data has an error. The ionization data is most
+ // probably not erroneous because it comes from the polymer
+ // chemistry definition or from the caller.
+ m_validationErrors = MXP_VALIDATION_FORMULA_ERRORS;
+
m_filePath = "";
m_ui.setupUi(this);
// Set the name of the polymer chemistry definition.
- const PolChemDef & polChemDef =
- static_cast<CalculatorWnd *>(parent)->polChemDef();
- m_ui.polChemDefLabel->setText(polChemDef.name());
+ m_ui.polChemDefLabel->setText(m_polChemDef.name());
-
+ // By default we want a gaussian-type curve.
+ m_curveType = MXP_CURVE_TYPE_GAUSSIAN;
+
+ // Feed the ionizeRule widgets with the data. If there is an error
+ // the MXP_VALIDATION_IONIZERULE_ERRORS bit will be automatically set.
+ m_ionizeRule = m_polChemDef.ionizeRule();
+ m_ui.ionizationChargeSpinBox->setValue(m_ionizeRule.charge());
+ m_ui.ionizationLevelSpinBox->setValue(m_ionizeRule.level());
+ m_ui.ionizationFormulaLineEdit->setText(m_ionizeRule.formula());
+
+ // Calculate and show the resulting charge of the ionizable.
+ QString charge;
+ m_charge = m_ionizeRule.charge() * m_ionizeRule.level();
+ charge.setNum(m_charge);
+ m_ui.chargeLabel->setText(charge);
m_ui.minimumProbabilityDoubleSpinBox->setRange(0, 1000000);
m_ui.minimumProbabilityDoubleSpinBox->setValue(0.0001);
@@ -103,14 +123,16 @@ namespace massXpert
m_ui.maximumPeaksSpinBox->setValue(1000);
m_maximumPeaks = 1000;
- m_ui.chargeSpinBox->setRange(0, 1000000);
- m_ui.chargeSpinBox->setValue(1);
- m_charge = 1;
-
+ // Resolution and FWHM stuff
m_ui.resolutionSpinBox->setRange(0, 1000000);
- m_ui.resolutionSpinBox->setValue(15000);
- m_resolution = 15000;
-
+ m_ui.resolutionSpinBox->setValue(0);
+ m_resolution = 0;
+ m_fwhm = 0;
+ // Since both values above are not correct, set the corresponding
+ // bits to the validation error int.
+ m_validationErrors |= MXP_VALIDATION_RESOLUTION_ERRORS;
+ m_validationErrors |= MXP_VALIDATION_FWHM_ERRORS;
+
m_ui.progressBar->setRange(0, 100);
m_ui.progressBar->setValue(0);
@@ -124,6 +146,36 @@ namespace massXpert
settings.endGroup();
+ connect(m_ui.ionizationFormulaLineEdit,
+ SIGNAL(textChanged(const QString &)),
+ this,
+ SLOT(ionizationDataChanged()));
+
+ connect(m_ui.ionizationChargeSpinBox,
+ SIGNAL(valueChanged(int)),
+ this,
+ SLOT(ionizationDataChanged()));
+
+ connect(m_ui.ionizationLevelSpinBox,
+ SIGNAL(valueChanged(int)),
+ this,
+ SLOT(ionizationDataChanged()));
+
+ connect(m_ui.formulaLineEdit,
+ SIGNAL(textChanged(const QString &)),
+ this,
+ SLOT(formulaChanged(const QString &)));
+
+ connect(m_ui.resolutionSpinBox,
+ SIGNAL(valueChanged(int)),
+ this,
+ SLOT(resolutionChanged(int)));
+
+ connect(m_ui.fwhmLineEdit,
+ SIGNAL(textEdited(const QString &)),
+ this,
+ SLOT(fwhmEdited(const QString &)));
+
connect(m_ui.executePushButton,
SIGNAL(clicked()),
this,
@@ -162,8 +214,6 @@ namespace massXpert
IsotopicPatternCalculationDlg::~IsotopicPatternCalculationDlg()
{
-
-
}
@@ -172,58 +222,46 @@ namespace massXpert
{
Application *application = static_cast<Application *>(qApp);
- QString formula = m_ui.formulaLineEdit->text();
-
- if (!formula.isEmpty())
- m_formula.setFormula(formula);
- else
+ // 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).
+
+ if(m_validationErrors != MXP_VALIDATION_ERRORS_NONE)
{
- QMessageBox::warning(0,
- tr("massXpert: Isotopic Pattern Calculation"),
- tr("Enter a valid formula."),
- QMessageBox::Ok);
- return false;
+ return false;
}
-
- // We want to validate the formula and in the mean time construct
- // the list of all the AtomCount objects(first true), and since
- // the formula is reused we also ensure that that list is reset
- //(second true).
-
- if (!m_formula.validate(m_atomList, true, true))
+
+ // We still have to fetch a number of parameters.
+
+ // Get to know if we want gaussian or lorentzian curves.
+ if(m_ui.gaussianRadioButton->isChecked())
{
- QMessageBox::warning(0,
- tr("massXpert: Isotopic Pattern Calculation"),
- tr("Formula(%1) is not valid.")
- .arg(formula),
- QMessageBox::Ok);
- return false;
+ m_curveType = MXP_CURVE_TYPE_GAUSSIAN;
}
+ else
+ {
+ m_curveType = MXP_CURVE_TYPE_LORENTZIAN;
+ }
+
// Shall we use localization for all the numerical output?
- bool locale = m_ui.localeCheckBox->checkState() == Qt::Checked ?
+ bool isUsingLocale = m_ui.localeCheckBox->checkState() == Qt::Checked ?
true : false;
-
int totAtoms = m_formula.totalAtoms();
m_ui.progressBar->setRange(0, totAtoms);
int totIsotopes = m_formula.totalIsotopes(m_atomList);
- m_mono = 0;
- m_avg = 0;
-
- if (!m_formula.accountMasses(m_atomList, &m_mono, &m_avg, 1))
- return false;
-
QString textEditText;
- if (locale)
+ if (isUsingLocale)
textEditText += tr("INPUT\n=====\n\nformula: %1\n"
"Mono Mass: %2 \t Avg mass: %3\n"
"Total number of atoms: %4\n"
"Total number of isotopes: %5")
- .arg(formula)
+ .arg(m_formula.formula())
.arg(application->locale().
toString(m_mono, 'f', MXP_OLIGOMER_DEC_PLACES))
.arg(application->locale().
@@ -234,7 +272,7 @@ namespace massXpert
textEditText += tr("INPUT\n=====\n\nformula: %1\n"
"Mono mass: %2 \t Avg mass: %3\n"
"Total number of 1) atoms: %4 ; 2) isotopes: %5\n\n")
- .arg(formula)
+ .arg(m_formula.formula())
.arg(QString().setNum(m_mono, 'f', MXP_OLIGOMER_DEC_PLACES))
.arg(QString().setNum(m_avg, 'f', MXP_OLIGOMER_DEC_PLACES))
.arg(totAtoms)
@@ -258,104 +296,500 @@ namespace massXpert
return false;
}
- m_charge = m_ui.chargeSpinBox->value();
- m_resolution = m_ui.resolutionSpinBox->value();
+ // 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_points = m_ui.pointsSpinBox->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_points;
+
+ // First however, see if the user wants to use the FWHM value or
+ // the resolution.
+
+ if(m_fwhm)
+ {
+ // FWHM is not zero, which means the user has set a value for
+ // it. Keep it.
+ }
+ else
+ {
+ // We have to compute the FWHM starting from the mz ratio and
+ // the resolution.
+
+ m_fwhm = m_mono / m_resolution;
+ }
+
+ // Now set the increment.
+ m_increment = m_ui.incrementSpinBox->value();
+ if(!m_increment)
+ m_increment = 2*(m_fwhm / m_points);
+
+ // Set the maximum number of peaks in the isotopic curve.
m_maximumPeaks = m_ui.maximumPeaksSpinBox->value();
-
- textEditText += tr("Charge: %1 ; Resolution: %2 ; Maximum peaks: %3 ;")
- .arg(m_charge)
- .arg(m_resolution)
- .arg(m_maximumPeaks);
+ QString fwhmString = m_ui.fwhmLineEdit->text();
+ // Set the minimum probability each isotopic peak must have to be
+ // retained in the final curve.
m_minimumProbability = m_ui.minimumProbabilityDoubleSpinBox->value();
- textEditText += tr(" Minimum probability: ");
- if (locale)
- textEditText += application->locale().
- toString(m_minimumProbability, 'f', MXP_OLIGOMER_DEC_PLACES);
- else
- textEditText += QString().
- setNum(m_minimumProbability, 'f', MXP_OLIGOMER_DEC_PLACES);;
-
- textEditText +=
- tr("\n\nGaussian simulation of a single peak is performed by "
- "computing 25 points on each side of the isotopic mass "
- "according to the following exponential:\n"
- "f(x) = relativeIntensity * exp(( -(x - mono)^2 ) / c^2 )\n\n"
- "Full Width At Half Maximum = "
- "(mono / resolution) = 2 * sqrt(ln(2) * c \n");
+
+ return true;
+ }
+
- double fullWidthHalfMax = m_mono / m_resolution;
- textEditText += tr("FWHM = ");
- if (locale)
- textEditText += application->locale().
- toString(fullWidthHalfMax, 'f', MXP_OLIGOMER_DEC_PLACES);
- else
- textEditText += QString().
- setNum(fullWidthHalfMax, 'f', MXP_OLIGOMER_DEC_PLACES);;
+ bool
+ IsotopicPatternCalculationDlg::fetchIonizationRuleData(IonizeRule *ionizeRule)
+ {
+ if(!ionizeRule)
+ qFatal("Fatal error at %s@%d.Aborting.", __FILE__, __LINE__);
+
+ // We feed the ionizeRule instance with the currently inserted
+ // data in the ionize rule widgets.
+
+ QString text = m_ui.ionizationFormulaLineEdit->text();
+ Formula formula(text);
+ if (!formula.validate(m_atomList, false, true))
+ return false;
+
+ int unitCharge = m_ui.ionizationChargeSpinBox->value();
+ int level = m_ui.ionizationLevelSpinBox->value();
+
+ m_charge = unitCharge * level;
+ QString ionChargeString;
+ ionChargeString.setNum(m_charge);
+ m_ui.chargeLabel->setText(ionChargeString);
+
+ ionizeRule->setFormula(text);
+ ionizeRule->setCharge(unitCharge);
+ ionizeRule->setLevel(level);
+
+ // Validate the ionization rule, because it might be set with
+ // m_isValid=false (in particular if the instance was constructed
+ // with non contructor parameters).
+
+ if(!ionizeRule->validate(m_atomList))
+ return false;
+
+ return true;
+ }
- textEditText += "\n";
- double c = fullWidthHalfMax /(2 * sqrt(log(2)));
- double c2 = pow(c, 2);
+ // Returns false if formula is bad or aborts if calculation fails..
+ bool
+ IsotopicPatternCalculationDlg::fetchFormulaMass(double *mono, double *avg)
+ {
+ // Check if there are currently errors set.
+
+ if((m_validationErrors | MXP_VALIDATION_FORMULA_ERRORS) ==
+ MXP_VALIDATION_FORMULA_ERRORS)
+ return false;
+
+ double monoMass = 0;
+ double avgMass = 0;
+
+ // It is impossible that we have an error here, since the formula
+ // was previously validated (MXP_VALIDATION_FORMULA_ERRORS above).
+ if (!m_formula.accountMasses(m_atomList, &monoMass, &avgMass, 1))
+ qFatal("Fatal error at %s@%d.Aborting.", __FILE__, __LINE__);
+
+ if(mono)
+ *mono = monoMass;
+
+ if(avg)
+ *avg = avgMass;
+
+ // qDebug() << __FILE__ << __LINE__
+ // << "Formula mono/avg masses:"
+ // << monoMass << "/" << avgMass;
- textEditText += tr("with c = ");
- if (locale)
- textEditText += application->locale().
- toString(c, 'f', MXP_OLIGOMER_DEC_PLACES);
- else
- textEditText += QString().setNum(c, 'f', MXP_OLIGOMER_DEC_PLACES);;
+ return true;
+ }
+
+ // Returns false if the formula is not validated and aborts if an
+ // error occurs while the formula was validated.
+ bool
+ IsotopicPatternCalculationDlg::fetchMzRatio(double *mono, double *avg)
+ {
+ // Check if there are currently errors set either in the formula
+ // or in the ionization rule.
+
+ // Show what's the value of the errors.
+ debugPutStdErr(__FILE__, __LINE__,
+ m_validationErrors, "m_validationErrors");
+
+ if((m_validationErrors | MXP_VALIDATION_FORMULA_ERRORS) ==
+ MXP_VALIDATION_FORMULA_ERRORS)
+ {
+ qDebug() << __FILE__ << __LINE__
+ << "Returning false";
+
+ return false;
+ }
+
+ if ((m_validationErrors | MXP_VALIDATION_IONIZERULE_ERRORS) ==
+ MXP_VALIDATION_IONIZERULE_ERRORS)
+ {
+ qDebug() << __FILE__ << __LINE__
+ << "Returning false";
+
+ return false;
+ }
+
+ // The ionization data have already been automatically fetched and
+ // set to m_ionizeRule when the data in the widgets changed using
+ // the correponding slot.
+
+ // Same for the formula in m_formula.
+
+ // We can compute the m/z ratio.
+
+ double monoMass = 0;
+ double avgMass = 0;
+
+ fetchFormulaMass(&monoMass, &avgMass);
+
+ qDebug() << __FILE__ << __LINE__
+ << "monoMass:" << monoMass
+ << "avgMass:" << avgMass;
+
+ // Note that the only acceptable value returned here is mono > 0,
+ // because the formula was validated and thus mass calculation
+ // should not fail. Indeed, if there is a failure in the called
+ // function, qFatal is triggered. No need, thus, to check the
+ // status of the call. It cannot fail.
+
+ // Compute the m/z ratio.
+
+ Ponderable ponderable(monoMass, avgMass);
+
+ // We create an ionizable using the ponderable above, which has
+ // masses computed only with the formula, that is for a
+ // non-ionized molecule.
+ Ionizable ionizable(&m_polChemDef, QString("NOT_SET"),
+ ponderable, m_ionizeRule, false);
+
+ // Set the charge of the ionizable. That is not the charge of
+ // ionizeRule ! That is the real charge of the ion ! Get it out of
+ // the chargeLabel, which allows us to track if errors were
+ // silently passing by.
+
+ bool ok = false;
+
+ int ionCharge = m_ui.chargeLabel->text().toInt(&ok);
+
+ if(!ionCharge && !ok)
+ qFatal("Fatal error at %s@%d.Aborting.", __FILE__, __LINE__);
+
+ // qDebug() << __FILE__ << __LINE__
+ // << "The ion whole charge is:" << ionCharge;
+
+ // The ionization will be performed automatically upon setting the
+ // charge of the ion ! The ionization above must perform
+ // correctly, because the ionizable was created not ionized. Thus
+ // the call below has to return 1.
+
+ int res = ionizable.setCharge(ionCharge);
+
+ // qDebug() << __FILE__ << __LINE__
+ // << "Ionization result: " << res;
+
+ if (res != 1)
+ qFatal("Fatal error at %s@%d.Aborting.", __FILE__, __LINE__);
+
+ // At this point the ionizable has the right mzRatio.
+
+ if(mono)
+ *mono = ionizable.mono();
+
+ if(avg)
+ *avg = ionizable.mono();
+
+ return true;
+ }
- textEditText += tr(" and c^2 = ");
- if (locale)
- textEditText += application->locale().
- toString(c2, 'f', MXP_OLIGOMER_DEC_PLACES);
- else
- textEditText += QString().setNum(c2, 'f', MXP_OLIGOMER_DEC_PLACES);;
+
+ void
+ IsotopicPatternCalculationDlg::ionizationDataChanged()
+ {
+ // When text changes, we have to update the smiley to indicate if
+ // the formula is OK or not.
+ IonizeRule ionizeRule;
+
+ // The call below will take care of setting m_charge to the proper
+ // value.
+ if(!fetchIonizationRuleData(&ionizeRule))
+ {
+ // Set the error bit.
+ m_validationErrors |= MXP_VALIDATION_IONIZERULE_ERRORS;
+
+ m_ui.monoMzRatioLineEdit->setText("0.000");
+ m_ui.chargeLabel->setText("0");
+ m_ui.inputDataFeedbackLineEdit->setText(tr("Ionization data error"));
+
+ return ;
+ }
+
+ // Clear the bit as there is no error here.
+ m_validationErrors &= ~MXP_VALIDATION_IONIZERULE_ERRORS;
+
+ m_ui.inputDataFeedbackLineEdit->setText(tr("Ionization data fine"));
+
+ // Now that we know the ionization rule is valid, set it to the
+ // member instance.
+ m_ionizeRule = ionizeRule;
+
+ updateMzRatio();
+
+ return;
+ }
- textEditText += "\n============================================\n\n";
+ void
+ IsotopicPatternCalculationDlg::resolutionChanged(int value)
+ {
+ // 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
+ // will be the value taken into account.
+
+ if(value <= 0)
+ {
+ // Tell the user to set a valid FWHM value, then.
+ m_ui.inputDataFeedbackLineEdit->setText
+ (tr("Set a valid FWHM value"));
+
+ m_ui.resolutionSpinBox->setValue(0);
+
+ // Clear the bit as there is no error here.
+ m_validationErrors &= ~MXP_VALIDATION_RESOLUTION_ERRORS;
+
+ return;
+ }
+
+ m_resolution = value;
+
+ m_ui.inputDataFeedbackLineEdit->setText
+ (tr("Will use the resolution"));
+
+ // Clear the bit as there is no error here.
+ m_validationErrors &= ~MXP_VALIDATION_RESOLUTION_ERRORS;
+
+ // Clear the fwhm value, as we want to use the resolution and
+ // clear the error bit also, so we are all clean.
+
+ m_ui.fwhmLineEdit->setText("0");
+ m_fwhm = 0;
+ m_validationErrors &= ~MXP_VALIDATION_FWHM_ERRORS;
+
+ return;
+ }
- // Out put some text in the textEdit:
- m_ui.resultTextEdit->append(textEditText);
+
+ void
+ IsotopicPatternCalculationDlg::fwhmEdited(const QString &text)
+ {
+ // If the text was edited in the line edit, that means that the
+ // user wants the FWHM to be taken into account for calculation of
+ // the peak width, and not the resolution. Only if FWHM is set to
+ // 0, resolution will be the value taken into account.
- return true;
+ QString txt = m_ui.fwhmLineEdit->text();
+
+ bool ok = false;
+
+ int fwhmValue = txt.toInt(&ok);
+
+ if(!fwhmValue && !ok)
+ {
+ // Set the error bit.
+ m_validationErrors |= MXP_VALIDATION_FWHM_ERRORS;
+
+ m_ui.inputDataFeedbackLineEdit->setText
+ (tr("Fix the FWHM value, please"));
+
+ return;
+ }
+
+ // But the value might be faithfully 0, if the user is telling us
+ // that she wants to take the resolution into account and not the
+ // FWHM.
+
+ if(!fwhmValue)
+ {
+ m_ui.inputDataFeedbackLineEdit->setText
+ (tr("Set a valid resolution value"));
+
+ // Clear the bit as there is no error here.
+ m_validationErrors &= ~MXP_VALIDATION_FWHM_ERRORS;
+
+ return;
+ }
+
+ // At this point we know that fwhmValue contains a proper value.
+
+ m_ui.inputDataFeedbackLineEdit->setText
+ (tr("Will use the FWHM"));
+
+ m_validationErrors &= ~MXP_VALIDATION_FWHM_ERRORS;
+
+ m_fwhm = fwhmValue;
+
+ // Set the resolution spinbox to 0 and clear the associated
+ // validation error bit.
+ m_resolution = 0;
+ m_ui.resolutionSpinBox->setValue(0);
+ m_validationErrors &= ~MXP_VALIDATION_RESOLUTION_ERRORS;
+
+ return;
}
+
void
- IsotopicPatternCalculationDlg::execute()
+ IsotopicPatternCalculationDlg::formulaChanged(const QString &text)
{
+ // New text contains a new formula. Check it.
+
+ if(text.isEmpty())
+ {
+ // Set the error bit.
+ m_validationErrors |= MXP_VALIDATION_FORMULA_ERRORS;
+
+ m_ui.monoMzRatioLineEdit->setText("0.000");
+ m_ui.inputDataFeedbackLineEdit->setText(tr("Formula error"));
+
+ return;
+ }
+
+ Formula formula(text);
+
+ // Do not bother storing all the atoms in the formula, this is
+ // only a check (false param below). 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, false, true))
+ {
+ // Set the error bit.
+ m_validationErrors |= MXP_VALIDATION_FORMULA_ERRORS;
+
+ m_ui.monoMzRatioLineEdit->setText("0.000");
+ m_ui.inputDataFeedbackLineEdit->setText(tr("Formula error"));
+
+ return;
+ }
+
+ // qDebug() << __FILE__ << __LINE__
+ // << "Formula:" << formula.formula() << "validated." ;
+
+ // At this point we know we could actually validate the formula,
+ // so do that work with the member formula:
+
+ // We want to validate the formula and in the mean time construct
+ // the list of all the AtomCount objects(first true), and since
+ // the formula is reused we also ensure that that list is reset
+ // (second true). m_atomList is a reference to the atom list of
+ // the polymer chemistry definition currently used in the caller
+ // calculator window.
+
+ m_formula.setFormula(text);
+ m_formula.validate(m_atomList, true, true);
+
+ // Clear the bit as there is no error here.
+ m_validationErrors &= ~MXP_VALIDATION_FORMULA_ERRORS;
+
+ m_ui.inputDataFeedbackLineEdit->setText(tr("Formula fine"));
+
+ // qDebug() << __FILE__ << __LINE__
+ // << "Going to call updateMzRatio.";
+
+ updateMzRatio();
+
+ return;
+ }
+
+
+ bool
+ IsotopicPatternCalculationDlg::updateMzRatio()
+ {
+ // Set the mz ratio to our member data variable.
+ bool res = fetchMzRatio(&m_mono, &m_avg);
+
+ // If res is falsed, that means that the formula is not validated
+ // at present. Silently return.
+ if(!res)
+ {
+ qDebug() << __FILE__ << __LINE__
+ << "Failed to fetch mz ratio.";
+
+ return false;
+ }
+
Application *application = static_cast<Application *>(qApp);
+
+ QString mzRatio = application->locale().
+ toString(m_mono, 'f', MXP_OLIGOMER_DEC_PLACES);
+
+ m_ui.monoMzRatioLineEdit->setText(mzRatio);
- bool inserted = false;
- int wholeCount = 0;
+ return true;
+ }
+
+
+ void
+ IsotopicPatternCalculationDlg::execute()
+ {
+ // We are asked to launch the calculation. But we ought to make
+ // sure that all the required data are set fine.
+ if(!fetchValidateInputData())
+ {
+ QMessageBox::warning(0,
+ tr("massXpert - Isotopic Pattern Calculation"),
+ tr("Please fix the input data first."),
+ QMessageBox::Ok);
+ return;
+ }
+
// Clear the textEdit widget so that we can start out-putting text
// into it.
m_ui.resultTextEdit->clear();
- if (!fetchValidateInputData())
- return;
-
- double fullWidthHalfMax = m_mono / m_resolution;
-
+ // We start computing the peaks in the isotopic cluster.
+ m_ui.feedbackLineEdit->setText(tr("Computing the peaks in the cluster."));
+
+ // We are going to compute a set of mzRatio/intensity pairs
+ // corresponding to the centroid of all the gaussian/lorentzian
+ // curves that will together make the isotopic cluster.
- QList<IsotopicPeak *> oldPeakList;
+ // Each centroid peak will be stored in a list of peaks:
+ QList<IsotopicPeak *> centroidPeakList;
- IsotopicPeak *firstPeak = new IsotopicPeak();
+ // Let's seed all the calculations with the first centroid peak.
+ IsotopicPeak *firstPeak = new IsotopicPeak(0, 0, 0, 0);
+
firstPeak->setMass(0);
firstPeak->setProbability(1);
-
- oldPeakList.append(firstPeak);
+ centroidPeakList.append(firstPeak);
- // After the validation of the formula, it contains a list of
- // allocated AtomCount objects. Get a handy shorthand to it.
+ // When the m_formula was validated, we had asked that the atoms
+ // be stored in its list. Get a handy shorthand to it.
const QList<AtomCount *> &atomCountList = m_formula.atomCountList();
QTime time;
time.start();
-
- m_ui.feedbackLineEdit->setText(tr("Computing the peaks in the pattern."));
+
+ Application *application = static_cast<Application *>(qApp);
+
+ bool inserted = false;
+ int wholeCount = 0;
+
+ // Iterate in the list of AtomCount instances corresponding to the
+ // formula for which the isotopic cluster is to be computed.
for (int iter = 0; iter < atomCountList.size(); ++iter)
{
@@ -365,6 +799,12 @@ namespace massXpert
// qDebug() << "Current atom:" << atomCount->symbol()
// << "with" << isotopeCount << "isotope(s)";
+ // One atom count instance is a pair of values : an atom and
+ // the number of times that atom occurs in the formula. Each
+ // atom, in turn has a list of isotopes. We iterate in that
+ // list of isotopes and take them into account according to
+ // their abundance.
+
for(int jter = 0; jter < atomCount->count(); ++jter)
{
// qDebug() << "Atom count:"<< atomCount->count()
@@ -379,28 +819,22 @@ namespace massXpert
QList<IsotopicPeak *> newPeakList;
- for (int kter = 0; kter < oldPeakList.size(); ++kter)
+ for (int kter = 0; kter < centroidPeakList.size(); ++kter)
{
- IsotopicPeak *peakListPeak = oldPeakList.at(kter);
+ IsotopicPeak *centroidPeak = centroidPeakList.at(kter);
for(int lter = 0; lter < isotopeCount; ++lter)
{
Isotope *isotope = atomCount->isotopeList().at(lter);
- // qDebug() << "Current isotope:" << isotope->mass();
-
IsotopicPeak *newPeak =
- new IsotopicPeak(peakListPeak->mass() +
+ new IsotopicPeak(centroidPeak->mass() +
isotope->mass(),
- 0,
- peakListPeak->probability() *
- (isotope->abundance() / 100),
- 0);
-
- // qDebug() << "Newly created peak:"
- // << newPeak->mass() << "--"
- // << newPeak->probability();
-
+ 0,
+ centroidPeak->probability() *
+ (isotope->abundance() / 100),
+ 0);
+
if (!newPeakList.size())
{
newPeakList.append(newPeak);
@@ -456,24 +890,28 @@ namespace massXpert
// << "--"
// << newPeakList.at(zter)->probability();
}
- }
+ }
+ // End of
+ // for(int lter = 0; lter < isotopeCount; ++lter)
}
+ // End of
+ // for (int kter = 0; kter < centroidPeakList.size(); ++kter)
- qDeleteAll(oldPeakList);
- oldPeakList.clear();
+ qDeleteAll(centroidPeakList);
+ centroidPeakList.clear();
- oldPeakList = newPeakList;
+ centroidPeakList = newPeakList;
newPeakList.clear();
// We now have to remove peaks that are too near one from
// the other.
- for (int nter = 0; nter < oldPeakList.size() - 1; ++nter)
+ for (int nter = 0; nter < centroidPeakList.size() - 1; ++nter)
{
- double absDiff = fabs(oldPeakList.at(nter)->mass() -
- oldPeakList.at(nter + 1)->mass());
+ double absDiff = fabs(centroidPeakList.at(nter)->mass() -
+ centroidPeakList.at(nter + 1)->mass());
- if(absDiff <= fullWidthHalfMax)
+ if(absDiff <= m_fwhm)
{
// qDebug() << "absDiff is" << absDiff;
@@ -481,28 +919,28 @@ namespace massXpert
// current one, but do not forget to account for
// that one from the abundance point of vue.
- oldPeakList.at(nter)->
- incrementProbability(oldPeakList.at(nter + 1)->
+ centroidPeakList.at(nter)->
+ incrementProbability(centroidPeakList.at(nter + 1)->
probability());
// qDebug() << "Removed peak"
- // << oldPeakList.at(nter + 1)->mass() << "--"
- // << oldPeakList.at(nter + 1)->probability();
+ // << centroidPeakList.at(nter + 1)->mass() << "--"
+ // << centroidPeakList.at(nter + 1)->probability();
- delete oldPeakList.takeAt(nter + 1);
+ delete centroidPeakList.takeAt(nter + 1);
--nter;
}
}
- if (m_maximumPeaks >= 2 && oldPeakList.size() > m_maximumPeaks)
+ if (m_maximumPeaks >= 2 && centroidPeakList.size() > m_maximumPeaks)
{
// The user wants at most m_maximumPeaks peaks, which means
// we have to remove all the ones in excess.
for(int pter = m_maximumPeaks;
- pter < oldPeakList.size(); ++pter)
+ pter < centroidPeakList.size(); ++pter)
{
- delete oldPeakList.takeAt(pter);
+ delete centroidPeakList.takeAt(pter);
}
}
}
@@ -510,8 +948,11 @@ namespace massXpert
if(m_aborted)
break;
}
+ // End of
+ // for (int iter = 0; iter < atomCountList.size(); ++iter)
+
m_aborted = false;
-
+
m_ui.progressBar->setRange(0, 100);
m_ui.progressBar->setValue(0);
@@ -528,13 +969,14 @@ namespace massXpert
double sumProbabilities = 0;
double greatestProbability = 0;
- for (int iter = 0; iter < oldPeakList.size(); ++iter)
+ for (int iter = 0; iter < centroidPeakList.size(); ++iter)
{
- IsotopicPeak *isotopicPeak = oldPeakList.at(iter);
+ IsotopicPeak *isotopicPeak = centroidPeakList.at(iter);
isotopicPeak->setMass(isotopicPeak->mass() / m_charge);
sumProbabilities += isotopicPeak->probability();
+
if(isotopicPeak->probability() > greatestProbability)
greatestProbability = isotopicPeak->probability();
}
@@ -545,24 +987,24 @@ namespace massXpert
if (m_charge > 1)
{
- for(int nter = 0; nter < oldPeakList.size() - 1; ++nter)
+ for(int nter = 0; nter < centroidPeakList.size() - 1; ++nter)
{
- if (fabs(oldPeakList.at(nter)->mass() -
- oldPeakList.at(nter + 1)->mass()) <= fullWidthHalfMax)
+ if (fabs(centroidPeakList.at(nter)->mass() -
+ centroidPeakList.at(nter + 1)->mass()) <= m_fwhm)
{
// Remove the forward peak that is too close to
// current one, but do not forget to account for
// that one from the abundance point of vue.
- oldPeakList.at(nter)->
- incrementProbability(oldPeakList.at(nter + 1)->
+ centroidPeakList.at(nter)->
+ incrementProbability(centroidPeakList.at(nter + 1)->
probability());
// qDebug() << "Removed peak"
- // << oldPeakList.at(nter + 1)->mass() << "--"
- // << oldPeakList.at(nter + 1)->probability();
+ // << centroidPeakList.at(nter + 1)->mass() << "--"
+ // << centroidPeakList.at(nter + 1)->probability();
- delete oldPeakList.takeAt(nter + 1);
+ delete centroidPeakList.takeAt(nter + 1);
}
}
}
@@ -571,9 +1013,9 @@ namespace massXpert
// Compute the relative intensity.
- for (int iter = 0; iter < oldPeakList.size(); ++iter)
+ for (int iter = 0; iter < centroidPeakList.size(); ++iter)
{
- IsotopicPeak *isotopicPeak = oldPeakList.at(iter);
+ IsotopicPeak *isotopicPeak = centroidPeakList.at(iter);
double relativeIntensity =
( isotopicPeak->probability() / greatestProbability) * 100;
@@ -584,43 +1026,36 @@ namespace massXpert
int elapsedTime = time.elapsed() /(1000 * 60);
- // And now we should do something with the peaks !!!
-
- m_ui.feedbackLineEdit->setText(tr("Formatting the results"));
-
- bool locale = m_ui.localeCheckBox->checkState() == Qt::Checked ?
+ // Shall we use localization for all the numerical output?
+ bool isUsingLocale = m_ui.localeCheckBox->checkState() == Qt::Checked ?
true : false;
-
- double c = fullWidthHalfMax /(2 * sqrt(log(2)));
- double c2 = pow(c, 2);
- double increment = fullWidthHalfMax / 50;
QString results(tr("RESULTS for this computation(duration: %1 min)\n"
"====================================\n\n").
arg(elapsedTime));
- for (int oter = 0; oter < oldPeakList.size(); ++oter)
+ for (int oter = 0; oter < centroidPeakList.size(); ++oter)
{
- double mass = oldPeakList.at(oter)->mass();
- double prob = oldPeakList.at(oter)->probability();
- double relInt = oldPeakList.at(oter)->relativeIntensity();
+ double mass = centroidPeakList.at(oter)->mass();
+ double prob = centroidPeakList.at(oter)->probability();
+ double relInt = centroidPeakList.at(oter)->relativeIntensity();
if(prob > m_minimumProbability)
{
results += tr("Mass: ");
- if (locale)
+ if(isUsingLocale)
results += application->locale().
toString(mass, 'f', MXP_OLIGOMER_DEC_PLACES);
else
results += QString().setNum(mass, 'f', MXP_OLIGOMER_DEC_PLACES);
results += tr(" -- Probability: ");
- if (locale)
+ if(isUsingLocale)
results += application->locale().
toString(prob, 'f', MXP_OLIGOMER_DEC_PLACES);
else
results += QString().setNum(prob, 'f', MXP_OLIGOMER_DEC_PLACES);
results += tr(" -- Rel. intensity: ");
- if (locale)
+ if(isUsingLocale)
results += application->locale().
toString(relInt, 'f', MXP_OLIGOMER_DEC_PLACES);
else
@@ -629,118 +1064,133 @@ namespace massXpert
results += "\n";
}
}
-
- m_ui.resultTextEdit->append(results);
- // qDebug() << "fullWidthHalfMax" << fullWidthHalfMax
- // << "x-increment" << increment
- // << "c" << c
- // << "c^2" << c2;
-
- // For each isotopic peak, compute a gaussian.
- // Write the results to the file, peak after peak.
+ qDebug() << __FILE__ << __LINE__
+ << results;
+
+
+ // For each Centroid peak, we should make a real curve, that is
+ // created either a gaussian or a lorentzian curve.
- QFile file(m_filePath);
- QTextStream stream;
-
- bool ret = file.open(QIODevice::WriteOnly |
- QIODevice::Truncate |
- QIODevice::Text);
- if (ret)
+ QList<IsotopicCurve *>curveList;
+
+ for (int iter = 0; iter < centroidPeakList.size(); ++iter)
{
- stream.setDevice(&file);
- stream.setCodec("UTF-8");
+ IsotopicPeak *peak = centroidPeakList.at(iter);
+
+ double mass = peak->mass();
+ double relInt = peak->relativeIntensity();
+
+ IsotopicCurve *curve = new IsotopicCurve(mass,
+ relInt,
+ m_fwhm,
+ m_points,
+ m_increment,
+ 1 /* normFactor */,
+ m_curveType);
+
+ curve->calculateCurve();
+
+ curveList.append(curve);
}
- else
+
+ // At this point, each Centroid peak, that is each mzRatio/intensity
+ // pair in centroidPeakList has given rise to a full
+ // gaussian/lorentzian curve that's been appended in curveList.
+
+ // We now have to perform the sum of all these curves so as to
+ // generate a single curve that encompasses all the isotopic
+ // cluster.
+
+ // First off, get the min/max mzRatio of all the curves.
+
+ int curveCount = curveList.size();
+
+ double tempMzRatio = 0;
+ double maxMzRatio = 0;
+ double minMzRatio = 1000000000;
+
+ for(int iter = 0; iter < curveCount ; ++iter)
{
- QMessageBox::warning(0,
- tr("massXpert - Isotopic Pattern Calculation"),
- tr("Failed to export "
- "the data: file could not be opened."),
- QMessageBox::Ok);
+ IsotopicCurve *curve = curveList.at(iter);
+
+ // Get to the list of points in
+ const QList<IsotopicPeak *> &peakList =
+ curve->isotopicPeakList();
+
+ // Get first point of the curve.
+ IsotopicPeak *peak = peakList.first();
+
+ // Get the minimum mzRatio
+ tempMzRatio = peak->mass();
- stream.setStatus(QTextStream::ReadCorruptData);
+ if(tempMzRatio < minMzRatio)
+ minMzRatio = tempMzRatio;
+
+ // Get last point of the curve.
+ peak = peakList.last();
+
+ // Get the maximum mzRatio
+ tempMzRatio = peak->mass();
+
+ if(tempMzRatio > maxMzRatio)
+ maxMzRatio = tempMzRatio;
}
- for (int iter = 0; iter < oldPeakList.size(); ++iter)
+ // At this point we know that our absorption spectrum should range
+ // [minMzRatio -- maxMzRatio]. We can perform the actual sum of
+ // all the isotopic curves. First off, empty the m_isotopicCurve.
+
+ m_isotopicCurve.emptyPeakList();
+
+ double curMzRatio = minMzRatio;
+
+ while(curMzRatio <= maxMzRatio)
{
- double prob = oldPeakList.at(iter)->probability();
-
- // If the formula has a big number of atoms, then the first few
- // peaks will be of almost negligible probability, and we'll
- // want to skip them.
- if(prob < m_minimumProbability)
- continue;
-
- double mono = oldPeakList.at(iter)->mass();
- double relInt = oldPeakList.at(iter)->relativeIntensity();
+ // curMzRatio now has a mzRatio value for which we have to
+ // sum all the intensities in each curve.
- double leftPoint = mono -(2 * fullWidthHalfMax);
- double rightPoint = mono +(2 * fullWidthHalfMax);
+ double summedIntensity = 0;
- QString outputString;
- stream << outputString;
- outputString.clear();
+ for(int iter = 0; iter < curveCount ; ++iter)
+ {
+ IsotopicCurve *curve = curveList.at(iter);
+
+ bool ok = false;
+
+ summedIntensity += curve->intensityAt(curMzRatio, m_increment, &ok);
+ }
- // outputString += "#########";
- // if (locale)
- // outputString += application->locale().toString(mono, 'f', 5);
- // else
- // outputString += QString().setNum(mono, 'f', 5);
- // outputString += "--> [";
- // if (locale)
- // outputString += application->locale().toString(leftPoint, 'f', 5);
- // else
- // outputString += QString().setNum(leftPoint, 'f', 5);
- // outputString += "--";
- // if (locale)
- // outputString += application->locale().toString(rightPoint, 'f', 5);
- // else
- // outputString += QString().setNum(rightPoint, 'f', 5);
- // outputString += "]\n";
-
- for(double x = leftPoint; x <= rightPoint; x += increment)
- {
- double y = relInt * exp(( - pow((x - mono), 2) ) / c2);
-
- if (locale)
- outputString += application->locale().
- toString(x, 'f', MXP_OLIGOMER_DEC_PLACES);
- else
- outputString += QString().
- setNum(x, 'f', MXP_OLIGOMER_DEC_PLACES);
- outputString += " ";
- if (locale)
- outputString += application->locale().
- toString(y, 'f', MXP_OLIGOMER_DEC_PLACES);
- else
- outputString += QString().
- setNum(y, 'f', MXP_OLIGOMER_DEC_PLACES);
- outputString += "\n";
- }
+ IsotopicPeak *newPeak = new IsotopicPeak(curMzRatio, summedIntensity, 0, 0);
+
+ m_isotopicCurve.appendPeak(newPeak);
- if(stream.status() == QTextStream::ReadCorruptData)
- m_ui.resultTextEdit->append(outputString);
- else
- stream << outputString;
-
- // qDebug() << outputString;
- outputString.clear();
+ curMzRatio += m_increment;
}
-
- m_ui.feedbackLineEdit->setText(tr(""));
-
- // Finished sending all the peak data to the file. QFile will close
- // itself.
+
+ if(!m_filePath.isEmpty())
+ {
+ // Send all the data to the output file.
+ if (!m_isotopicCurve.dataToFile(m_filePath))
+ QMessageBox::warning(this,
+ tr("massXpert - Isotopic Pattern Calculation"),
+ tr("Failed to export the curve data to file."),
+ QMessageBox::Ok);
+
+ return;
+ }
+
+ // Send the data to the text edit widget.
+ m_ui.resultTextEdit->append(m_isotopicCurve.dataAsString());
}
-
+
void
IsotopicPatternCalculationDlg::abort()
{
m_aborted = true;
}
-
+
void
IsotopicPatternCalculationDlg::outputFile()
@@ -753,6 +1203,19 @@ namespace massXpert
tr("Any file type(*)"));
}
+ void
+ IsotopicPatternCalculationDlg::debugPutStdErr(QString file, int line,
+ int value, const QString &text)
+ {
+ qDebug() << file << line
+ << "value " << text << ":" << value
+ << " -- bitset:" << GlobBinaryRepresentation(value)
+ << "\n";
+ }
+
+} // namespace massXpert
+
+
#if 0
/***************************************************************************
@@ -1142,5 +1605,3 @@ namespace massXpert
printf("-h show this text\n\n");
}
#endif
-
-} // namespace massXpert
diff --git a/gui/isotopicPatternCalculationDlg.hpp b/gui/isotopicPatternCalculationDlg.hpp
index 836cab7..14acacb 100644
--- a/gui/isotopicPatternCalculationDlg.hpp
+++ b/gui/isotopicPatternCalculationDlg.hpp
@@ -50,11 +50,23 @@
#include "atom.hpp"
#include "atomCount.hpp"
#include "formula.hpp"
+#include "isotopicCurve.hpp"
+#include "globals.hpp"
namespace massXpert
{
+ enum ValidationError
+ {
+ MXP_VALIDATION_ERRORS_NONE = 0x0000,
+ MXP_VALIDATION_IONIZERULE_ERRORS = 1 << 0,
+ MXP_VALIDATION_FORMULA_ERRORS = 1 << 1,
+ MXP_VALIDATION_RESOLUTION_ERRORS = 1 << 2,
+ MXP_VALIDATION_FWHM_ERRORS = 1 << 3,
+ };
+
+
class IsotopicPatternCalculationDlg : public QDialog
{
Q_OBJECT
@@ -64,13 +76,33 @@ namespace massXpert
const QList<Atom *> &m_atomList;
+ int m_validationErrors;
+
QString m_filePath;
Formula m_formula;
+
+ double m_minimumProbability;
int m_maximumPeaks;
- int m_resolution;
+
+ double m_resolution;
+ double m_fwhm;
+
+ int m_points;
+ double m_increment;
+
int m_charge;
- double m_minimumProbability;
+ CurveType m_curveType;
+
+ const PolChemDef &m_polChemDef;
+ IonizeRule m_ionizeRule;
+
+ // The curve that will hold the sum of all the
+ // gaussians/lorentzian curves obtained for the single mass peaks
+ // of the isotopic cluster.
+
+ IsotopicCurve m_isotopicCurve;
+
double m_mono;
double m_avg;
@@ -78,9 +110,26 @@ namespace massXpert
void closeEvent(QCloseEvent *event);
+ bool fetchIonizationRuleData(IonizeRule *);
+ bool fetchFormulaMass(double * = 0, double * = 0);
+ bool fetchMzRatio(double * = 0, double * = 0);
+
bool fetchValidateInputData();
-
+
+ void setInErrorStatus(const QString &);
+
+ bool updateMzRatio();
+
+ void debugPutStdErr(QString /*file*/, int /*line*/,
+ int /*value*/,
+ const QString & = QString() /*descString*/);
+
+
private slots:
+ void formulaChanged(const QString &);
+ void ionizationDataChanged();
+ void resolutionChanged(int);
+ void fwhmEdited(const QString &);
void execute();
void abort();
void outputFile();
diff --git a/gui/ui/isotopicPatternCalculationDlg.ui b/gui/ui/isotopicPatternCalculationDlg.ui
index 6b179f2..d2a9c46 100644
--- a/gui/ui/isotopicPatternCalculationDlg.ui
+++ b/gui/ui/isotopicPatternCalculationDlg.ui
@@ -1,444 +1,549 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<class>IsotopicPatternCalculationDlg</class>
- <widget class="QDialog" name="IsotopicPatternCalculationDlg" >
- <property name="geometry" >
+ <widget class="QDialog" name="IsotopicPatternCalculationDlg">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>576</width>
- <height>578</height>
+ <width>776</width>
+ <height>844</height>
</rect>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string>massXpert: Isotopic pattern calculator</string>
</property>
- <property name="windowIcon" >
- <iconset resource="../application.qrc" >
+ <property name="windowIcon">
+ <iconset resource="../application.qrc">
<normaloff>:/images/massxpert-icon-32.png</normaloff>:/images/massxpert-icon-32.png</iconset>
</property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="3" column="0" >
- <widget class="QGroupBox" name="groupBox_4" >
- <property name="title" >
- <string>Processing feedback</string>
+ <layout class="QGridLayout" name="gridLayout_8">
+ <item row="0" column="0">
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>9</number>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string/>
</property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="0" column="1" >
- <widget class="QProgressBar" name="progressBar" >
- <property name="value" >
- <number>24</number>
- </property>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="0" column="0" >
- <widget class="QLineEdit" name="feedbackLineEdit" >
- <property name="font" >
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="frame" >
- <bool>false</bool>
- </property>
- <property name="readOnly" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="0" column="0" >
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Polymer chemistry definition:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="polChemDefLabel" >
- <property name="text" >
- <string>polChemDefLabel</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="1" column="0" >
- <widget class="QGroupBox" name="groupBox" >
- <property name="title" >
- <string>Input data</string>
- </property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="1" column="0" >
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label_9" >
- <property name="text" >
- <string>&Min. probability:</string>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="2">
+ <widget class="QGroupBox" name="polChemDefGroupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Polymer chemistry definition</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_7">
+ <item row="0" column="0">
+ <widget class="QLabel" name="polChemDefLabel">
+ <property name="text">
+ <string>polChemDefLabel</string>
</property>
- <property name="buddy" >
- <cstring>minimumProbabilityDoubleSpinBox</cstring>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QGroupBox" name="groupBox_6">
+ <property name="title">
+ <string>Ionization</string>
</property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Unitary formula</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLineEdit" name="ionizationFormulaLineEdit">
+ <property name="toolTip">
+ <string>Ionization formula</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="_3">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="_4">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Unitary charge</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="ionizationChargeSpinBox">
+ <property name="toolTip">
+ <string>Ionization unitary charge</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>1000000</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="_5">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Ionization level</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="ionizationLevelSpinBox">
+ <property name="toolTip">
+ <string>Ionization level</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
</widget>
</item>
- <item>
- <widget class="QDoubleSpinBox" name="minimumProbabilityDoubleSpinBox" >
- <property name="toolTip" >
- <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Minimum probability (or compounded abundance) that a peak must have to be taken into account in the output.</p></body></html></string>
+ <item row="0" column="1">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="decimals" >
- <number>7</number>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
</property>
- </widget>
+ </spacer>
</item>
</layout>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label_5" >
- <property name="text" >
- <string>&Resolution:</string>
- </property>
- <property name="buddy" >
- <cstring>resolutionSpinBox</cstring>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QGroupBox" name="inputDataGroupBox">
+ <property name="title">
+ <string>Input data</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_6">
+ <item row="0" column="0">
+ <widget class="QGroupBox" name="massConfigGroupBox">
+ <property name="title">
+ <string>Mass config.</string>
</property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Formula:</string>
+ </property>
+ <property name="buddy">
+ <cstring>formulaLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="formulaLineEdit">
+ <property name="toolTip">
+ <string>Formula of the non-ionized analyte</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Charge: </string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="chargeLabel">
+ <property name="text">
+ <string>1</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>mz Ratio: </string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLineEdit" name="monoMzRatioLineEdit"/>
+ </item>
+ </layout>
</widget>
</item>
- <item>
- <widget class="QSpinBox" name="resolutionSpinBox" >
- <property name="toolTip" >
- <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Resolution of the mass spectrometer.</p></body></html></string>
+ <item row="0" column="1">
+ <widget class="QGroupBox" name="resolutionConfigGroupBox">
+ <property name="title">
+ <string>Resolution config.</string>
</property>
- <property name="maximum" >
- <number>100000</number>
- </property>
- <property name="singleStep" >
- <number>1000</number>
- </property>
- <property name="value" >
- <number>15000</number>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>&Resolution:</string>
+ </property>
+ <property name="buddy">
+ <cstring>resolutionSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>FWHM:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="fwhmLineEdit"/>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="resolutionSpinBox">
+ <property name="toolTip">
+ <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Resolution of the mass spectrometer.</p></body></html></string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>1000000</number>
+ </property>
+ <property name="singleStep">
+ <number>1000</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QGroupBox" name="spectrumConfigGroupBox">
+ <property name="title">
+ <string>Spectrum config.</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>
+ <property name="buddy">
+ <cstring>minimumProbabilityDoubleSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QDoubleSpinBox" name="minimumProbabilityDoubleSpinBox">
+ <property name="toolTip">
+ <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Minimum probability (or compounded abundance) that a peak must have to be taken into account in the output.</p></body></html></string>
+ </property>
+ <property name="decimals">
+ <number>7</number>
+ </property>
+ <property name="minimum">
+ <double>0.000100000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Max. &peaks:</string>
+ </property>
+ <property name="buddy">
+ <cstring>maximumPeaksSpinBox</cstring>
+ </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>25</number>
+ </property>
+ <property name="maximum">
+ <number>100000</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Points:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="pointsSpinBox">
+ <property name="minimum">
+ <number>10</number>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </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">
+ <string>Increment:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="incrementSpinBox">
+ <property name="toolTip">
+ <string>Gap between any two points in the curve</string>
+ </property>
+ <property name="maximum">
+ <number>1000000</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
</layout>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label_6" >
- <property name="text" >
- <string>Max. &peaks:</string>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QGroupBox" name="actionsGroupBox">
+ <property name="title">
+ <string>Actions</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QPushButton" name="outputFilePushButton">
+ <property name="toolTip">
+ <string>Choose a file in which to store the data for the plotting of the isotopic peak. </string>
</property>
- <property name="buddy" >
- <cstring>maximumPeaksSpinBox</cstring>
+ <property name="text">
+ <string>&Output file...</string>
</property>
</widget>
</item>
- <item>
- <widget class="QSpinBox" name="maximumPeaksSpinBox" >
- <property name="toolTip" >
- <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Maximum number of peaks that must be calculated.</p></body></html></string>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="localeCheckBox">
+ <property name="toolTip">
+ <string>If checked all the numerical output will be generated with locale specificity.</string>
</property>
- <property name="maximum" >
- <number>100000</number>
- </property>
- <property name="value" >
- <number>100</number>
+ <property name="text">
+ <string>&Locale</string>
</property>
</widget>
</item>
- </layout>
- </item>
- </layout>
- </item>
- <item row="0" column="0" >
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label_3" >
- <property name="text" >
- <string>&Formula:</string>
- </property>
- <property name="buddy" >
- <cstring>formulaLineEdit</cstring>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="executePushButton">
+ <property name="text">
+ <string>&Execute</string>
</property>
</widget>
</item>
- <item>
- <widget class="QLineEdit" name="formulaLineEdit" />
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label_10" >
- <property name="text" >
- <string>&Charge:</string>
+ <item row="0" column="3">
+ <widget class="QPushButton" name="abortPushButton">
+ <property name="toolTip">
+ <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Abort the ongoing computation. In this case, the data that will be displayed will be incomplete and are shown only for forensic tasks.</p></body></html></string>
</property>
- <property name="buddy" >
- <cstring>chargeSpinBox</cstring>
+ <property name="text">
+ <string>&Abort</string>
</property>
</widget>
</item>
- <item>
- <widget class="QSpinBox" name="chargeSpinBox" />
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QGroupBox" name="feedbackGroupBox">
+ <property name="title">
+ <string>Feedback</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_11">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QGroupBox" name="inputDataFeedbackGroupBox">
+ <property name="title">
+ <string>Input data</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_9">
+ <item row="0" column="0">
+ <widget class="QLineEdit" name="inputDataFeedbackLineEdit"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="processingFeedbackGroupBox">
+ <property name="title">
+ <string>Processing</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_10">
+ <item row="0" column="0">
+ <widget class="QLineEdit" name="feedbackLineEdit">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="frame">
+ <bool>false</bool>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QProgressBar" name="progressBar">
+ <property name="value">
+ <number>24</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0" >
- <layout class="QHBoxLayout" >
- <property name="spacing" >
- <number>6</number>
- </property>
- <property name="margin" >
- <number>0</number>
- </property>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>16</width>
- <height>25</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="outputFilePushButton" >
- <property name="toolTip" >
- <string>Choose a file in which to store the data for the plotting of the isotopic peak. </string>
- </property>
- <property name="text" >
- <string>&Output file...</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>21</width>
- <height>25</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QCheckBox" name="localeCheckBox" >
- <property name="toolTip" >
- <string>If checked all the numerical output will be generated with locale specificity.</string>
- </property>
- <property name="text" >
- <string>&Locale</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>21</width>
- <height>25</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="executePushButton" >
- <property name="text" >
- <string>&Execute</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>21</width>
- <height>25</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="abortPushButton" >
- <property name="toolTip" >
- <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Abort the ongoing computation. In this case, the data that will be displayed will be incomplete and are shown only for forensic tasks.</p></body></html></string>
- </property>
- <property name="text" >
- <string>&Abort</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QGroupBox" name="resultsGroupBox">
+ <property name="title">
+ <string>Results</string>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>9</number>
</property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>21</width>
- <height>25</height>
- </size>
+ <property name="spacing">
+ <number>6</number>
</property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="4" column="0" >
- <widget class="QGroupBox" name="groupBox_2" >
- <property name="title" >
- <string>Results</string>
- </property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="0" column="0" >
- <widget class="QTextEdit" name="resultTextEdit" >
- <property name="toolTip" >
- <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
+ <item row="0" column="0">
+ <widget class="QTextEdit" name="resultTextEdit">
+ <property name="toolTip">
+ <string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Will display data about the isotopic peaks.</p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Note that if no file was chosen to write the plotting data, these data will be output in this text edit widget also.</p></body></html></string>
- </property>
- </widget>
- </item>
- </layout>
+</style></head><body style=" font-family:'Sans Serif'; font-size:6pt; font-weight:400; font-style:normal; text-decoration:none;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Will display data about the isotopic peaks.</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Note that if no file was chosen to write the plotting data, these data will be output in this text edit widget also.</p></body></html></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
- <item row="5" column="0" >
- <widget class="QLabel" name="label_2" >
- <property name="font" >
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="font">
<font>
<pointsize>5</pointsize>
</font>
</property>
- <property name="text" >
+ <property name="text">
<string>Credit: the algorithm was partly adapted from the work of Dirk Nolting (nolting at uni-duesseldorf.de)</string>
</property>
</widget>
@@ -447,18 +552,12 @@ p, li { white-space: pre-wrap; }
</widget>
<tabstops>
<tabstop>formulaLineEdit</tabstop>
- <tabstop>chargeSpinBox</tabstop>
<tabstop>minimumProbabilityDoubleSpinBox</tabstop>
- <tabstop>resolutionSpinBox</tabstop>
<tabstop>maximumPeaksSpinBox</tabstop>
- <tabstop>outputFilePushButton</tabstop>
- <tabstop>localeCheckBox</tabstop>
- <tabstop>executePushButton</tabstop>
- <tabstop>abortPushButton</tabstop>
<tabstop>resultTextEdit</tabstop>
</tabstops>
<resources>
- <include location="../application.qrc" />
+ <include location="../application.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 39933a6..749e7eb 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -33,6 +33,7 @@ SET (masslib_SRCS
ionizable.cpp
ionizeRule.cpp
isotope.cpp
+ isotopicCurve.cpp
isotopicPeak.cpp
massList.cpp
modif.cpp
diff --git a/lib/globals.cpp b/lib/globals.cpp
index d5eda96..69668d5 100644
--- a/lib/globals.cpp
+++ b/lib/globals.cpp
@@ -57,3 +57,12 @@ GlobUnspacifyQString(QString &src)
}
+QString
+GlobBinaryRepresentation(int value)
+{
+ QString string;
+ string = QString("%1")
+ .arg(value, 10, 2);
+
+ return string;
+}
diff --git a/lib/globals.hpp b/lib/globals.hpp
index bbd45f5..0373c1d 100644
--- a/lib/globals.hpp
+++ b/lib/globals.hpp
@@ -117,6 +117,11 @@ enum PolymerChemEnt
MXT_POLYMER_CHEMENT_FORCE_RIGHT_END_MODIF)
};
+enum CurveType
+ {
+ MXP_CURVE_TYPE_GAUSSIAN = 1 << 0,
+ MXP_CURVE_TYPE_LORENTZIAN = 1 << 1,
+ };
extern int MXP_ATOM_DEC_PLACES;
extern int MXP_OLIGOMER_DEC_PLACES;
@@ -129,6 +134,8 @@ extern int MXP_PH_PKA_DEC_PLACES;
QString &
GlobUnspacifyQString(QString &);
+QString
+GlobBinaryRepresentation(int);
#endif // GLOBALS_HPP
diff --git a/lib/ionizable.cpp b/lib/ionizable.cpp
index 19ce46e..3ad501b 100644
--- a/lib/ionizable.cpp
+++ b/lib/ionizable.cpp
@@ -342,18 +342,29 @@ namespace massXpert
int
Ionizable::ionize()
{
- if (m_isIonized)
- return 0;
-
if (!m_ionizeRule.isValid())
return -1;
+ if (m_isIonized)
+ return 0;
+
// At this point perform the ionization proper.
Formula formula(m_ionizeRule.formula());
Ponderable temp(*this);
+ // qDebug() << __FILE__ << __LINE__
+ // << "Before ionization:\n"
+ // << "Ionizable's charge / level:"
+ // << m_ionizeRule.charge() << "/" << m_ionizeRule.level()
+ // << " -- "
+ // << "Ionizable's whole charge:"
+ // << m_ionizeRule.charge() * m_ionizeRule.level()
+ // << " -- "
+ // << "Mono:" << temp.mono() << "Avg:" << temp.avg()
+ // << "\n\n";
+
double localMono = 0;
double localAvg = 0;
@@ -370,24 +381,34 @@ namespace massXpert
// charge and level values of m_ionizeRule cannot be <= 0 because
// otherwise the m_ionizRule would not have validated.
+ int ionCharge = m_ionizeRule.charge() * m_ionizeRule.level();
+
m_mono += localMono;
- m_mono = m_mono /(m_ionizeRule.charge() * m_ionizeRule.level());
+ m_mono = m_mono /ionCharge;
m_avg += localAvg;
- m_avg = m_avg /(m_ionizeRule.charge() * m_ionizeRule.level());
+ m_avg = m_avg / ionCharge;
// Of course, we now are ionized.
m_isIonized = true;
-// qDebug() << __FILE__ << __LINE__
-// << "Total charge:"
-// << m_ionizeRule.charge() * m_ionizeRule.level()
-// << "After ionization: Mono:" << m_mono << "Avg:" << m_avg;
-
+ // qDebug() << __FILE__ << __LINE__
+ // << "After ionization:\n"
+ // << "Ionizable's charge / level:"
+ // << m_ionizeRule.charge() << "/" << m_ionizeRule.level()
+ // << " -- "
+ // << "Ionizable's whole charge:"
+ // << m_ionizeRule.charge() * m_ionizeRule.level()
+ // << " -- "
+ // << "Mono:" << m_mono << "Avg:" << m_avg
+ // << "\n\n";
+
// If something changed in the masses, then return 1, otherwise
// return 0.
- if (temp != *this)
- return 1;
+ if (temp != static_cast<Ponderable>(*this))
+ {
+ return 1;
+ }
return 0;
}
@@ -509,8 +530,6 @@ namespace massXpert
int
Ionizable::ionize(Ionizable *ionizable, const IonizeRule &ionizeRule)
{
- Q_ASSERT(ionizable);
-
if (!ionizeRule.isValid())
return -1;
diff --git a/lib/isotopicPeak.cpp b/lib/isotopicPeak.cpp
index b106d64..221bcb6 100644
--- a/lib/isotopicPeak.cpp
+++ b/lib/isotopicPeak.cpp
@@ -56,18 +56,21 @@ namespace massXpert
\param relIntensity relative intensity. Defaults to 0. Cannot be
negative.
*/
- IsotopicPeak::IsotopicPeak(double mass, double abundance,
- double probability, double relIntensity)
+ IsotopicPeak::IsotopicPeak(double mass, double relIntensity,
+ double probability, double abundance)
{
+ qDebug() << __FILE__ << __LINE__
+ << "relIntensity:" << relIntensity;
+
Q_ASSERT(mass >= 0);
- Q_ASSERT(abundance >= 0);
- Q_ASSERT(probability >= 0);
Q_ASSERT(relIntensity >= 0);
+ Q_ASSERT(probability >= 0);
+ Q_ASSERT(abundance >= 0);
m_mass = mass;
- m_abundance = abundance;
- m_probability = probability;
m_relativeIntensity = relIntensity;
+ m_probability = probability;
+ m_abundance = abundance;
}
diff --git a/lib/isotopicPeak.hpp b/lib/isotopicPeak.hpp
index 14396be..ebe23e9 100644
--- a/lib/isotopicPeak.hpp
+++ b/lib/isotopicPeak.hpp
@@ -72,8 +72,9 @@ namespace massXpert
double m_relativeIntensity;
public:
- IsotopicPeak(double = 0, double = 0, double = 0, double = 0);
- IsotopicPeak(Isotope &, double = 0, double = 0);
+ IsotopicPeak(double /* mass */, double /* relIntensity */,
+ double /* probability */, double /* abundance */);
+ IsotopicPeak(Isotope &, double, double);
IsotopicPeak(const IsotopicPeak &);
virtual IsotopicPeak * clone() const;
diff --git a/lib/ponderable.cpp b/lib/ponderable.cpp
index 97dabab..d08bf65 100644
--- a/lib/ponderable.cpp
+++ b/lib/ponderable.cpp
@@ -37,7 +37,7 @@
/////////////////////// Qt includes
#include <QtGlobal>
-
+#include <QDebug>
/////////////////////// Local includes
#include "ponderable.hpp"
@@ -478,8 +478,19 @@ namespace massXpert
Ponderable::operator !=(const Ponderable &other) const
{
if (m_mono != other.m_mono || m_avg != other.m_avg)
- return true;
-
+ {
+ // qDebug() << __FILE__ << __LINE__
+ // << "m_mono:" << m_mono
+ // << "/"
+ // << "other.m_mono:" << other.m_mono
+ // << "--"
+ // << "m_avg:" << m_avg
+ // << "/"
+ // << "other.m_avg:" << other.m_avg;
+
+ return true;
+ }
+
return false;
}
--
massXpert mass spectrometry suite: debian packaging
More information about the Debichem-commits
mailing list