diff --git a/CycloBranch/core/cGlobalPreferences.cpp b/CycloBranch/core/cGlobalPreferences.cpp index 4b02900..8c365b7 100644 --- a/CycloBranch/core/cGlobalPreferences.cpp +++ b/CycloBranch/core/cGlobalPreferences.cpp @@ -968,8 +968,8 @@ void cGlobalPreferences::setDefaultIonTypes() { void cGlobalPreferences::setDefaultDataProcessingMethods() { - linebafprocessingmethod = 0; - profilebafprocessingmethod = 0; + linebafprocessingmethod = 1; + profilebafprocessingmethod = 1; rawdataprocessingmethod = 0; } diff --git a/CycloBranch/core/cParameters.cpp b/CycloBranch/core/cParameters.cpp index 882888f..eae3e59 100644 --- a/CycloBranch/core/cParameters.cpp +++ b/CycloBranch/core/cParameters.cpp @@ -465,8 +465,35 @@ void cParameters::clear() { minimumrt = 0; maximumrt = 0; fwhm = 0.05; + + enableratio54Fe56Fe = true; minratio54Fe56Fe = 0.01; maxratio54Fe56Fe = 0.1; + + enableratio60Ni58Ni = true; + minratio60Ni58Ni = 0; + maxratio60Ni58Ni = 0.5; + + enableratio62Ni58Ni = true; + minratio62Ni58Ni = 0; + maxratio62Ni58Ni = 0.1; + + enableratio65Cu63Cu = true; + minratio65Cu63Cu = 0; + maxratio65Cu63Cu = 0.6; + + enableratio66Zn64Zn = true; + minratio66Zn64Zn = 0; + maxratio66Zn64Zn = 0.7; + + enableratio67Zn64Zn = true; + minratio67Zn64Zn = 0; + maxratio67Zn64Zn = 0.2; + + enableratio68Zn64Zn = true; + minratio68Zn64Zn = 0; + maxratio68Zn64Zn = 0.5; + bricksdatabasefilename = ""; bricksdatabase.clear(); maximumbricksincombinationbegin = 1; @@ -1722,8 +1749,56 @@ string cParameters::printToString() { s += "Minimum Retention Time: " + to_string(minimumrt) + "\n"; s += "Maximum Retention Time: " + to_string(maximumrt) + "\n"; s += "FWHM: " + to_string(fwhm) + "\n"; + + s += "Enable Ratio 54Fe/56Fe: "; + s += enableratio54Fe56Fe ? "on" : "off"; + s += "\n"; + s += "Minimum Ratio 54Fe/56Fe: " + to_string(minratio54Fe56Fe) + "\n"; s += "Maximum Ratio 54Fe/56Fe: " + to_string(maxratio54Fe56Fe) + "\n"; + + s += "Enable Ratio 60Ni/58Ni: "; + s += enableratio60Ni58Ni ? "on" : "off"; + s += "\n"; + + s += "Minimum Ratio 60Ni/58Ni: " + to_string(minratio60Ni58Ni) + "\n"; + s += "Maximum Ratio 60Ni/58Ni: " + to_string(maxratio60Ni58Ni) + "\n"; + + //s += "Enable Ratio 62Ni/58Ni: "; + //s += enableratio62Ni58Ni ? "on" : "off"; + //s += "\n"; + + //s += "Minimum Ratio 62Ni/58Ni: " + to_string(minratio62Ni58Ni) + "\n"; + //s += "Maximum Ratio 62Ni/58Ni: " + to_string(maxratio62Ni58Ni) + "\n"; + + s += "Enable Ratio 65Cu/63Cu: "; + s += enableratio65Cu63Cu ? "on" : "off"; + s += "\n"; + + s += "Minimum Ratio 65Cu/63Cu: " + to_string(minratio65Cu63Cu) + "\n"; + s += "Maximum Ratio 65Cu/63Cu: " + to_string(maxratio65Cu63Cu) + "\n"; + + s += "Enable Ratio 66Zn/64Zn: "; + s += enableratio66Zn64Zn ? "on" : "off"; + s += "\n"; + + s += "Minimum Ratio 66Zn/64Zn: " + to_string(minratio66Zn64Zn) + "\n"; + s += "Maximum Ratio 66Zn/64Zn: " + to_string(maxratio66Zn64Zn) + "\n"; + + //s += "Enable Ratio 67Zn/64Zn: "; + //s += enableratio67Zn64Zn ? "on" : "off"; + //s += "\n"; + + //s += "Minimum Ratio 67Zn/64Zn: " + to_string(minratio67Zn64Zn) + "\n"; + //s += "Maximum Ratio 67Zn/64Zn: " + to_string(maxratio67Zn64Zn) + "\n"; + + s += "Enable Ratio 68Zn/64Zn: "; + s += enableratio68Zn64Zn ? "on" : "off"; + s += "\n"; + + s += "Minimum Ratio 68Zn/64Zn: " + to_string(minratio68Zn64Zn) + "\n"; + s += "Maximum Ratio 68Zn/64Zn: " + to_string(maxratio68Zn64Zn) + "\n"; + s += "Building Blocks Database File: " + bricksdatabasefilename + "\n"; s += "Maximum Number of Combined Blocks (start, middle, end): " + to_string(maximumbricksincombinationbegin) + ", " + to_string(maximumbricksincombinationmiddle) + ", " + to_string(maximumbricksincombinationend) + "\n"; @@ -1792,6 +1867,9 @@ string cParameters::printToString() { case weighted_ratio_of_matched_peaks: s += "Weighted Ratio of Matched Peaks"; break; + case cosine_similarity: + s += "Cosine Similarity"; + break; default: s += "undefined"; break; @@ -2508,6 +2586,86 @@ int cParameters::generateCompounds(bool& terminatecomputation, string& errormess } } + size_t ionssize = ionsfortheoreticalspectraMS1.size(); + + vector ionsfortheoreticalspectraMS1hasFe; + vector ionsfortheoreticalspectraMS1hasNi; + vector ionsfortheoreticalspectraMS1hasCu; + vector ionsfortheoreticalspectraMS1hasZn; + + ionsfortheoreticalspectraMS1hasFe.resize(ionssize, false); + ionsfortheoreticalspectraMS1hasNi.resize(ionssize, false); + ionsfortheoreticalspectraMS1hasCu.resize(ionssize, false); + ionsfortheoreticalspectraMS1hasZn.resize(ionssize, false); + + for (size_t i = 0; i < ionssize; i++) { + if (ionsfortheoreticalspectraMS1[i].formula.find("Fe") != string::npos) { + ionsfortheoreticalspectraMS1hasFe[i] = true; + } + + if (ionsfortheoreticalspectraMS1[i].formula.find("Ni") != string::npos) { + ionsfortheoreticalspectraMS1hasNi[i] = true; + } + + if (ionsfortheoreticalspectraMS1[i].formula.find("Cu") != string::npos) { + ionsfortheoreticalspectraMS1hasCu[i] = true; + } + + if (ionsfortheoreticalspectraMS1[i].formula.find("Zn") != string::npos) { + ionsfortheoreticalspectraMS1hasZn[i] = true; + } + + //cout << ionsfortheoreticalspectraMS1[i].formula << " " << ionsfortheoreticalspectraMS1hasFe[i] << " " << ionsfortheoreticalspectraMS1hasNi[i] << " " << ionsfortheoreticalspectraMS1hasCu[i] << " " << ionsfortheoreticalspectraMS1hasZn[i] << endl; + } + + vector > hintsvector; + hintsvector.resize(peaklistseriesvector.size()); + + vector hintsvectorsizes; + hintsvectorsizes.resize(peaklistseriesvector.size(), 0); + + int hsize; + int ksize; + int isize; + + hintStructure hs; + if (!reportunmatchedtheoreticalpeaks) { + hsize = (int)peaklistseriesvector.size(); + for (size_t h = 0; h < hsize; h++) { + ksize = peaklistseriesvector[h].size(); + for (int k = 0; k < ksize; k++) { + hintsvectorsizes[h] += peaklistseriesvector[h][k].size(); + } + hintsvector[h].resize(hintsvectorsizes[h]); + } + + int j; + hsize = (int)peaklistseriesvector.size(); + for (int h = 0; h < hsize; h++) { + j = 0; + ksize = peaklistseriesvector[h].size(); + for (int k = 0; k < ksize; k++) { + isize = peaklistseriesvector[h][k].size(); + for (int i = 0; i < isize; i++) { + hs.mz = peaklistseriesvector[h][k][i].mzratio; + hs.id = k; + hintsvector[h][j] = hs; + j++; + } + } + sort(hintsvector[h].begin(), hintsvector[h].end(), compareHints); + } + } + + bool shint; + + set hintset; + set hintsetFe54; + set hintsetNi60; + set hintsetCu65; + set hintsetZn66; + set hintsetZn68; + double unchargedmaximummz = charge(uncharge(maximummz, precursorcharge), (precursorcharge > 0) ? 1 : -1) - minadd; //double unchargedmaximummz = maximummz - minadd; @@ -2618,11 +2776,11 @@ int cParameters::generateCompounds(bool& terminatecomputation, string& errormess } - for (auto& it : ionsfortheoreticalspectraMS1) { + for (size_t i = 0; i < ionssize; i++) { for (int j = 0; j < abs(precursorcharge); j++) { - tmpmzdifference = sumofmasses + it.massdifference; + tmpmzdifference = sumofmasses + ionsfortheoreticalspectraMS1[i].massdifference; if (precursorcharge > 0) { tmpmzdifference += j * (H - e); } @@ -2635,9 +2793,60 @@ int cParameters::generateCompounds(bool& terminatecomputation, string& errormess featureshint = 0; + hintset.clear(); + hintsetFe54.clear(); + hintsetNi60.clear(); + hintsetCu65.clear(); + hintsetZn66.clear(); + hintsetZn68.clear(); + + searchHintForDeNovo(tmpmzdifference, hintsvector[h], fragmentmasserrortolerance, hintset); + + if (ionsfortheoreticalspectraMS1hasFe[i] && enableratio54Fe56Fe && (minratio54Fe56Fe > 0) && (minimumpatternsize > 1)) { + searchHintForDeNovo(tmpmzdifference - (Fe56 - Fe54) / (double)(j + 1), hintsvector[h], fragmentmasserrortolerance, hintsetFe54); + } + + if (ionsfortheoreticalspectraMS1hasNi[i] && enableratio60Ni58Ni && (minratio60Ni58Ni > 0) && (minimumpatternsize > 1)) { + searchHintForDeNovo(tmpmzdifference + (Ni60 - Ni58) / (double)(j + 1), hintsvector[h], fragmentmasserrortolerance, hintsetNi60); + } + + if (ionsfortheoreticalspectraMS1hasCu[i] && enableratio65Cu63Cu && (minratio65Cu63Cu > 0) && (minimumpatternsize > 1)) { + searchHintForDeNovo(tmpmzdifference + (Cu65 - Cu63) / (double)(j + 1), hintsvector[h], fragmentmasserrortolerance, hintsetCu65); + } + + if (ionsfortheoreticalspectraMS1hasZn[i] && enableratio66Zn64Zn && (minratio66Zn64Zn > 0) && (minimumpatternsize > 1)) { + searchHintForDeNovo(tmpmzdifference + (Zn66 - Zn64) / (double)(j + 1), hintsvector[h], fragmentmasserrortolerance, hintsetZn66); + + if (enableratio68Zn64Zn && (minratio68Zn64Zn > 0) && (minimumpatternsize > 2)) { + searchHintForDeNovo(tmpmzdifference + (Zn68 - Zn64) / (double)(j + 1), hintsvector[h], fragmentmasserrortolerance, hintsetZn68); + } + } + for (int k = kstart; k < kend; k++) { - if (searchHint(tmpmzdifference, peaklistseriesvector[h][k], fragmentmasserrortolerance)) { + shint = (bool)hintset.count(k); + + if (shint && ionsfortheoreticalspectraMS1hasFe[i] && enableratio54Fe56Fe && (minratio54Fe56Fe > 0) && (minimumpatternsize > 1)) { + shint = (bool)hintsetFe54.count(k); + } + + if (shint && ionsfortheoreticalspectraMS1hasNi[i] && enableratio60Ni58Ni && (minratio60Ni58Ni > 0) && (minimumpatternsize > 1)) { + shint = (bool)hintsetNi60.count(k); + } + + if (shint && ionsfortheoreticalspectraMS1hasCu[i] && enableratio65Cu63Cu && (minratio65Cu63Cu > 0) && (minimumpatternsize > 1)) { + shint = (bool)hintsetCu65.count(k); + } + + if (shint && ionsfortheoreticalspectraMS1hasZn[i] && enableratio66Zn64Zn && (minratio66Zn64Zn > 0) && (minimumpatternsize > 1)) { + shint = (bool)hintsetZn66.count(k); + + if (shint && enableratio68Zn64Zn && (minratio68Zn64Zn > 0) && (minimumpatternsize > 2)) { + shint = (bool)hintsetZn68.count(k); + } + } + + if (shint) { featureshint++; } else { @@ -2787,9 +2996,35 @@ void cParameters::store(ofstream& os) { os.write((char *)&maximumrt, sizeof(double)); os.write((char *)&fwhm, sizeof(double)); + os.write((char *)&enableratio54Fe56Fe, sizeof(bool)); + os.write((char *)&enableratio60Ni58Ni, sizeof(bool)); + os.write((char *)&enableratio62Ni58Ni, sizeof(bool)); + os.write((char *)&enableratio65Cu63Cu, sizeof(bool)); + os.write((char *)&enableratio66Zn64Zn, sizeof(bool)); + os.write((char *)&enableratio67Zn64Zn, sizeof(bool)); + os.write((char *)&enableratio68Zn64Zn, sizeof(bool)); + os.write((char *)&minratio54Fe56Fe, sizeof(double)); os.write((char *)&maxratio54Fe56Fe, sizeof(double)); + os.write((char *)&minratio60Ni58Ni, sizeof(double)); + os.write((char *)&maxratio60Ni58Ni, sizeof(double)); + + os.write((char *)&minratio62Ni58Ni, sizeof(double)); + os.write((char *)&maxratio62Ni58Ni, sizeof(double)); + + os.write((char *)&minratio65Cu63Cu, sizeof(double)); + os.write((char *)&maxratio65Cu63Cu, sizeof(double)); + + os.write((char *)&minratio66Zn64Zn, sizeof(double)); + os.write((char *)&maxratio66Zn64Zn, sizeof(double)); + + os.write((char *)&minratio67Zn64Zn, sizeof(double)); + os.write((char *)&maxratio67Zn64Zn, sizeof(double)); + + os.write((char *)&minratio68Zn64Zn, sizeof(double)); + os.write((char *)&maxratio68Zn64Zn, sizeof(double)); + storeString(bricksdatabasefilename, os); bricksdatabase.store(os); @@ -2997,6 +3232,25 @@ void cParameters::load(ifstream& is, int fileversionpart1, int fileversionpart2, is.read((char *)&fwhm, sizeof(double)); + if (isCompatibleVersion(fileversionpart1, fileversionpart2, fileversionpart3, 2, 1, 34)) { + is.read((char *)&enableratio54Fe56Fe, sizeof(bool)); + is.read((char *)&enableratio60Ni58Ni, sizeof(bool)); + is.read((char *)&enableratio62Ni58Ni, sizeof(bool)); + is.read((char *)&enableratio65Cu63Cu, sizeof(bool)); + is.read((char *)&enableratio66Zn64Zn, sizeof(bool)); + is.read((char *)&enableratio67Zn64Zn, sizeof(bool)); + is.read((char *)&enableratio68Zn64Zn, sizeof(bool)); + } + else { + enableratio54Fe56Fe = true; + enableratio60Ni58Ni = true; + enableratio62Ni58Ni = true; + enableratio65Cu63Cu = true; + enableratio66Zn64Zn = true; + enableratio67Zn64Zn = true; + enableratio68Zn64Zn = true; + } + if (isCompatibleVersion(fileversionpart1, fileversionpart2, fileversionpart3, 2, 0, 37)) { is.read((char *)&minratio54Fe56Fe, sizeof(double)); is.read((char *)&maxratio54Fe56Fe, sizeof(double)); @@ -3006,6 +3260,45 @@ void cParameters::load(ifstream& is, int fileversionpart1, int fileversionpart2, maxratio54Fe56Fe = 0.1; } + if (isCompatibleVersion(fileversionpart1, fileversionpart2, fileversionpart3, 2, 1, 33)) { + is.read((char *)&minratio60Ni58Ni, sizeof(double)); + is.read((char *)&maxratio60Ni58Ni, sizeof(double)); + + is.read((char *)&minratio62Ni58Ni, sizeof(double)); + is.read((char *)&maxratio62Ni58Ni, sizeof(double)); + + is.read((char *)&minratio65Cu63Cu, sizeof(double)); + is.read((char *)&maxratio65Cu63Cu, sizeof(double)); + + is.read((char *)&minratio66Zn64Zn, sizeof(double)); + is.read((char *)&maxratio66Zn64Zn, sizeof(double)); + + is.read((char *)&minratio67Zn64Zn, sizeof(double)); + is.read((char *)&maxratio67Zn64Zn, sizeof(double)); + + is.read((char *)&minratio68Zn64Zn, sizeof(double)); + is.read((char *)&maxratio68Zn64Zn, sizeof(double)); + } + else { + minratio60Ni58Ni = 0; + maxratio60Ni58Ni = 0.5; + + minratio62Ni58Ni = 0; + maxratio62Ni58Ni = 0.1; + + minratio65Cu63Cu = 0; + maxratio65Cu63Cu = 0.6; + + minratio66Zn64Zn = 0; + maxratio66Zn64Zn = 0.7; + + minratio67Zn64Zn = 0; + maxratio67Zn64Zn = 0.2; + + minratio68Zn64Zn = 0; + maxratio68Zn64Zn = 0.5; + } + loadString(bricksdatabasefilename, is); bricksdatabase.load(is); @@ -3197,3 +3490,43 @@ void cParameters::load(ifstream& is, int fileversionpart1, int fileversionpart2, is.read((char *)&vendor, sizeof(eVendorType)); } + +bool compareHints(const hintStructure& a, const hintStructure& b) { + return a.mz < b.mz; +} + + +void searchHintForDeNovo(double mzratio, vector& experimentalpeaks, double fragmentmasserrortolerance, set& hintset) { + int left, right, middle, tmp; + int experimentalpeakssize = (int)experimentalpeaks.size(); + + left = 0; + right = experimentalpeakssize - 1; + while (left <= right) { + middle = (left + right) / 2; + if (isInPpmMassErrorTolerance(experimentalpeaks[middle].mz, mzratio, fragmentmasserrortolerance)) { + hintset.insert(experimentalpeaks[middle].id); + + tmp = middle - 1; + while ((tmp >= 0) && isInPpmMassErrorTolerance(experimentalpeaks[tmp].mz, mzratio, fragmentmasserrortolerance)) { + hintset.insert(experimentalpeaks[tmp].id); + tmp--; + } + + tmp = middle + 1; + while ((tmp < experimentalpeakssize) && isInPpmMassErrorTolerance(experimentalpeaks[tmp].mz, mzratio, fragmentmasserrortolerance)) { + hintset.insert(experimentalpeaks[tmp].id); + tmp++; + } + + return; + } + if (mzratio < experimentalpeaks[middle].mz) { + right = middle - 1; + } + else { + left = middle + 1; + } + } +} + diff --git a/CycloBranch/core/cParameters.h b/CycloBranch/core/cParameters.h index c3cbdf2..0e23bfc 100644 --- a/CycloBranch/core/cParameters.h +++ b/CycloBranch/core/cParameters.h @@ -9,6 +9,7 @@ #include #include +#include #include "core/utilities.h" #include "core/cGlobalPreferences.h" #include "core/cPeakListSeries.h" @@ -49,7 +50,8 @@ enum eScoreType { number_of_b_ions = 2, number_of_y_ions = 3, number_of_b_and_y_ions = 4, - weighted_ratio_of_matched_peaks = 5 + weighted_ratio_of_matched_peaks = 5, + cosine_similarity = 6 }; @@ -235,6 +237,12 @@ class cParameters { double fwhm; + /** + \brief Enable 54Fe/56Fe ratio. + */ + bool enableratio54Fe56Fe; + + /** \brief Minimum ratio 54Fe/56Fe. */ @@ -247,6 +255,114 @@ class cParameters { double maxratio54Fe56Fe; + /** + \brief Enable 60Ni/58Ni ratio. + */ + bool enableratio60Ni58Ni; + + + /** + \brief Minimum ratio 60Ni/58Ni. + */ + double minratio60Ni58Ni; + + + /** + \brief Maximum ratio 60Ni/58Ni. + */ + double maxratio60Ni58Ni; + + + /** + \brief Enable 62Ni/58Ni ratio. + */ + bool enableratio62Ni58Ni; + + + /** + \brief Minimum ratio 62Ni/58Ni. + */ + double minratio62Ni58Ni; + + + /** + \brief Maximum ratio 62Ni/58Ni. + */ + double maxratio62Ni58Ni; + + + /** + \brief Enable 65Cu/63Cu ratio. + */ + bool enableratio65Cu63Cu; + + + /** + \brief Minimum ratio 65Cu/63Cu. + */ + double minratio65Cu63Cu; + + + /** + \brief Maximum ratio 65Cu/63Cu. + */ + double maxratio65Cu63Cu; + + + /** + \brief Enable 66Zn/64Zn ratio. + */ + bool enableratio66Zn64Zn; + + + /** + \brief Minimum ratio 66Zn/64Zn. + */ + double minratio66Zn64Zn; + + + /** + \brief Maximum ratio 66Zn/64Zn. + */ + double maxratio66Zn64Zn; + + + /** + \brief Enable 67Zn/64Zn ratio. + */ + bool enableratio67Zn64Zn; + + + /** + \brief Minimum ratio 67Zn/64Zn. + */ + double minratio67Zn64Zn; + + + /** + \brief Maximum ratio 67Zn/64Zn. + */ + double maxratio67Zn64Zn; + + + /** + \brief Enable 68Zn/64Zn ratio. + */ + bool enableratio68Zn64Zn; + + + /** + \brief Minimum ratio 68Zn/64Zn. + */ + double minratio68Zn64Zn; + + + /** + \brief Maximum ratio 68Zn/64Zn. + */ + double maxratio68Zn64Zn; + + /** \brief A file name of a bricks database. */ @@ -738,7 +854,43 @@ class cParameters { /** \brief Register cParameters by Qt. */ -Q_DECLARE_METATYPE(cParameters); +Q_DECLARE_METATYPE(cParameters); + + +/** + \brief An auxiliary structure for search hints. +*/ +struct hintStructure { + + /** + \brief m/z value. + */ + double mz; + + + /** + \brief Spectrum ID. + */ + int id; + +}; + + +/** + \brief An auxiliary comparator for search hints. +*/ +bool compareHints(const hintStructure& a, const hintStructure& b); + + + +/** + \brief Get IDs of spectra in which the theoretical m/z ratio can be found. + \param mzratio theoretical m/z ratio + \param experimentalpeaks a sorted vector of hint structures + \param fragmentmasserrortolerance m/z error tolerance + \param hintset output set of spectra IDs +*/ +void searchHintForDeNovo(double mzratio, vector& experimentalpeaks, double fragmentmasserrortolerance, set& hintset); #endif \ No newline at end of file diff --git a/CycloBranch/core/cTheoreticalSpectrum.cpp b/CycloBranch/core/cTheoreticalSpectrum.cpp index e6e41a3..f06abc9 100644 --- a/CycloBranch/core/cTheoreticalSpectrum.cpp +++ b/CycloBranch/core/cTheoreticalSpectrum.cpp @@ -142,6 +142,10 @@ void cTheoreticalSpectrum::searchForPeakPairs(cPeaksList& theoreticalpeaks, int void cTheoreticalSpectrum::computeStatistics(bool writedescription) { double sumofallintensities = 0; + + double expsquare = 0; + double expsquarematched = 0; + double tmpsquare; experimentalpeaksmatched = 0; scrambledpeaksmatched = 0; @@ -154,12 +158,19 @@ void cTheoreticalSpectrum::computeStatistics(bool writedescription) { for (int i = 0; i < (int)experimentalpeaks.size(); i++) { sumofallintensities += experimentalpeaks[i].relativeintensity; + if (parameters && ((parameters->mode == denovoengine) || (parameters->mode == singlecomparison) || (parameters->mode == databasesearch))) { + tmpsquare = experimentalpeaks[i].relativeintensity / 100.0; + expsquare += tmpsquare * tmpsquare; + } + if (experimentalpeaks[i].matched > 0) { experimentalpeaksmatched++; sumofrelativeintensities += experimentalpeaks[i].relativeintensity; - + if (parameters && ((parameters->mode == denovoengine) || (parameters->mode == singlecomparison) || (parameters->mode == databasesearch))) { + expsquarematched += tmpsquare * tmpsquare; + if (!experimentalpeaks[i].scrambled) { matchedions[experimentalpeaks[i].iontype][experimentalpeaks[i].neutrallosstype]++; } @@ -178,8 +189,20 @@ void cTheoreticalSpectrum::computeStatistics(bool writedescription) { peakstested = experimentalpeaks.size(); weightedpeaksratio = 0; + cosinesimilarity = 0; if (experimentalpeaks.size() > 0) { experimentalpeaksmatchedratio = ((double)experimentalpeaksmatched) / ((double)experimentalpeaks.size()); + + if (parameters && ((parameters->mode == denovoengine) || (parameters->mode == singlecomparison) || (parameters->mode == databasesearch))) { + if ((expsquare > 0) && (expsquarematched > 0)) { + // the number of bins is defined by the number of experimental peaks + // theoretical intensities are the same as experimental intensities + cosinesimilarity = expsquarematched; + cosinesimilarity /= sqrt(expsquarematched); + cosinesimilarity /= sqrt(expsquare); + } + } + if (sumofallintensities > 0) { weightedpeaksratio = sumofrelativeintensities / sumofallintensities; } @@ -722,23 +745,30 @@ void cTheoreticalSpectrum::generateScrambledIons(cBricksDatabase& bricksdatabase scrambledsequences.clear(); int numberofbricks = (int)stringcomposition.size(); + int stop = (1 << numberofbricks) - 1; string subseq; int brickscount; + int part; // generate all possible combinations of blocks for (int i = 1; i < stop; i++) { subseq = ""; brickscount = 0; + part = i; for (int j = 0; j < numberofbricks; j++) { - if ((i >> j) % 2 == 1) { + if (part == 0) { + break; + } + if (part % 2 == 1) { if (brickscount > 0) { subseq += "-"; } subseq += stringcomposition[j]; brickscount++; } + part = part >> 1; } if ((brickscount > 1) && (brickscount < numberofbricks - 1)) { scrambledsequences.insert(subseq); @@ -1276,6 +1306,7 @@ void cTheoreticalSpectrum::removeUnmatchedMetalIsotopes(cPeaksList& theoreticalp continue; } + // parent is not matched, remove current peak if ((theoreticalpeaks[lastparent].matched == 0) && (theoreticalpeaks[i].matched > 0)) { experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; @@ -1284,42 +1315,282 @@ void cTheoreticalSpectrum::removeUnmatchedMetalIsotopes(cPeaksList& theoreticalp theoreticalpeaks[i].matchedid = -1; } - if ((theoreticalpeaks[lastparent].matched > 0) && (theoreticalpeaks[i].matched == 0)) { - pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("54Fe"); - if ((pos != string::npos) && (parameters->minratio54Fe56Fe > 0)) { - // remove 56Fe - experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); - experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + // parent peak matched, current peak unmatched; remove parent if minimum ratio is bigger than zero + if ((theoreticalpeaks[lastparent].matched > 0) && (theoreticalpeaks[i].matched == 0) && (theoreticalpeaks[i].descriptionid >= 0)) { - theoreticalpeaks[lastparent].matched--; - theoreticalpeaks[lastparent].matchedid = -1; + if (parameters->enableratio54Fe56Fe && (parameters->minratio54Fe56Fe > 0)) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("54Fe"); + if (pos != string::npos) { + // remove 56Fe + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + } } - } - // to do - // other elements - // multiple Fe atoms in a molecule - // 54Fe vs. 56Fe m/z difference + charged variants - if ((theoreticalpeaks[lastparent].matched > 0) && (theoreticalpeaks[i].matched > 0)) { - pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("54Fe"); - if ((pos != string::npos) && (experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity > 0)) { - ratio = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity / experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity; - if ((ratio < parameters->minratio54Fe56Fe) || (ratio > parameters->maxratio54Fe56Fe)) { - // remove 56Fe + if (parameters->enableratio60Ni58Ni && (parameters->minratio60Ni58Ni > 0)) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("60Ni"); + if (pos != string::npos) { + // remove 58Ni + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + } + } + + /* + if (parameters->enableratio62Ni58Ni && (parameters->minratio62Ni58Ni > 0)) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("62Ni"); + if (pos != string::npos) { + // remove 58Ni experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; theoreticalpeaks[lastparent].matched--; theoreticalpeaks[lastparent].matchedid = -1; + } + } + */ - // remove 54Fe - experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); - experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + if (parameters->enableratio65Cu63Cu && (parameters->minratio65Cu63Cu > 0)) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("65Cu"); + if (pos != string::npos) { + // remove 63Cu + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; - theoreticalpeaks[i].matched--; - theoreticalpeaks[i].matchedid = -1; + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + } + } + + if (parameters->enableratio66Zn64Zn && (parameters->minratio66Zn64Zn > 0)) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("66Zn"); + if (pos != string::npos) { + // remove 64Zn + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + } + } + + /* + if (parameters->enableratio67Zn64Zn && (parameters->minratio67Zn64Zn > 0)) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("67Zn"); + if (pos != string::npos) { + // remove 64Zn + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + } + } + */ + + if (parameters->enableratio68Zn64Zn && (parameters->minratio68Zn64Zn > 0)) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("68Zn"); + if (pos != string::npos) { + // remove 64Zn + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + } + } + + } + + // to do + // other elements + // multiple Fe atoms in a molecule + // 54Fe vs. 56Fe m/z difference (and Ni, Cu, Zn m/z differences) + charged variants + // parent peak matched, current peak matched; remove both if the isotope ratio does not match the tolerance + if ((theoreticalpeaks[lastparent].matched > 0) && (theoreticalpeaks[i].matched > 0) && (theoreticalpeaks[i].descriptionid >= 0)) { + + if (parameters->enableratio54Fe56Fe) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("54Fe"); + if ((pos != string::npos) && (experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity > 0)) { + ratio = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity / experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity; + if ((ratio < parameters->minratio54Fe56Fe) || (ratio > parameters->maxratio54Fe56Fe)) { + // remove 56Fe + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + + // remove 54Fe + experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); + experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + + theoreticalpeaks[i].matched--; + theoreticalpeaks[i].matchedid = -1; + } + } + } + + if (parameters->enableratio60Ni58Ni) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("60Ni"); + if ((pos != string::npos) && (experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity > 0)) { + ratio = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity / experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity; + if ((ratio < parameters->minratio60Ni58Ni) || (ratio > parameters->maxratio60Ni58Ni)) { + // remove 58Ni + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + + // remove 60Ni + experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); + experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + + theoreticalpeaks[i].matched--; + theoreticalpeaks[i].matchedid = -1; + } + } + } + + /* + if (parameters->enableratio62Ni58Ni) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("62Ni"); + if ((pos != string::npos) && (experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity > 0)) { + ratio = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity / experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity; + if ((ratio < parameters->minratio62Ni58Ni) || (ratio > parameters->maxratio62Ni58Ni)) { + // remove 58Ni + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + + // remove 62Ni + experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); + experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + + theoreticalpeaks[i].matched--; + theoreticalpeaks[i].matchedid = -1; + } + } + } + */ + + if (parameters->enableratio65Cu63Cu) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("65Cu"); + if ((pos != string::npos) && (experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity > 0)) { + ratio = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity / experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity; + if ((ratio < parameters->minratio65Cu63Cu) || (ratio > parameters->maxratio65Cu63Cu)) { + // remove 63Cu + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + + // remove 65Cu + experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); + experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + + theoreticalpeaks[i].matched--; + theoreticalpeaks[i].matchedid = -1; + } + } + } + + if (parameters->enableratio66Zn64Zn) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("66Zn"); + if ((pos != string::npos) && (experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity > 0)) { + ratio = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity / experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity; + if ((ratio < parameters->minratio66Zn64Zn) || (ratio > parameters->maxratio66Zn64Zn)) { + // remove 64Zn + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + + // remove 66Zn + experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); + experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + + theoreticalpeaks[i].matched--; + theoreticalpeaks[i].matchedid = -1; + } + } + } + + /* + if (parameters->enableratio67Zn64Zn) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("67Zn"); + if ((pos != string::npos) && (experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity > 0)) { + ratio = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity / experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity; + if ((ratio < parameters->minratio67Zn64Zn) || (ratio > parameters->maxratio67Zn64Zn)) { + // remove 64Zn + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + + // remove 67Zn + experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); + experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + + theoreticalpeaks[i].matched--; + theoreticalpeaks[i].matchedid = -1; + } } } + */ + + if (parameters->enableratio68Zn64Zn) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find("68Zn"); + if ((pos != string::npos) && (experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity > 0)) { + ratio = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity / experimentalpeaks[theoreticalpeaks[lastparent].matchedid].relativeintensity; + if ((ratio < parameters->minratio68Zn64Zn) || (ratio > parameters->maxratio68Zn64Zn)) { + // remove 64Zn + experimentalmatches[theoreticalpeaks[lastparent].matchedid].erase(experimentalmatches[theoreticalpeaks[lastparent].matchedid].find(lastparent)); + experimentalpeaks[theoreticalpeaks[lastparent].matchedid].matched--; + + theoreticalpeaks[lastparent].matched--; + theoreticalpeaks[lastparent].matchedid = -1; + + // remove 68Zn + experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); + experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + + theoreticalpeaks[i].matched--; + theoreticalpeaks[i].matchedid = -1; + } + } + } + + } + + } + + // second round is required if an element has multiple isotopes + for (int i = 0; i < theoreticalpeaksrealsize; i++) { + if (!theoreticalpeaks[i].isotope) { + lastparent = i; + continue; + } + + // parent is not matched, remove current peak + if ((theoreticalpeaks[lastparent].matched == 0) && (theoreticalpeaks[i].matched > 0)) { + experimentalmatches[theoreticalpeaks[i].matchedid].erase(experimentalmatches[theoreticalpeaks[i].matchedid].find(i)); + experimentalpeaks[theoreticalpeaks[i].matchedid].matched--; + + theoreticalpeaks[i].matched--; + theoreticalpeaks[i].matchedid = -1; } } } @@ -1855,10 +2126,21 @@ void cTheoreticalSpectrum::removeUnmatchedPatternsFineSpectra(cPeaksList& theore maximumexperimentalintensity = experimentalpeaks[theoreticalpeaks[maximumintensityid].matchedid].relativeintensity; } - langle = (int)parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].rfind('('); - rangle = (int)parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].rfind(')'); + if (theoreticalpeaks[start].descriptionid >= 0) { + langle = (int)parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].rfind('('); + rangle = (int)parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].rfind(')'); + } + else { + langle = (int)theoreticalpeaks[start].description.rfind('('); + rangle = (int)theoreticalpeaks[start].description.rfind(')'); + } if ((langle != string::npos) && (rangle != string::npos)) { - subdesc = parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].substr(langle + 1, rangle - langle - 1); + if (theoreticalpeaks[start].descriptionid >= 0) { + subdesc = parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].substr(langle + 1, rangle - langle - 1); + } + else { + subdesc = theoreticalpeaks[start].description.substr(langle + 1, rangle - langle - 1); + } subdescsize = subdesc.size(); elempos = subdesc.find("Li"); @@ -1895,6 +2177,8 @@ void cTheoreticalSpectrum::removeUnmatchedPatternsFineSpectra(cPeaksList& theore if (parameters->fwhm <= fwhmthreshold) { + // high-res + elempos = subdesc.find("Mg"); if (elempos != string::npos) { hasMg = true; @@ -1955,6 +2239,26 @@ void cTheoreticalSpectrum::removeUnmatchedPatternsFineSpectra(cPeaksList& theore } } + else { + + // low-res + + elempos = subdesc.find("Ni"); + if (elempos != string::npos) { + hasNi = true; + } + + elempos = subdesc.find("Cu"); + if (elempos != string::npos) { + hasCu = true; + } + + elempos = subdesc.find("Zn"); + if (elempos != string::npos) { + hasZn = true; + } + + } } @@ -1976,39 +2280,41 @@ void cTheoreticalSpectrum::removeUnmatchedPatternsFineSpectra(cPeaksList& theore // lithium if (hasLi) { - if (checkIsotope(elementLi, isotopeLi6, Li6, Li7, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementLi, isotopeLi6, Li6, Li7, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // boron if (hasB) { - if (checkIsotope(elementB, isotopeB10, B10, B11, 0.000001, 0.3, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementB, isotopeB10, B10, B11, 0.000001, 0.3, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // titanium (part 1) if (hasTi) { - if (checkIsotope(elementTi, isotopeTi46, Ti46, Ti48, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementTi, isotopeTi46, Ti46, Ti48, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } - if (checkIsotope(elementTi, isotopeTi47, Ti47, Ti48, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementTi, isotopeTi47, Ti47, Ti48, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // chromium (part 1) if (hasCr) { - if (checkIsotope(elementCr, isotopeCr50, Cr50, Cr52, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementCr, isotopeCr50, Cr50, Cr52, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // iron if (hasFe) { - if (checkIsotope(elementFe, isotopeFe54, Fe54, Fe56, parameters->minratio54Fe56Fe, parameters->maxratio54Fe56Fe, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { - cleargroup = true; + if (parameters->enableratio54Fe56Fe) { + if (checkIsotopeHighRes(elementFe, isotopeFe54, Fe54, Fe56, parameters->minratio54Fe56Fe, parameters->maxratio54Fe56Fe, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } } } @@ -2016,99 +2322,164 @@ void cTheoreticalSpectrum::removeUnmatchedPatternsFineSpectra(cPeaksList& theore // magnesium if (hasMg) { - if (checkIsotope(elementMg, isotopeMg25, Mg25, Mg24, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementMg, isotopeMg25, Mg25, Mg24, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } - if (checkIsotope(elementMg, isotopeMg26, Mg26, Mg24, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementMg, isotopeMg26, Mg26, Mg24, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // silicon if (hasSi) { - if (checkIsotope(elementSi, isotopeSi29, Si29, Si28, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementSi, isotopeSi29, Si29, Si28, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } - if (checkIsotope(elementSi, isotopeSi30, Si30, Si28, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementSi, isotopeSi30, Si30, Si28, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // sulfur if (hasS) { - if (checkIsotope(elementS, isotopeS34, S34, S32, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementS, isotopeS34, S34, S32, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // chlorine if (hasCl) { - if (checkIsotope(elementCl, isotopeCl37, Cl37, Cl35, 0.000001, 0.4, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementCl, isotopeCl37, Cl37, Cl35, 0.000001, 0.4, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // potassium if (hasK) { - if (checkIsotope(elementK, isotopeK41, K41, K39, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementK, isotopeK41, K41, K39, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // titanium (part 2) if (hasTi) { - if (checkIsotope(elementTi, isotopeTi49, Ti49, Ti48, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementTi, isotopeTi49, Ti49, Ti48, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } - if (checkIsotope(elementTi, isotopeTi50, Ti50, Ti48, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementTi, isotopeTi50, Ti50, Ti48, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // chromium (part 2) if (hasCr) { - if (checkIsotope(elementCr, isotopeCr53, Cr53, Cr52, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementCr, isotopeCr53, Cr53, Cr52, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } // nickel if (hasNi) { - if (checkIsotope(elementNi, isotopeNi60, Ni60, Ni58, 0.000001, 0.5, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { - cleargroup = true; + if (parameters->enableratio60Ni58Ni) { + if (checkIsotopeHighRes(elementNi, isotopeNi60, Ni60, Ni58, parameters->minratio60Ni58Ni, parameters->maxratio60Ni58Ni, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } } - if (checkIsotope(elementNi, isotopeNi62, Ni62, Ni58, 0.000001, 0.1, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { - cleargroup = true; + /* + if (parameters->enableratio62Ni58Ni) { + if (checkIsotopeHighRes(elementNi, isotopeNi62, Ni62, Ni58, parameters->minratio62Ni58Ni, parameters->maxratio62Ni58Ni, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } } + */ } // copper if (hasCu) { - if (checkIsotope(elementCu, isotopeCu65, Cu65, Cu63, 0.000001, 0.6, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { - cleargroup = true; + if (parameters->enableratio65Cu63Cu) { + if (checkIsotopeHighRes(elementCu, isotopeCu65, Cu65, Cu63, parameters->minratio65Cu63Cu, parameters->maxratio65Cu63Cu, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } } } // zinc if (hasZn) { - if (checkIsotope(elementZn, isotopeZn66, Zn66, Zn64, 0.000001, 0.7, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { - cleargroup = true; + if (parameters->enableratio66Zn64Zn) { + if (checkIsotopeHighRes(elementZn, isotopeZn66, Zn66, Zn64, parameters->minratio66Zn64Zn, parameters->maxratio66Zn64Zn, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } } - if (checkIsotope(elementZn, isotopeZn67, Zn67, Zn64, 0.000001, 0.2, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { - cleargroup = true; + /* + if (parameters->enableratio67Zn64Zn) { + if (checkIsotopeHighRes(elementZn, isotopeZn67, Zn67, Zn64, parameters->minratio67Zn64Zn, parameters->maxratio67Zn64Zn, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } } - if (checkIsotope(elementZn, isotopeZn68, Zn68, Zn64, 0.000001, 0.5, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { - cleargroup = true; + */ + if (parameters->enableratio68Zn64Zn) { + if (checkIsotopeHighRes(elementZn, isotopeZn68, Zn68, Zn64, parameters->minratio68Zn64Zn, parameters->maxratio68Zn64Zn, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } } } // gallium if (hasGa) { - if (checkIsotope(elementGa, isotopeGa71, Ga71, Ga69, 0.000001, 0.8, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + if (checkIsotopeHighRes(elementGa, isotopeGa71, Ga71, Ga69, 0.000001, 0.8, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { cleargroup = true; } } + } + else { + + // nickel + if (hasNi) { + if (parameters->enableratio60Ni58Ni) { + if (checkIsotopeLowRes(elementNi, isotopeNi60, Ni60, Ni58, parameters->minratio60Ni58Ni, parameters->maxratio60Ni58Ni, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } + } + /* + if (parameters->enableratio62Ni58Ni) { + if (checkIsotopeLowRes(elementNi, isotopeNi62, Ni62, Ni58, parameters->minratio62Ni58Ni, parameters->maxratio62Ni58Ni, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } + } + */ + } + + // copper + if (hasCu) { + if (parameters->enableratio65Cu63Cu) { + if (checkIsotopeLowRes(elementCu, isotopeCu65, Cu65, Cu63, parameters->minratio65Cu63Cu, parameters->maxratio65Cu63Cu, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } + } + } + + // zinc + if (hasZn) { + if (parameters->enableratio66Zn64Zn) { + if (checkIsotopeLowRes(elementZn, isotopeZn66, Zn66, Zn64, parameters->minratio66Zn64Zn, parameters->maxratio66Zn64Zn, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } + } + /* + if (parameters->enableratio67Zn64Zn) { + if (checkIsotopeLowRes(elementZn, isotopeZn67, Zn67, Zn64, parameters->minratio67Zn64Zn, parameters->maxratio67Zn64Zn, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } + } + */ + if (parameters->enableratio68Zn64Zn) { + if (checkIsotopeLowRes(elementZn, isotopeZn68, Zn68, Zn64, parameters->minratio68Zn64Zn, parameters->maxratio68Zn64Zn, theoreticalpeaks, theoreticalpeaksrealsize, experimentalpeaks, start, stop, maximumintensityid, maximumexperimentalintensity)) { + cleargroup = true; + } + } + } + } if (cleargroup) { @@ -2149,10 +2520,22 @@ void cTheoreticalSpectrum::removeUnmatchedPatternsFineSpectra(cPeaksList& theore maximumexperimentalintensity = experimentalpeaks[theoreticalpeaks[i].matchedid].relativeintensity; } - langle = (int)parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].rfind('('); - rangle = (int)parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].rfind(')'); + if (theoreticalpeaks[start].descriptionid >= 0) { + langle = (int)parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].rfind('('); + rangle = (int)parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].rfind(')'); + } + else { + langle = (int)theoreticalpeaks[start].description.rfind('('); + rangle = (int)theoreticalpeaks[start].description.rfind(')'); + + } if ((langle != string::npos) && (rangle != string::npos)) { - subdesc = parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].substr(langle + 1, rangle - langle - 1); + if (theoreticalpeaks[start].descriptionid >= 0) { + subdesc = parameters->peakidtodesc[theoreticalpeaks[start].descriptionid].substr(langle + 1, rangle - langle - 1); + } + else { + subdesc = theoreticalpeaks[start].description.substr(langle + 1, rangle - langle - 1); + } subdescsize = subdesc.size(); elempos = subdesc.find("Li"); @@ -2189,6 +2572,8 @@ void cTheoreticalSpectrum::removeUnmatchedPatternsFineSpectra(cPeaksList& theore if (parameters->fwhm <= fwhmthreshold) { + // high-res + elempos = subdesc.find("Mg"); if (elempos != string::npos) { hasMg = true; @@ -2249,6 +2634,26 @@ void cTheoreticalSpectrum::removeUnmatchedPatternsFineSpectra(cPeaksList& theore } } + else { + + // low-res + + elempos = subdesc.find("Ni"); + if (elempos != string::npos) { + hasNi = true; + } + + elempos = subdesc.find("Cu"); + if (elempos != string::npos) { + hasCu = true; + } + + elempos = subdesc.find("Zn"); + if (elempos != string::npos) { + hasZn = true; + } + + } } @@ -2988,7 +3393,7 @@ void cTheoreticalSpectrum::fillExperimentalAnnotationsAndRemoveUnmatchedTheoreti } -bool cTheoreticalSpectrum::checkIsotope(string& elementstring, string& isotopestring, double isotopemass1, double isotopemass2, double minintensityratio, double maxintensityratio, cPeaksList& theoreticalpeaks, int theoreticalpeaksrealsize, cPeaksList& experimentalpeaks, int start, int stop, int maximumintensityid, double maximumexperimentalintensity) { +bool cTheoreticalSpectrum::checkIsotopeHighRes(string& elementstring, string& isotopestring, double isotopemass1, double isotopemass2, double minintensityratio, double maxintensityratio, cPeaksList& theoreticalpeaks, int theoreticalpeaksrealsize, cPeaksList& experimentalpeaks, int start, int stop, int maximumintensityid, double maximumexperimentalintensity) { bool notdetected = false; int isotopeposition = -1; double intensitymultiplier = 1.0; @@ -3001,12 +3406,24 @@ bool cTheoreticalSpectrum::checkIsotope(string& elementstring, string& isotopest if (theoreticalpeaks[i].matched > 0) { mzdiff = fabs(uncharge(theoreticalpeaks[i].mzratio, theoreticalpeaks[i].charge) - uncharge(theoreticalpeaks[maximumintensityid].mzratio, theoreticalpeaks[maximumintensityid].charge) - isotopemass1 + isotopemass2); if (mzdiff < 0.1) { - if (parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find('%') == string::npos) { - pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].rfind(isotopestring); - if (pos != string::npos) { - intensitymultiplier = getIntensityMultiplier(theoreticalpeaks, i, elementstring, pos); - isotopeposition = i; - break; + if (theoreticalpeaks[i].descriptionid >= 0) { + if (parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find('%') == string::npos) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].rfind(isotopestring); + if (pos != string::npos) { + intensitymultiplier = getIntensityMultiplier(theoreticalpeaks, i, elementstring, pos); + isotopeposition = i; + break; + } + } + } + else { + if (theoreticalpeaks[i].description.find('%') == string::npos) { + pos = theoreticalpeaks[i].description.rfind(isotopestring); + if (pos != string::npos) { + intensitymultiplier = getIntensityMultiplier(theoreticalpeaks, i, elementstring, pos); + isotopeposition = i; + break; + } } } } @@ -3042,14 +3459,96 @@ bool cTheoreticalSpectrum::checkIsotope(string& elementstring, string& isotopest } +bool cTheoreticalSpectrum::checkIsotopeLowRes(string& elementstring, string& isotopestring, double isotopemass1, double isotopemass2, double minintensityratio, double maxintensityratio, cPeaksList& theoreticalpeaks, int theoreticalpeaksrealsize, cPeaksList& experimentalpeaks, int start, int stop, int maximumintensityid, double maximumexperimentalintensity) { + bool notdetected = false; + int isotopeposition = -1; + double intensitymultiplier = 1.0; + double mzdiff; + size_t pos; + + if (theoreticalpeaks[maximumintensityid].matched > 0) { + if (maximumexperimentalintensity >= parameters->minimumrelativeintensitythreshold) { + for (int i = start; i <= stop; i++) { + if (theoreticalpeaks[i].matched > 0) { + mzdiff = fabs(uncharge(theoreticalpeaks[i].mzratio, theoreticalpeaks[i].charge) - uncharge(theoreticalpeaks[maximumintensityid].mzratio, theoreticalpeaks[maximumintensityid].charge) - isotopemass1 + isotopemass2); + if (mzdiff < 0.2) { + if (theoreticalpeaks[i].descriptionid >= 0) { + //if (parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].find('%') == string::npos) { + pos = parameters->peakidtodesc[theoreticalpeaks[i].descriptionid].rfind(isotopestring); + if (pos != string::npos) { + //intensitymultiplier = getIntensityMultiplier(theoreticalpeaks, i, elementstring, pos); + isotopeposition = i; + break; + } + //} + } + else { + //if (theoreticalpeaks[i].description.find('%') == string::npos) { + pos = theoreticalpeaks[i].description.rfind(isotopestring); + if (pos != string::npos) { + //intensitymultiplier = getIntensityMultiplier(theoreticalpeaks, i, elementstring, pos); + isotopeposition = i; + break; + } + //} + } + } + } + } + } + } + + if (isotopeposition == -1) { + if (minintensityratio > 0) { + notdetected = true; + } + } + else { + if ((theoreticalpeaks[isotopeposition].matched > 0) && (theoreticalpeaks[maximumintensityid].matched > 0)) { + if (maximumexperimentalintensity >= parameters->minimumrelativeintensitythreshold) { + if (theoreticalpeaks[isotopeposition].relativeintensity*maximumexperimentalintensity / 100.0 >= parameters->minimumrelativeintensitythreshold) { + if (experimentalpeaks[theoreticalpeaks[isotopeposition].matchedid].relativeintensity > maxintensityratio * intensitymultiplier * maximumexperimentalintensity) { + notdetected = true; + } + if (experimentalpeaks[theoreticalpeaks[isotopeposition].matchedid].relativeintensity < minintensityratio * intensitymultiplier * maximumexperimentalintensity) { + notdetected = true; + } + } + else { + notdetected = true; + } + } + } + } + + return notdetected; +} + + double cTheoreticalSpectrum::getIntensityMultiplier(cPeaksList& theoreticalpeaks, int peakid, string& elementstring, size_t startpos) { - size_t pos = parameters->peakidtodesc[theoreticalpeaks[peakid].descriptionid].find(elementstring, startpos); + size_t pos; + + if (theoreticalpeaks[peakid].descriptionid >= 0) { + pos = parameters->peakidtodesc[theoreticalpeaks[peakid].descriptionid].find(elementstring, startpos); + } + else { + pos = theoreticalpeaks[peakid].description.find(elementstring, startpos); + } + if (pos == string::npos) { // one occurrence return 1.0; } - string shortstr = parameters->peakidtodesc[theoreticalpeaks[peakid].descriptionid].substr(pos + elementstring.size()); + string shortstr; + + if (theoreticalpeaks[peakid].descriptionid >= 0) { + shortstr = parameters->peakidtodesc[theoreticalpeaks[peakid].descriptionid].substr(pos + elementstring.size()); + } + else { + shortstr = theoreticalpeaks[peakid].description.substr(pos + elementstring.size()); + } + if ((shortstr.size() > 0) && (shortstr[0] == ' ')) { // two occurrences return 2.0; @@ -3094,6 +3593,7 @@ void cTheoreticalSpectrum::clear(bool clearpeaklist) { peakstested = 0; experimentalpeaksmatchedratio = 0; weightedpeaksratio = 0; + cosinesimilarity = 0; unmatchedexperimentalpeakscount = 0; coveragebyseries = ""; valid = false; @@ -4772,6 +5272,115 @@ void cTheoreticalSpectrum::compareMSSpectrum(int id, int peaklistseriesvectorid, } +void cTheoreticalSpectrum::compareAverageMSSpectrum(cPeaksList& averagespectrum, cTheoreticalSpectrum& tsfull, cPeaksList& unmatchedpeaksinmatchedpatterns) { + experimentalpeaks = averagespectrum; + + cPeaksList* tsfullpeaklist = tsfull.getTheoreticalPeaks(); + + experimentalmatches.clear(); + + searchForPeakPairs(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks, parameters->fragmentmasserrortolerance); + + if (parameters->generateisotopepattern) { + if ((parameters->minimumannotationintensityrelative > parameters->minimumrelativeintensitythreshold) || (parameters->minimumannotationintensityabsolute > parameters->minimumabsoluteintensitythreshold)) { + removePatternsUnderAnnotationThreshold(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks); + } + if (parameters->minimumpatternsize > 1) { + removeUnmatchedPatternsFineSpectra(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks); + } + if (parameters->intensitytolerance > 0) { + removeUnmatchedPatternsByIntensityRatio(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks); + } + if (parameters->mzdifftolerance > 0) { + removeUnmatchedPatternsByMZDifference(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks); + } + } + else { + if ((parameters->minimumannotationintensityrelative > parameters->minimumrelativeintensitythreshold) || (parameters->minimumannotationintensityabsolute > parameters->minimumabsoluteintensitythreshold)) { + removePeaksUnderAnnotationThreshold(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks); + } + } + + // pre-cleaning (relative intensity threshold, minimumpatternsize) + if (parameters->generateisotopepattern) { + if (parameters->minimumiontypes > 1) { + removeUnmatchedIsotopePatterns(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks, unmatchedpeaksinmatchedpatterns, false); + } + } + + // mark isotopes + if (parameters->generateisotopepattern) { + if (parameters->minimumiontypes > 1) { + tsfullpeaklist->markIsotopes(); + } + } + + if (parameters->minimumiontypes > 1) { + removeUnmatchedCompounds(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks, parameters->minimumiontypes); + } + + // clear marks of isotopes + if (parameters->generateisotopepattern) { + if (parameters->minimumiontypes > 1) { + tsfullpeaklist->setIsotopeFlags(false); + } + } + + // clear matched isotopes of unmatched monoisotopic peaks + unmatchedpeaksinmatchedpatterns.clear(); + if (parameters->generateisotopepattern) { + removeUnmatchedIsotopePatterns(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks, unmatchedpeaksinmatchedpatterns, true); + } + else { + removeUnmatchedMetalIsotopes(*tsfullpeaklist, tsfull.getNumberOfPeaks(), experimentalpeaks); + } + + if (parameters->reportunmatchedtheoreticalpeaks && !parameters->generateisotopepattern) { + theoreticalpeaks = *tsfullpeaklist; + + // fill annotations of experimental peaks + for (int i = 0; i < (int)experimentalpeaks.size(); i++) { + for (auto it = experimentalmatches[i].begin(); it != experimentalmatches[i].end(); ++it) { + theoreticalpeaks[*it].matchedmz = experimentalpeaks[i].mzratio; + theoreticalpeaks[*it].matchedrelativeintensity = experimentalpeaks[i].relativeintensity; + theoreticalpeaks[*it].matchedabsoluteintensity = experimentalpeaks[i].absoluteintensity; + theoreticalpeaks[*it].matchedppm = ppmError(experimentalpeaks[i].mzratio, theoreticalpeaks[*it].mzratio); + + (*tsfullpeaklist)[*it].matched = 0; + (*tsfullpeaklist)[*it].matchedid = -1; + } + } + } + else { + theoreticalpeaks.clear(); + vector > updatedexperimentalmatches; + updatedexperimentalmatches.resize(experimentalmatches.size()); + + // fill annotations of experimental peaks and remove unmatched theoretical peaks + for (int i = 0; i < (int)experimentalpeaks.size(); i++) { + for (auto it = experimentalmatches[i].begin(); it != experimentalmatches[i].end(); ++it) { + updatedexperimentalmatches[i].insert((int)theoreticalpeaks.size()); + + cPeak matchedpeak; + matchedpeak = (*tsfullpeaklist)[*it]; + + matchedpeak.matchedmz = experimentalpeaks[i].mzratio; + matchedpeak.matchedrelativeintensity = experimentalpeaks[i].relativeintensity; + matchedpeak.matchedabsoluteintensity = experimentalpeaks[i].absoluteintensity; + matchedpeak.matchedppm = ppmError(experimentalpeaks[i].mzratio, matchedpeak.mzratio); + theoreticalpeaks.add(matchedpeak); + + (*tsfullpeaklist)[*it].matched = 0; + (*tsfullpeaklist)[*it].matchedid = -1; + } + experimentalpeaks[i].matched = (int)updatedexperimentalmatches[i].size(); + } + + experimentalmatches = updatedexperimentalmatches; + } +} + + void cTheoreticalSpectrum::finalizeMSSpectrum(cPeaksList& unmatchedpeaksinmatchedpatterns, bool writedescription) { if (parameters->generateisotopepattern) { theoreticalpeaks.attach(unmatchedpeaksinmatchedpatterns); @@ -4884,6 +5493,11 @@ double cTheoreticalSpectrum::getWeightedRatioOfMatchedPeaks() const { } +double cTheoreticalSpectrum::getCosineSimilarity() const { + return cosinesimilarity; +} + + void cTheoreticalSpectrum::generateNTerminalFragmentIons(int maxcharge, int& peaklistrealsize, vector& intcomposition, eFragmentIonType fragmentiontype, int neutrallosstype, cBricksDatabase& bricksdatabase, bool writedescription, int rotationid, vector& splittingsites, vector& searchedmodifications, ePeptideType peptidetype, bool regularblocksorder, TRotationInfo* trotation, eResidueLossType leftresiduelosstype, bool hasfirstblockartificial) { cPeak peak; map atoms; @@ -5455,6 +6069,14 @@ cPeaksList& cTheoreticalSpectrum::getExperimentalSpectrum() { } +void cTheoreticalSpectrum::setExperimentalSpectrum(cPeaksList& experimentalspectrum) { + experimentalpeaks = experimentalspectrum; + + experimentalmatches.clear(); + experimentalmatches.resize(experimentalpeaks.size()); +} + + set& cTheoreticalSpectrum::getExperimentalMatches(int peakid) { return experimentalmatches[peakid]; } @@ -5761,6 +6383,7 @@ void cTheoreticalSpectrum::store(ofstream& os) { os.write((char *)&peakstested, sizeof(int)); os.write((char *)&experimentalpeaksmatchedratio, sizeof(double)); os.write((char *)&weightedpeaksratio, sizeof(double)); + os.write((char *)&cosinesimilarity, sizeof(double)); os.write((char *)&unmatchedexperimentalpeakscount, sizeof(int)); storeString(coveragebyseries, os); @@ -5845,6 +6468,13 @@ void cTheoreticalSpectrum::load(ifstream& is, int fileversionpart1, int filevers is.read((char *)&experimentalpeaksmatchedratio, sizeof(double)); is.read((char *)&weightedpeaksratio, sizeof(double)); + if (isCompatibleVersion(fileversionpart1, fileversionpart2, fileversionpart3, 2, 1, 22)) { + is.read((char *)&cosinesimilarity, sizeof(double)); + } + else { + cosinesimilarity = 0; + } + is.read((char *)&unmatchedexperimentalpeakscount, sizeof(int)); loadString(coveragebyseries, is); @@ -5932,6 +6562,11 @@ bool cTheoreticalSpectrum::equals(cTheoreticalSpectrum& secondtheoreticalspectru return false; } + if (!compareDoubles(cosinesimilarity, secondtheoreticalspectrum.cosinesimilarity)) { + cout << "cosinesimilarity does not match" << endl; + return false; + } + if (unmatchedexperimentalpeakscount != secondtheoreticalspectrum.unmatchedexperimentalpeakscount) { cout << "unmatchedexperimentalpeakscount does not match" << endl; return false; diff --git a/CycloBranch/core/cTheoreticalSpectrum.h b/CycloBranch/core/cTheoreticalSpectrum.h index 80cb173..228e9eb 100644 --- a/CycloBranch/core/cTheoreticalSpectrum.h +++ b/CycloBranch/core/cTheoreticalSpectrum.h @@ -116,6 +116,7 @@ class cTheoreticalSpectrum { int peakstested; double experimentalpeaksmatchedratio; double weightedpeaksratio; + double cosinesimilarity; int unmatchedexperimentalpeakscount; string coveragebyseries; bool valid; @@ -232,7 +233,10 @@ class cTheoreticalSpectrum { void fillExperimentalAnnotationsAndRemoveUnmatchedTheoreticalPeaks(int& theoreticalpeaksrealsize, ePeptideType peptidetype, cPeaksList& unmatchedpeaksinmatchedpatterns, bool reportunmatchedtheoreticalpeaks, bool writedescription); // check the existence of an isotope - bool checkIsotope(string& elementstring, string& isotopestring, double isotopemass1, double isotopemass2, double minintensityratio, double maxintensityratio, cPeaksList& theoreticalpeaks, int theoreticalpeaksrealsize, cPeaksList& experimentalpeaks, int start, int stop, int maximumintensityid, double maximumexperimentalintensity); + bool checkIsotopeHighRes(string& elementstring, string& isotopestring, double isotopemass1, double isotopemass2, double minintensityratio, double maxintensityratio, cPeaksList& theoreticalpeaks, int theoreticalpeaksrealsize, cPeaksList& experimentalpeaks, int start, int stop, int maximumintensityid, double maximumexperimentalintensity); + + // check the existence of an isotope + bool checkIsotopeLowRes(string& elementstring, string& isotopestring, double isotopemass1, double isotopemass2, double minintensityratio, double maxintensityratio, cPeaksList& theoreticalpeaks, int theoreticalpeaksrealsize, cPeaksList& experimentalpeaks, int start, int stop, int maximumintensityid, double maximumexperimentalintensity); // get intensity multiplier double getIntensityMultiplier(cPeaksList& theoreticalpeaks, int peakid, string& elementstring, size_t startpos); @@ -423,6 +427,16 @@ class cTheoreticalSpectrum { void compareMSSpectrum(int id, int peaklistseriesvectorid, cTheoreticalSpectrum& tsfull, cPeaksList& unmatchedpeaksinmatchedpatterns, vector< vector >& hintsindex, bool lcmsrt, bool skipcomparison); + /** + \brief Compare theoretical peaks with an average spectrum. + \param averagespectrum average experimental spectrum + \param tsfull theoretical spectrum with descriptions of peaks + \param unmatchedpeaksinmatchedpatterns unmatched peaks in matched isotope patterns + */ + void compareAverageMSSpectrum(cPeaksList& averagespectrum, cTheoreticalSpectrum& tsfull, cPeaksList& unmatchedpeaksinmatchedpatterns); + + + /** \brief Finalize MS spectrum after comparison. \param unmatchedpeaksinmatchedpatterns unmatched peaks in matched isotope patterns @@ -489,6 +503,13 @@ class cTheoreticalSpectrum { double getWeightedRatioOfMatchedPeaks() const; + /** + \brief Get cosine similarity. + \retval double cosine similarity + */ + double getCosineSimilarity() const; + + /** \brief Generate a N-terminal fragment ion series. \param maxcharge a charge of precursor ion @@ -567,6 +588,13 @@ class cTheoreticalSpectrum { cPeaksList& getExperimentalSpectrum(); + /** + \brief Set the experimental spectrum. + \param experimentalspectrum an experimental spectrum + */ + void setExperimentalSpectrum(cPeaksList& experimentalspectrum); + + /** \brief Get ids of theoretical peaks which hit an experimental peak. \retval set set of ids of theoretical peaks diff --git a/CycloBranch/core/cTheoreticalSpectrumList.cpp b/CycloBranch/core/cTheoreticalSpectrumList.cpp index 06daac4..6b59bd2 100644 --- a/CycloBranch/core/cTheoreticalSpectrumList.cpp +++ b/CycloBranch/core/cTheoreticalSpectrumList.cpp @@ -423,6 +423,9 @@ double cTheoreticalSpectrumList::updatekNNList(cTheoreticalSpectrum& theoretical case weighted_ratio_of_matched_peaks: comparatorfunction = &compareWeightedRatioDesc; break; + case cosine_similarity: + comparatorfunction = &compareCosineSimilarityDesc; + break; default: break; } @@ -453,6 +456,9 @@ double cTheoreticalSpectrumList::updatekNNList(cTheoreticalSpectrum& theoretical case weighted_ratio_of_matched_peaks: currentscore = it1->getWeightedRatioOfMatchedPeaks(); break; + case cosine_similarity: + currentscore = it1->getCosineSimilarity(); + break; default: break; } @@ -491,6 +497,9 @@ double cTheoreticalSpectrumList::updatekNNList(cTheoreticalSpectrum& theoretical case weighted_ratio_of_matched_peaks: currentworstscore = prev(spectrumbuffer.end())->getWeightedRatioOfMatchedPeaks(); break; + case cosine_similarity: + currentworstscore = prev(spectrumbuffer.end())->getCosineSimilarity(); + break; default: break; } @@ -521,6 +530,9 @@ void cTheoreticalSpectrumList::sortAndFitSize(int fileid) { case weighted_ratio_of_matched_peaks: sort(theoreticalspectra[fileid].begin(), theoreticalspectra[fileid].end(), compareWeightedRatioDesc); break; + case cosine_similarity: + sort(theoreticalspectra[fileid].begin(), theoreticalspectra[fileid].end(), compareCosineSimilarityDesc); + break; default: break; } diff --git a/CycloBranch/core/utilities.cpp b/CycloBranch/core/utilities.cpp index 2ae12b7..762f63e 100644 --- a/CycloBranch/core/utilities.cpp +++ b/CycloBranch/core/utilities.cpp @@ -4,7 +4,7 @@ QString appname = "CycloBranch"; -QString appversion = "v. 2.1.21 (64-bit)"; +QString appversion = "v. 2.1.35 (64-bit)"; QString lastcompatibleappversion = "v. 2.0.8 (64-bit)"; @@ -404,7 +404,7 @@ string getStringFromPeptideType(ePeptideType peptidetype) { double cropPrecisionToSixDecimals(double value) { - char buffer[50]; + char buffer[500]; double val; sprintf_s(buffer, "%.6f\0", value); sscanf_s(buffer, "%lf", &val); @@ -413,7 +413,7 @@ double cropPrecisionToSixDecimals(double value) { QByteArray cropDecimalsByteArray(double value) { - char buffer[50]; + char buffer[500]; sprintf_s(buffer, "%.0f\0", value); QByteArray bytearray = buffer; return bytearray; @@ -421,7 +421,7 @@ QByteArray cropDecimalsByteArray(double value) { QByteArray cropPrecisionToSixDecimalsByteArray(double value) { - char buffer[50]; + char buffer[500]; sprintf_s(buffer, "%.6f\0", value); QByteArray bytearray = buffer; return bytearray; diff --git a/CycloBranch/docs/cyclobranch_ejms_bib.txt b/CycloBranch/docs/cyclobranch_ejms_bib.txt new file mode 100644 index 0000000..1aa48d5 --- /dev/null +++ b/CycloBranch/docs/cyclobranch_ejms_bib.txt @@ -0,0 +1,10 @@ +@ARTICLE{CycloBranch-EJMS-2023, +author={Novak, Jiri and Schug, Kevin A. and Havlicek, Vladimir}, +title={Quantitation of Small Molecules from Liquid Chromatography-Mass Spectrometric Accurate Mass Datasets using CycloBranch}, +journal={Eur. J. Mass Spectrom.}, +volume={29}, +number={2}, +year={2023}, +pages={102--110}, +doi={10.1177/14690667231164766} +} diff --git a/CycloBranch/docs/cyclobranch_ejms_ris.txt b/CycloBranch/docs/cyclobranch_ejms_ris.txt new file mode 100644 index 0000000..1beaded --- /dev/null +++ b/CycloBranch/docs/cyclobranch_ejms_ris.txt @@ -0,0 +1,14 @@ +TY - JOUR +TI - Quantitation of Small Molecules from Liquid Chromatography-Mass Spectrometric Accurate Mass Datasets using CycloBranch +T2 - Eur. J. Mass Spectrom. +VL - 29 +IS - 2 +SP - 102-110 +PY - 2023 +AU - Novak,Jiri +AU - Schug,Kevin A. +AU - Havlicek,Vladimir +N1 - +DB - +DO - 10.1177/14690667231164766 +ER - diff --git a/CycloBranch/gui/cAboutWidget.cpp b/CycloBranch/gui/cAboutWidget.cpp index 66925af..cea8ae9 100644 --- a/CycloBranch/gui/cAboutWidget.cpp +++ b/CycloBranch/gui/cAboutWidget.cpp @@ -42,9 +42,14 @@ cAboutWidget::cAboutWidget(QWidget* parent) { citations += "Jiri Novak, Anton Skriba, Jakub Zapal, Marek Kuzma, Vladimir Havlicek:
"; citations += "CycloBranch: an Open Tool for Fine Isotope Structures in Conventional and Product Ion Mass Spectra,
"; citations += "J. Mass Spectrom., vol. 53, no. 11, pp. 1097-1103, 2018. DOI: 10.1002/jms.4285.
"; - citations += "Download citation: [ ris ], [ bib ]


"; + citations += "Download citation: [ ris ], [ bib ]

"; - QString developers = "Developers:

Jiri Novak
Laboratory of Molecular Structure Characterization
Institute of Microbiology
Czech Academy of Sciences
Videnska 1083
142 20 Prague
Czech Republic
jiri.novak@biomed.cas.cz

(C) 2013 - 2022


"; + citations += "Jiri Novak, Kevin A. Schug, Vladimir Havlicek:
"; + citations += "Quantitation of Small Molecules from Liquid Chromatography-Mass Spectrometric Accurate Mass Datasets using CycloBranch,
"; + citations += "Eur. J. Mass Spectrom., vol. 29, no. 2, pp. 102-110, 2023. DOI: 10.1177/14690667231164766.
"; + citations += "Download citation: [ ris ], [ bib ]


"; + + QString developers = "Developers:

Jiri Novak
Laboratory of Molecular Structure Characterization
Institute of Microbiology
Czech Academy of Sciences
Videnska 1083
142 20 Prague
Czech Republic
jiri.novak@biomed.cas.cz

(C) 2013 - 2023


"; QString license = "License:

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

"; license += "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

"; diff --git a/CycloBranch/gui/cCalibrationChart.cpp b/CycloBranch/gui/cCalibrationChart.cpp index 9ebc477..d89a444 100644 --- a/CycloBranch/gui/cCalibrationChart.cpp +++ b/CycloBranch/gui/cCalibrationChart.cpp @@ -20,7 +20,7 @@ cCalibrationChart::cCalibrationChart(cGlobalPreferences* globalpreferences, QWid this->parent = parent; this->globalpreferences = globalpreferences; - setWindowTitle("Calibration Curve"); + setWindowTitle("Calibration Curve and Statistics"); setWindowIcon(QIcon(":/images/icons/features.png")); vsplitter = new QSplitter(); @@ -91,55 +91,72 @@ cCalibrationChart::cCalibrationChart(cGlobalPreferences* globalpreferences, QWid toolbarHelp->addAction(actionHTMLDocumentation); connect(actionHTMLDocumentation, SIGNAL(triggered()), this, SLOT(showHTMLDocumentation())); - labelconcentration = new QLabel(tr("Concentration: ")); + labelxvalue = new QLabel(tr("Range of X-values: ")); - minconcentration = new QDoubleSpinBox(); - minconcentration->setDecimals(6); - minconcentration->setRange(0, 1000000); - minconcentration->setSingleStep(1); + minxvalue = new QDoubleSpinBox(); + minxvalue->setDecimals(6); + minxvalue->setRange(0, 1000000); + minxvalue->setSingleStep(1); labelseparator = new QLabel(tr("-")); - maxconcentration = new QDoubleSpinBox(); - maxconcentration->setDecimals(6); - maxconcentration->setRange(0, 1000000); - maxconcentration->setSingleStep(1); - - setconcentrationinterval = new QPushButton("Set"); - setconcentrationinterval->setMinimumWidth(75); - connect(setconcentrationinterval, SIGNAL(released()), this, SLOT(setConcentrationInterval())); - connect(this, SIGNAL(emitConcentrationInterval(double, double)), chartscene, SLOT(setConcentrationInterval(double, double))); - - resetconcentrationinterval = new QPushButton("Reset"); - resetconcentrationinterval->setMinimumWidth(75); - connect(resetconcentrationinterval, SIGNAL(released()), chartscene, SLOT(resetConcentrationInterval())); - connect(chartscene, SIGNAL(updateConcentrationInterval(double, double)), this, SLOT(updateConcentrationInterval(double, double))); - - hboxconcentration = new QHBoxLayout(); - hboxconcentration->addWidget(labelconcentration); - hboxconcentration->addWidget(minconcentration); - hboxconcentration->addWidget(labelseparator); - hboxconcentration->addWidget(maxconcentration); - hboxconcentration->addSpacing(5); - hboxconcentration->addWidget(setconcentrationinterval); - hboxconcentration->addSpacing(5); - hboxconcentration->addWidget(resetconcentrationinterval); - - widgetconcentration = new QWidget(); - widgetconcentration->setLayout(hboxconcentration); - - toolbarConcentration = addToolBar(tr("Concentration")); - - //actionMouseConcentrationSelection = new QAction(QIcon(":/images/icons/64.png"), tr("Mouse Concentration Selection Tool"), this); - //actionMouseConcentrationSelection->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T)); - //actionMouseConcentrationSelection->setToolTip("Mouse Concentration Selection Tool (Ctrl + T)"); - //actionMouseConcentrationSelection->setCheckable(true); - //actionMouseConcentrationSelection->setChecked(true); - //actionMouseConcentrationSelection->setEnabled(true); - //toolbarConcentration->addAction(actionMouseConcentrationSelection); - //connect(actionMouseConcentrationSelection, SIGNAL(toggled(bool)), chartscene, SLOT(enableMouseConcentrationSelectionTool(bool))); - - toolbarConcentration->addWidget(widgetconcentration); + maxxvalue = new QDoubleSpinBox(); + maxxvalue->setDecimals(6); + maxxvalue->setRange(0, 1000000); + maxxvalue->setSingleStep(1); + + setxvalueinterval = new QPushButton("Set"); + setxvalueinterval->setMinimumWidth(75); + connect(setxvalueinterval, SIGNAL(released()), this, SLOT(setXValueInterval())); + connect(this, SIGNAL(emitXValueInterval(double, double)), chartscene, SLOT(setXValueInterval(double, double))); + + resetxvalueinterval = new QPushButton("Reset"); + resetxvalueinterval->setMinimumWidth(75); + connect(resetxvalueinterval, SIGNAL(released()), chartscene, SLOT(resetXValueInterval())); + connect(chartscene, SIGNAL(updateXValueInterval(double, double)), this, SLOT(updateXValueInterval(double, double))); + + labelgraphtype = new QLabel(tr("Graph Type: ")); + + comboboxgraphtype = new QComboBox(); + comboboxgraphtype->addItem("Calibration Curve"); + comboboxgraphtype->addItem("Collection Time and Concentration"); + connect(comboboxgraphtype, SIGNAL(currentIndexChanged(int)), this, SLOT(graphTypeChanged(int))); + + hboxgraphtype = new QHBoxLayout(); + hboxgraphtype->addWidget(labelgraphtype); + hboxgraphtype->addWidget(comboboxgraphtype); + + widgetgraphtype = new QWidget(); + widgetgraphtype->setLayout(hboxgraphtype); + + hboxxvalue = new QHBoxLayout(); + hboxxvalue->addWidget(labelxvalue); + hboxxvalue->addWidget(minxvalue); + hboxxvalue->addWidget(labelseparator); + hboxxvalue->addWidget(maxxvalue); + hboxxvalue->addSpacing(5); + hboxxvalue->addWidget(setxvalueinterval); + hboxxvalue->addSpacing(5); + hboxxvalue->addWidget(resetxvalueinterval); + + widgetxvalue = new QWidget(); + widgetxvalue->setLayout(hboxxvalue); + + addToolBarBreak(); + + toolbarGraph = addToolBar(tr("Graph")); + + //actionMouseXValueSelection = new QAction(QIcon(":/images/icons/64.png"), tr("Mouse X-value Selection Tool"), this); + //actionMouseXValueSelection->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T)); + //actionMouseXValueSelection->setToolTip("Mouse X-value Selection Tool (Ctrl + T)"); + //actionMouseXValueSelection->setCheckable(true); + //actionMouseXValueSelection->setChecked(true); + //actionMouseXValueSelection->setEnabled(true); + //toolbarRange->addAction(actionMouseXValueSelection); + //connect(actionMouseXValueSelection, SIGNAL(toggled(bool)), chartscene, SLOT(enableMouseXValueSelectionTool(bool))); + + toolbarGraph->addWidget(widgetgraphtype); + toolbarGraph->addWidget(widgetxvalue); database = new QTableView(this); databasemodel = new QStandardItemModel(0, 0, this); @@ -186,21 +203,26 @@ cCalibrationChart::cCalibrationChart(cGlobalPreferences* globalpreferences, QWid setMenuBar(menuBar); - resize(750, defaultwinsizey); + resize(900, defaultwinsizey); //applyGlobalPreferences(globalpreferences); } cCalibrationChart::~cCalibrationChart() { - delete labelconcentration; - delete minconcentration; + delete labelgraphtype; + delete comboboxgraphtype; + delete hboxgraphtype; + delete widgetgraphtype; + + delete labelxvalue; + delete minxvalue; delete labelseparator; - delete maxconcentration; - delete setconcentrationinterval; - delete resetconcentrationinterval; - delete hboxconcentration; - delete widgetconcentration; + delete maxxvalue; + delete setxvalueinterval; + delete resetxvalueinterval; + delete hboxxvalue; + delete widgetxvalue; delete chartscene; @@ -217,7 +239,7 @@ cCalibrationChart::~cCalibrationChart() { delete actionZoomOut; delete actionZoomReset; delete actionHideLabels; - //delete actionMouseConcentrationSelection; + //delete actionMouseXValueSelection; delete actionHTMLDocumentation; delete menuFile; @@ -252,14 +274,14 @@ void cCalibrationChart::setLineParameters(int equationtype, double a, double b, } -void cCalibrationChart::setData(vector xvalues, vector yvalues, vector sd, vector datagroups) { +void cCalibrationChart::setData(vector xvalues, vector yvalues, vector sd, vector datagroups, vector& datatimevalues) { if (chartscene) { - chartscene->setData(xvalues, yvalues, sd, datagroups); + chartscene->setData(xvalues, yvalues, sd, datagroups, datatimevalues); } } -void cCalibrationChart::createTable(double a, double b, vector& calibrationxvalues, vector& calibrationyvalues, vector& calibrationsd, vector& datagroups, vector& dataxvalues, vector& datayvalues, vector& datasd) { +void cCalibrationChart::createTable(double a, double b, vector& calibrationxvalues, vector& calibrationyvalues, vector& calibrationsd, vector& datagroups, vector& dataxvalues, vector& datayvalues, vector& datasd, vector& datatimevalues) { int currentrow = 0; int currentcolumn = 0; size_t size; @@ -291,6 +313,11 @@ void cCalibrationChart::createTable(double a, double b, vector& calibrat database->setItemDelegateForColumn(currentcolumn, new QItemDelegate()); currentcolumn++; + databasemodel->setHorizontalHeaderItem(currentcolumn, new QStandardItem()); + databasemodel->horizontalHeaderItem(currentcolumn)->setText("Collection Time"); + database->setItemDelegateForColumn(currentcolumn, new QItemDelegate()); + currentcolumn++; + size = calibrationxvalues.size(); for (size_t i = 0; i < size; i++) { currentrow = databasemodel->rowCount(); @@ -333,6 +360,9 @@ void cCalibrationChart::createTable(double a, double b, vector& calibrat databasemodel->setItem(currentrow, currentcolumn, new QStandardItem()); databasemodel->item(currentrow, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(value)), Qt::DisplayRole); currentcolumn++; + + databasemodel->setItem(currentrow, currentcolumn, new QStandardItem()); + currentcolumn++; } size = dataxvalues.size(); @@ -342,8 +372,7 @@ void cCalibrationChart::createTable(double a, double b, vector& calibrat currentcolumn = 0; - s = "Group "; - s += to_string(datagroups[i]); + s = datagroups[i]; databasemodel->setItem(currentrow, currentcolumn, new QStandardItem()); databasemodel->item(currentrow, currentcolumn)->setText(s.c_str()); currentcolumn++; @@ -372,6 +401,10 @@ void cCalibrationChart::createTable(double a, double b, vector& calibrat databasemodel->setItem(currentrow, currentcolumn, new QStandardItem()); databasemodel->item(currentrow, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(value)), Qt::DisplayRole); currentcolumn++; + + databasemodel->setItem(currentrow, currentcolumn, new QStandardItem()); + databasemodel->item(currentrow, currentcolumn)->setData(QVariant::fromValue(datatimevalues[i]), Qt::DisplayRole); + currentcolumn++; } for (int i = 0; i < databasemodel->columnCount(); i++) { @@ -392,8 +425,8 @@ void cCalibrationChart::deleteTable() { void cCalibrationChart::keyPressEvent(QKeyEvent *event) { if ((event->key() == Qt::Key_Enter) || (event->key() == Qt::Key_Return)) { - if (minconcentration->hasFocus() || maxconcentration->hasFocus() || setconcentrationinterval->hasFocus()) { - setConcentrationInterval(); + if (minxvalue->hasFocus() || maxxvalue->hasFocus() || setxvalueinterval->hasFocus()) { + setXValueInterval(); } } @@ -499,14 +532,38 @@ void cCalibrationChart::exportToCsv() { } -void cCalibrationChart::updateConcentrationInterval(double minconcentration, double maxconcentration) { - this->minconcentration->setValue(minconcentration); - this->maxconcentration->setValue(maxconcentration); +void cCalibrationChart::updateXValueInterval(double minxvalue, double maxxvalue) { + this->minxvalue->setValue(minxvalue); + this->maxxvalue->setValue(maxxvalue); } -void cCalibrationChart::setConcentrationInterval() { - emit emitConcentrationInterval(minconcentration->value(), maxconcentration->value()); +void cCalibrationChart::setXValueInterval() { + emit emitXValueInterval(minxvalue->value(), maxxvalue->value()); +} + + +void cCalibrationChart::graphTypeChanged(int type) { + double value; + + if (type == 0) { + value = chartscene->getMaximumConcentration(); + if (value == 0) { + value = 1000; + } + } + else { + value = (double)chartscene->getMaximumCollectionTime(); + if (value == 0) { + value = 240; + } + } + + updateXValueInterval(0, value); + + setXValueInterval(); + + chartscene->setGraphType(type); } diff --git a/CycloBranch/gui/cCalibrationChart.h b/CycloBranch/gui/cCalibrationChart.h index fa91abb..37f8c7c 100644 --- a/CycloBranch/gui/cCalibrationChart.h +++ b/CycloBranch/gui/cCalibrationChart.h @@ -82,7 +82,7 @@ class cCalibrationChart : public QMainWindow \param b b \param xvalues x coordinates of points \param yvalues y coordinates of points - \param sd standard deviation of y-values + \param sd standard deviation of y values */ void setLineParameters(int equationtype, double a, double b, vector xvalues, vector yvalues, vector sd); @@ -91,10 +91,11 @@ class cCalibrationChart : public QMainWindow \brief Set data points. \param xvalues x coordinates of points \param yvalues y coordinates of points - \param sd standard deviation of y-values - \param datagroups vector of group ids + \param sd standard deviation of y values + \param datagroups vector of group names + \param datatimevalues data collection times corresponding the groups */ - void setData(vector xvalues, vector yvalues, vector sd, vector datagroups); + void setData(vector xvalues, vector yvalues, vector sd, vector datagroups, vector& datatimevalues); /** @@ -103,13 +104,14 @@ class cCalibrationChart : public QMainWindow \param b b \param calibrationxvalues x coordinates of calibration points \param calibrationyvalues y coordinates of calibration points - \param calibrationsd standard deviation of y-values of calibration points - \param datagroups ids of groups of data points + \param calibrationsd standard deviation of y values of calibration points + \param datagroups names of groups of data points \param dataxvalues x coordinates of data points \param datayvalues y coordinates of data points - \param datasd standard deviation of y-values of data points + \param datasd standard deviation of y values of data points + \param datatimevalues data collection times corresponding the groups */ - void createTable(double a, double b, vector& calibrationxvalues, vector& calibrationyvalues, vector& calibrationsd, vector& datagroups, vector& dataxvalues, vector& datayvalues, vector& datasd); + void createTable(double a, double b, vector& calibrationxvalues, vector& calibrationyvalues, vector& calibrationsd, vector& datagroups, vector& dataxvalues, vector& datayvalues, vector& datasd, vector& datatimevalues); /** @@ -141,7 +143,7 @@ class cCalibrationChart : public QMainWindow QToolBar* toolbarFile; QToolBar* toolbarView; QToolBar* toolbarHelp; - QToolBar* toolbarConcentration; + QToolBar* toolbarGraph; QAction* actionExportCSV; QAction* actionExportSpectrum; @@ -150,17 +152,22 @@ class cCalibrationChart : public QMainWindow QAction* actionZoomOut; QAction* actionZoomReset; QAction* actionHideLabels; - //QAction* actionMouseConcentrationSelection; + //QAction* actionMouseXValueSelection; QAction* actionHTMLDocumentation; - QWidget* widgetconcentration; - QHBoxLayout* hboxconcentration; - QLabel* labelconcentration; - QDoubleSpinBox* minconcentration; + QWidget* widgetgraphtype; + QHBoxLayout* hboxgraphtype; + QLabel* labelgraphtype; + QComboBox* comboboxgraphtype; + + QWidget* widgetxvalue; + QHBoxLayout* hboxxvalue; + QLabel* labelxvalue; + QDoubleSpinBox* minxvalue; QLabel* labelseparator; - QDoubleSpinBox* maxconcentration; - QPushButton* setconcentrationinterval; - QPushButton* resetconcentrationinterval; + QDoubleSpinBox* maxxvalue; + QPushButton* setxvalueinterval; + QPushButton* resetxvalueinterval; cCalibrationChartScene* chartscene; @@ -176,11 +183,11 @@ class cCalibrationChart : public QMainWindow /** - \brief The signal is emitted when the range of concentration is changed. - \param minconcentration a minimum threshold of concentration - \param maxconcentration a maximum threshold of concentration + \brief The signal is emitted when the range of x value is changed. + \param minxvalue a minimum threshold of x value + \param maxxvalue a maximum threshold of x value */ - void emitConcentrationInterval(double minconcentration, double maxconcentration); + void emitXValueInterval(double minxvalue, double maxxvalue); private slots: @@ -189,10 +196,13 @@ private slots: void exportToCsv(); - void updateConcentrationInterval(double minconcentration, double maxconcentration); + void updateXValueInterval(double minxvalue, double maxxvalue); + + + void setXValueInterval(); - void setConcentrationInterval(); + void graphTypeChanged(int type); void exportScene(); diff --git a/CycloBranch/gui/cCalibrationChartScene.cpp b/CycloBranch/gui/cCalibrationChartScene.cpp index 7d4be0c..368d111 100644 --- a/CycloBranch/gui/cCalibrationChartScene.cpp +++ b/CycloBranch/gui/cCalibrationChartScene.cpp @@ -98,14 +98,17 @@ cCalibrationChartScene::cCalibrationChartScene(QWidget* parent) { calledbyresizeevent = false; oldwidth.clear(); oldheight.clear(); + + graphtype = 0; + currentscale = 1; factor = 0.2; pressedx = -1; pressedy = -1; currentx = 0; currenty = 0; - minconcentration = 0; - maxconcentration = 0; + minxvalue = 0; + maxxvalue = 0; topmargin = 0; bottommargin = 0; @@ -113,7 +116,7 @@ cCalibrationChartScene::cCalibrationChartScene(QWidget* parent) { rightmargin = 0; firstshow = true; - enablemouseconcentrationselection = true; + enablemousexvalueselection = true; equationtype = 0; @@ -131,6 +134,8 @@ cCalibrationChartScene::cCalibrationChartScene(QWidget* parent) { datasd.clear(); datagroups.clear(); + datatimevalues.clear(); + hidelabels = false; scene = new QGraphicsScene(this); @@ -153,9 +158,24 @@ cCalibrationChartScene::~cCalibrationChartScene() { void cCalibrationChartScene::initialize() { - minconcentration = 0; - maxconcentration = 1000; - emit updateConcentrationInterval(minconcentration, maxconcentration); + if (graphtype == 0) { + minxvalue = 0; + + maxxvalue = getMaximumConcentration(); + if (maxxvalue == 0) { + maxxvalue = 1000; + } + } + else { + minxvalue = 0; + + maxxvalue = (double)getMaximumCollectionTime(); + if (maxxvalue == 0) { + maxxvalue = 240; + } + } + + emit updateXValueInterval(minxvalue, maxxvalue); setScene(scene); @@ -174,6 +194,8 @@ void cCalibrationChartScene::initialize() { datasd.clear(); datagroups.clear(); + datatimevalues.clear(); + redrawScene(); } @@ -270,39 +292,91 @@ void cCalibrationChartScene::setLineParameters(int equationtype, double a, doubl } -void cCalibrationChartScene::setData(vector datax, vector datay, vector datasd, vector datagroups) { +void cCalibrationChartScene::setData(vector datax, vector datay, vector datasd, vector datagroups, vector datatimevalues) { this->datax = datax; this->datay = datay; this->datasd = datasd; this->datagroups = datagroups; + this->datatimevalues = datatimevalues; + + if (graphtype == 0) { + minxvalue = 0; + + maxxvalue = getMaximumConcentration(); + if (maxxvalue == 0) { + maxxvalue = 1000; + } + } + else { + minxvalue = 0; + + maxxvalue = (double)getMaximumCollectionTime(); + if (maxxvalue == 0) { + maxxvalue = 240; + } + } + redrawScene(); } +void cCalibrationChartScene::setGraphType(int type) { + graphtype = type; + redrawScene(); +} + + +double cCalibrationChartScene::getMaximumConcentration() { + double value = 0; + for (auto it : xvalues) { + if (it > value) { + value = it; + } + } + for (auto it : datax) { + if (it > value) { + value = it; + } + } + return value; +} + + +int cCalibrationChartScene::getMaximumCollectionTime() { + int value = 0; + for (auto it : datatimevalues) { + if (it > value) { + value = it; + } + } + return value; +} + + void cCalibrationChartScene::wheelEvent(QWheelEvent *event) { double part, newmin, newmax; if (event->delta() > 0) { - part = fabs(maxconcentration - minconcentration) / 10.0; - newmin = minconcentration + part; - newmax = maxconcentration - part; + part = fabs(maxxvalue - minxvalue) / 10.0; + newmin = minxvalue + part; + newmax = maxxvalue - part; } else { - part = fabs(maxconcentration - minconcentration) / 8.0; - newmin = max(minconcentration - part, 0.0); - newmax = min(maxconcentration + part, 1000000.0); + part = fabs(maxxvalue - minxvalue) / 8.0; + newmin = max(minxvalue - part, 0.0); + newmax = min(maxxvalue + part, 1000000.0); } if (newmin < newmax) { - minconcentration = newmin; - maxconcentration = newmax; - emit updateConcentrationInterval(minconcentration, maxconcentration); + minxvalue = newmin; + maxxvalue = newmax; + emit updateXValueInterval(minxvalue, maxxvalue); redrawScene(); viewport()->update(); } - + event->accept(); } @@ -316,9 +390,9 @@ void cCalibrationChartScene::mouseMoveEvent(QMouseEvent *event) { curpos.setX(p.x() + 15); curpos.setY(p.y() - 2); - double concentration = getConcentrationFromXPosition((int)p.x(), origwidth); - double intensity = getIntensityFromYPosition((int)p.y(), origheight); - QString curtext = "x: " + QString::number(concentration) + ", y: " + QString::number(intensity); + double xval = getValueFromXPosition((int)p.x(), origwidth); + double yval = getValueFromYPosition((int)p.y(), origheight); + QString curtext = "x: " + QString::number(xval) + ", y: " + QString::number(yval); cursorsimpletextitem->setPos(curpos); cursorsimpletextitem->setText(curtext); @@ -329,13 +403,13 @@ void cCalibrationChartScene::mouseMoveEvent(QMouseEvent *event) { currentx = (int)p.x(); currenty = (int)p.y(); - if (enablemouseconcentrationselection) { + if (enablemousexvalueselection) { updateZoomGroup(); } else { - calculateMinMaxConcentration(); + calculateMinMaxXValue(); - emit updateConcentrationInterval(minconcentration, maxconcentration); + emit updateXValueInterval(minxvalue, maxxvalue); pressedx = currentx; pressedy = currenty; @@ -367,9 +441,9 @@ void cCalibrationChartScene::mouseReleaseEvent(QMouseEvent *event) { } if ((event->button() == Qt::LeftButton) && (pressedx != -1) && (pressedy != -1)) { - calculateMinMaxConcentration(); + calculateMinMaxXValue(); - emit updateConcentrationInterval(minconcentration, maxconcentration); + emit updateXValueInterval(minxvalue, maxxvalue); pressedx = -1; pressedy = -1; @@ -383,9 +457,9 @@ void cCalibrationChartScene::mouseReleaseEvent(QMouseEvent *event) { curpos.setX(p.x() + 15); curpos.setY(p.y() - 2); - double concentration = getConcentrationFromXPosition((int)p.x(), origwidth); - double intensity = getIntensityFromYPosition((int)p.y(), origheight); - QString curtext = "x: " + QString::number(concentration) + ", y: " + QString::number(intensity); + double xval = getValueFromXPosition((int)p.x(), origwidth); + double yval = getValueFromYPosition((int)p.y(), origheight); + QString curtext = "x: " + QString::number(xval) + ", y: " + QString::number(yval); cursorsimpletextitem->setPos(curpos); cursorsimpletextitem->setText(curtext); @@ -414,7 +488,7 @@ void cCalibrationChartScene::mousePressEvent(QMouseEvent *event) { currentx = pressedx; currenty = pressedy; - if (enablemouseconcentrationselection) { + if (enablemousexvalueselection) { updateZoomGroup(); } } @@ -426,12 +500,12 @@ void cCalibrationChartScene::mousePressEvent(QMouseEvent *event) { redrawScene(); } - //if (enablemouseconcentrationselection) { + //if (enablemousexvalueselection) { if (event->button() == Qt::MiddleButton) { pressedx = -1; pressedy = -1; - resetConcentrationInterval(); + resetXValueInterval(); redrawScene(); } @@ -467,30 +541,30 @@ void cCalibrationChartScene::resizeEvent(QResizeEvent *event) { } -double cCalibrationChartScene::getConcentrationFromXPosition(int x, int w) { - double concentration = (double)(x - leftmargin) / (double)(w - leftmargin - rightmargin) * (maxconcentration - minconcentration) + minconcentration; - return max(0.0, concentration); +double cCalibrationChartScene::getValueFromXPosition(int x, int w) { + double value = (double)(x - leftmargin) / (double)(w - leftmargin - rightmargin) * (maxxvalue - minxvalue) + minxvalue; + return max(0.0, value); } -int cCalibrationChartScene::getXPositionFromConcentration(double concentration, int w) { - double val = concentration - minconcentration; - val /= maxconcentration - minconcentration; +int cCalibrationChartScene::getXPositionFromValue(double value, int w) { + double val = value - minxvalue; + val /= maxxvalue - minxvalue; val *= double(w - leftmargin - rightmargin); return (int)val + leftmargin; } -double cCalibrationChartScene::getIntensityFromYPosition(int y, int h) { - double maximumintensity = getMaximumIntensity(); +double cCalibrationChartScene::getValueFromYPosition(int y, int h) { + double maximumintensity = getMaximumYValue(); double intensity = (double)(y - topmargin) / (double)(h - topmargin - bottommargin) * maximumintensity; intensity = maximumintensity - intensity; return max(0.0, intensity); } -int cCalibrationChartScene::getYPositionFromIntensity(double intensity, int h) { - double maximumintensity = getMaximumIntensity(); +int cCalibrationChartScene::getYPositionFromValue(double intensity, int h) { + double maximumintensity = getMaximumYValue(); double val = maximumintensity - intensity; val /= maximumintensity; val *= double(h - topmargin - bottommargin); @@ -514,7 +588,7 @@ void cCalibrationChartScene::redrawScene() { QList usedtextitems; - double maxintensity = getMaximumIntensity(); + double maxyvalue = getMaximumYValue(); scene->removeItem(zoomgroup); scene->removeItem(cursorsimpletextitem); @@ -539,24 +613,24 @@ void cCalibrationChartScene::redrawScene() { for (int i = 0; i < rulergranularity; i++) { line = scene->addLine(leftmargin + xstep * i, h - bottommargin, leftmargin + xstep * i, h - bottommargin + 10, QPen(Qt::black, 2, Qt::SolidLine)); line->setZValue(1); - } + } line = scene->addLine(w - rightmargin, h - bottommargin, w - rightmargin, h - bottommargin + 10, QPen(Qt::black, 2, Qt::SolidLine)); line->setZValue(1); - simpletext = scene->addSimpleText(QString::number(minconcentration), myFont); + simpletext = scene->addSimpleText(QString::number(minxvalue), myFont); simpletext->setPos(QPointF(leftmargin - simpletext->boundingRect().width() / 2, h - bottommargin + 12)); simpletext->setZValue(1); - if (maxconcentration - minconcentration > 0.01) { + if (maxxvalue - minxvalue > 0.01) { xstep = (w - leftmargin - rightmargin) / rulergranularity; for (int i = 1; i < rulergranularity; i++) { - simpletext = scene->addSimpleText(QString::number(minconcentration + (maxconcentration - minconcentration) / (double)rulergranularity * (double)i), myFont); + simpletext = scene->addSimpleText(QString::number(minxvalue + (maxxvalue - minxvalue) / (double)rulergranularity * (double)i), myFont); simpletext->setPos(QPointF(leftmargin + xstep * i - simpletext->boundingRect().width() / 2, h - bottommargin + 12)); simpletext->setZValue(1); } } - simpletext = scene->addSimpleText(QString::number(maxconcentration), myFont); + simpletext = scene->addSimpleText(QString::number(maxxvalue), myFont); simpletext->setPos(QPointF(w - rightmargin - simpletext->boundingRect().width() / 2, h - bottommargin + 12)); simpletext->setZValue(1); @@ -564,7 +638,7 @@ void cCalibrationChartScene::redrawScene() { // y axis line = scene->addLine(leftmargin, h - bottommargin, leftmargin, h - bottommargin - std::max(h - topmargin - bottommargin, 0), QPen(Qt::black, 2, Qt::SolidLine)); line->setZValue(1); - + // y axis ruler ystep = (h - topmargin - bottommargin) / rulergranularity; for (int i = 0; i < rulergranularity; i++) { @@ -579,191 +653,266 @@ void cCalibrationChartScene::redrawScene() { simpletext->setZValue(1); ystep = (h - topmargin - bottommargin) / rulergranularity; - if (maxintensity > 0) { + if (maxyvalue > 0) { for (int i = 1; i < rulergranularity; i++) { - simpletext = scene->addSimpleText(QString::number(maxintensity / (double)rulergranularity * (double)i), myFont); + simpletext = scene->addSimpleText(QString::number(maxyvalue / (double)rulergranularity * (double)i), myFont); simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), h - bottommargin - simpletext->boundingRect().height() / 2 - ystep * i)); simpletext->setZValue(1); } } - if (maxintensity > 0) { - simpletext = scene->addSimpleText(QString::number(maxintensity), myFont); + if (maxyvalue > 0) { + simpletext = scene->addSimpleText(QString::number(maxyvalue), myFont); simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), h - bottommargin - std::max(h - topmargin - bottommargin, 0) - simpletext->boundingRect().height() / 2)); simpletext->setZValue(1); } - QPainterPath rpath; - const int step = 1; + string graphlabel; + + // calibration curve + if (graphtype == 0) { + + QPainterPath rpath; + const int step = 1; - int xmin = getXPositionFromConcentration(minconcentration, w); - int xmax = getXPositionFromConcentration(maxconcentration, w); - int xval, yval, tmpyval1, tmpyval2; + int xmin = getXPositionFromValue(minxvalue, w); + int xmax = getXPositionFromValue(maxxvalue, w); + int xval, yval, tmpyval1, tmpyval2; - for (int i = xmin; i < xmax; i += step) { - yval = getYPositionFromIntensity(a * getConcentrationFromXPosition(i, w) + b, h); + for (int i = xmin; i < xmax; i += step) { + yval = getYPositionFromValue(a * getValueFromXPosition(i, w) + b, h); - if (rpath.elementCount() == 0) { - if (yval <= h - bottommargin) { - rpath.moveTo(i, yval); + if (rpath.elementCount() == 0) { + if (yval <= h - bottommargin) { + rpath.moveTo(i, yval); + } } - } - else { - if (yval >= topmargin) { - rpath.lineTo(i, yval); + else { + if (yval >= topmargin) { + rpath.lineTo(i, yval); + } } } - } - scene->addPath(rpath, QPen(Qt::red, 2, Qt::SolidLine)); + scene->addPath(rpath, QPen(Qt::red, 2, Qt::SolidLine)); - for (int i = 0; i < (int)xvalues.size(); i++) { - xval = getXPositionFromConcentration(xvalues[i], w); - yval = getYPositionFromIntensity(yvalues[i], h); + for (int i = 0; i < (int)xvalues.size(); i++) { + xval = getXPositionFromValue(xvalues[i], w); + yval = getYPositionFromValue(yvalues[i], h); - if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { - tmpyval1 = getYPositionFromIntensity(min(getMaximumIntensity(), yvalues[i] + sd[i]), h); - tmpyval2 = max(topmargin, tmpyval1); - scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { + tmpyval1 = getYPositionFromValue(min(getMaximumYValue(), yvalues[i] + sd[i]), h); + tmpyval2 = max(topmargin, tmpyval1); + scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); - if (tmpyval1 > topmargin) { - scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); - } + if (tmpyval1 > topmargin) { + scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + } - tmpyval1 = getYPositionFromIntensity(min(getMaximumIntensity(), yvalues[i] - sd[i]), h); - tmpyval2 = min(h - bottommargin, tmpyval1); - scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + tmpyval1 = getYPositionFromValue(min(getMaximumYValue(), yvalues[i] - sd[i]), h); + tmpyval2 = min(h - bottommargin, tmpyval1); + scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); - if (tmpyval1 < h - bottommargin) { - scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); - } + if (tmpyval1 < h - bottommargin) { + scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + } - scene->addEllipse(QRectF(xval - 4, yval - 4, 8, 8), QPen(Qt::blue, 1, Qt::SolidLine), QBrush(Qt::blue)); + scene->addEllipse(QRectF(xval - 4, yval - 4, 8, 8), QPen(Qt::blue, 1, Qt::SolidLine), QBrush(Qt::blue)); + } } - } - for (int i = 0; i < (int)datax.size(); i++) { - xval = getXPositionFromConcentration(datax[i], w); - yval = getYPositionFromIntensity(datay[i], h); + for (int i = 0; i < (int)datax.size(); i++) { + xval = getXPositionFromValue(datax[i], w); + yval = getYPositionFromValue(datay[i], h); - if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { - tmpyval1 = getYPositionFromIntensity(min(getMaximumIntensity(), datay[i] + datasd[i]), h); - tmpyval2 = max(topmargin, tmpyval1); - scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { + tmpyval1 = getYPositionFromValue(min(getMaximumYValue(), datay[i] + datasd[i]), h); + tmpyval2 = max(topmargin, tmpyval1); + scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); - if (tmpyval1 > topmargin) { - scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); - } + if (tmpyval1 > topmargin) { + scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + } - tmpyval1 = getYPositionFromIntensity(min(getMaximumIntensity(), datay[i] - datasd[i]), h); - tmpyval2 = min(h - bottommargin, tmpyval1); - scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + tmpyval1 = getYPositionFromValue(min(getMaximumYValue(), datay[i] - datasd[i]), h); + tmpyval2 = min(h - bottommargin, tmpyval1); + scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); - if (tmpyval1 < h - bottommargin) { - scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); - } + if (tmpyval1 < h - bottommargin) { + scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + } - scene->addEllipse(QRectF(xval - 4, yval - 4, 8, 8), QPen(Qt::green, 1, Qt::SolidLine), QBrush(Qt::green)); + scene->addEllipse(QRectF(xval - 4, yval - 4, 8, 8), QPen(Qt::green, 1, Qt::SolidLine), QBrush(Qt::green)); + } } - } - string graphlabel; - if (!hidelabels) { - graphlabel = "y = " + to_string(a) + "x"; - if (b != 0) { - if (b > 0) { - graphlabel += " + " + to_string(b); - } - else { - graphlabel += " - " + to_string(fabs(b)); + if (!hidelabels) { + graphlabel = "y = " + to_string(a) + "x"; + if (b != 0) { + if (b > 0) { + graphlabel += " + " + to_string(b); + } + else { + graphlabel += " - " + to_string(fabs(b)); + } } } - } - htmltext = scene->addText("", myFont); - htmltext->setHtml(graphlabel.c_str()); - htmltext->setPos(QPointF(leftmargin + 10, topmargin)); - htmltext->setZValue(1); + htmltext = scene->addText("", myFont); + htmltext->setHtml(graphlabel.c_str()); + htmltext->setPos(QPointF(leftmargin + 10, topmargin)); + htmltext->setZValue(1); - int linespace = 16; + int linespace = 16; - if (!xvalues.empty() && (equationtype < 2)) { - if (!hidelabels) { - graphlabel = "R2 = " + to_string(calculateR2Value(a, b, xvalues, yvalues)); + if (!xvalues.empty() && (equationtype < 2)) { + if (!hidelabels) { + graphlabel = "R2 = " + to_string(calculateR2Value(a, b, xvalues, yvalues)); - htmltext = scene->addText("", myFont); - htmltext->setHtml(graphlabel.c_str()); - htmltext->setPos(QPointF(leftmargin + 10, topmargin + linespace)); - htmltext->setZValue(1); + htmltext = scene->addText("", myFont); + htmltext->setHtml(graphlabel.c_str()); + htmltext->setPos(QPointF(leftmargin + 10, topmargin + linespace)); + htmltext->setZValue(1); - graphlabel = "LOD = " + to_string(calculateLOD(a, xvalues, yvalues)); + graphlabel = "LOD = " + to_string(calculateLOD(a, xvalues, yvalues)); - htmltext = scene->addText("", myFont); - htmltext->setHtml(graphlabel.c_str()); - htmltext->setPos(QPointF(leftmargin + 10, topmargin + 3 * linespace)); - htmltext->setZValue(1); + htmltext = scene->addText("", myFont); + htmltext->setHtml(graphlabel.c_str()); + htmltext->setPos(QPointF(leftmargin + 10, topmargin + 3 * linespace)); + htmltext->setZValue(1); - graphlabel = "LOQ = " + to_string(calculateLOQ(a, xvalues, yvalues)); + graphlabel = "LOQ = " + to_string(calculateLOQ(a, xvalues, yvalues)); - htmltext = scene->addText("", myFont); - htmltext->setHtml(graphlabel.c_str()); - htmltext->setPos(QPointF(leftmargin + 10, topmargin + 4 * linespace)); - htmltext->setZValue(1); + htmltext = scene->addText("", myFont); + htmltext->setHtml(graphlabel.c_str()); + htmltext->setPos(QPointF(leftmargin + 10, topmargin + 4 * linespace)); + htmltext->setZValue(1); + } } - } - if (!hidelabels) { + if (!hidelabels) { + + usedtextitems.clear(); - usedtextitems.clear(); + for (int i = (int)xvalues.size() - 1; i >= 0; i--) { + xval = getXPositionFromValue(xvalues[i], w); + yval = getYPositionFromValue(yvalues[i], h); - for (int i = (int)xvalues.size() - 1; i >= 0; i--) { - xval = getXPositionFromConcentration(xvalues[i], w); - yval = getYPositionFromIntensity(yvalues[i], h); + if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { + graphlabel = "Calib. " + to_string(xvalues[i]); + simpletext = scene->addSimpleText(graphlabel.c_str(), myFont); + simpletext->setPos(QPointF(xval + 10, yval - 5)); + simpletext->setZValue(1); - if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { - graphlabel = "Calib. " + to_string(xvalues[i]); - simpletext = scene->addSimpleText(graphlabel.c_str(), myFont); - simpletext->setPos(QPointF(xval + 10, yval - 5)); - simpletext->setZValue(1); - - for (auto& it : usedtextitems) { - if (simpletext->collidesWithItem(it, Qt::IntersectsItemBoundingRect)) { - scene->removeItem(simpletext); - simpletext = 0; - break; + for (auto& it : usedtextitems) { + if (simpletext->collidesWithItem(it, Qt::IntersectsItemBoundingRect)) { + scene->removeItem(simpletext); + simpletext = 0; + break; + } + } + + if (simpletext) { + usedtextitems.append(simpletext); } } + } + + for (int i = (int)datax.size() - 1; i >= 0; i--) { + xval = getXPositionFromValue(datax[i], w); + yval = getYPositionFromValue(datay[i], h); + + if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { + graphlabel = datagroups[i]; + simpletext = scene->addSimpleText(graphlabel.c_str(), myFont); + simpletext->setPos(QPointF(xval + 10, yval - 5)); + simpletext->setZValue(1); + + for (auto& it : usedtextitems) { + if (simpletext->collidesWithItem(it, Qt::IntersectsItemBoundingRect)) { + scene->removeItem(simpletext); + simpletext = 0; + break; + } + } - if (simpletext) { - usedtextitems.append(simpletext); + if (simpletext) { + usedtextitems.append(simpletext); + } } } + } - for (int i = (int)datax.size() - 1; i >= 0; i--) { - xval = getXPositionFromConcentration(datax[i], w); - yval = getYPositionFromIntensity(datay[i], h); + } + // collection time and concentration + else { + + int xmin = getXPositionFromValue(minxvalue, w); + int xmax = getXPositionFromValue(maxxvalue, w); + int xval, yval, tmpyval1, tmpyval2; + double xsd; + + for (int i = 0; i < (int)datax.size(); i++) { + xval = getXPositionFromValue(datatimevalues[i], w); + yval = getYPositionFromValue(datax[i], h); if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { - graphlabel = "Group " + to_string(datagroups[i]); - simpletext = scene->addSimpleText(graphlabel.c_str(), myFont); - simpletext->setPos(QPointF(xval + 10, yval - 5)); - simpletext->setZValue(1); - - for (auto& it : usedtextitems) { - if (simpletext->collidesWithItem(it, Qt::IntersectsItemBoundingRect)) { - scene->removeItem(simpletext); - simpletext = 0; - break; - } + xsd = 0; + if (a != 0) { + xsd = (datasd[i] - b) / a; } - if (simpletext) { - usedtextitems.append(simpletext); + tmpyval1 = getYPositionFromValue(min(getMaximumYValue(), datax[i] + xsd), h); + tmpyval2 = max(topmargin, tmpyval1); + scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + + if (tmpyval1 > topmargin) { + scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); } + + tmpyval1 = getYPositionFromValue(min(getMaximumYValue(), datax[i] - xsd), h); + tmpyval2 = min(h - bottommargin, tmpyval1); + scene->addLine(xval, yval, xval, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + + if (tmpyval1 < h - bottommargin) { + scene->addLine(xval - 2, tmpyval2, xval + 2, tmpyval2, QPen(Qt::gray, 2, Qt::SolidLine)); + } + + scene->addEllipse(QRectF(xval - 4, yval - 4, 8, 8), QPen(Qt::green, 1, Qt::SolidLine), QBrush(Qt::green)); } } + if (!hidelabels) { + + usedtextitems.clear(); + + for (int i = (int)datax.size() - 1; i >= 0; i--) { + xval = getXPositionFromValue(datatimevalues[i], w); + yval = getYPositionFromValue(datax[i], h); + + if ((xval >= xmin) && (xval <= xmax) && (yval >= topmargin) && (yval <= h - bottommargin)) { + graphlabel = datagroups[i]; + simpletext = scene->addSimpleText(graphlabel.c_str(), myFont); + simpletext->setPos(QPointF(xval + 10, yval - 5)); + simpletext->setZValue(1); + + for (auto& it : usedtextitems) { + if (simpletext->collidesWithItem(it, Qt::IntersectsItemBoundingRect)) { + scene->removeItem(simpletext); + simpletext = 0; + break; + } + } + + if (simpletext) { + usedtextitems.append(simpletext); + } + } + } + + } + } scene->removeItem(zoomgroup); @@ -840,11 +989,11 @@ void cCalibrationChartScene::updateZoomGroup() { zoomrect->setRect(QRectF(QPointF(rx1, ry1), QPointF(rx2, ry2))); QString qstr = "x: "; - qstr += QString::number(getConcentrationFromXPosition((pressedx < currentx)?pressedx:currentx, origwidth)); + qstr += QString::number(getValueFromXPosition((pressedx < currentx)?pressedx:currentx, origwidth)); qstr += "-"; - qstr += QString::number(getConcentrationFromXPosition((pressedx < currentx)?currentx:pressedx, origwidth)); + qstr += QString::number(getValueFromXPosition((pressedx < currentx)?currentx:pressedx, origwidth)); qstr += "\ndiff: "; - qstr += QString::number(getConcentrationFromXPosition((pressedx < currentx)?currentx:pressedx, origwidth) - getConcentrationFromXPosition((pressedx < currentx)?pressedx:currentx, origwidth)); + qstr += QString::number(getValueFromXPosition((pressedx < currentx)?currentx:pressedx, origwidth) - getValueFromXPosition((pressedx < currentx)?pressedx:currentx, origwidth)); zoomsimpletextitem->setFont(myFont); zoomsimpletextitem->setText(qstr); @@ -854,7 +1003,7 @@ void cCalibrationChartScene::updateZoomGroup() { } -void cCalibrationChartScene::calculateMinMaxConcentration() { +void cCalibrationChartScene::calculateMinMaxXValue() { if (pressedx < leftmargin) { pressedx = leftmargin; } @@ -871,28 +1020,48 @@ void cCalibrationChartScene::calculateMinMaxConcentration() { currentx = origwidth - rightmargin; } - double tmpminconcentration = getConcentrationFromXPosition((pressedx < currentx) ? pressedx : currentx, origwidth); - double tmpmaxconcentration = getConcentrationFromXPosition((pressedx < currentx) ? currentx : pressedx, origwidth); + double tmpminvalue = getValueFromXPosition((pressedx < currentx) ? pressedx : currentx, origwidth); + double tmpmaxvalue = getValueFromXPosition((pressedx < currentx) ? currentx : pressedx, origwidth); - if (enablemouseconcentrationselection) { - minconcentration = tmpminconcentration; - maxconcentration = tmpmaxconcentration; + if (enablemousexvalueselection) { + minxvalue = tmpminvalue; + maxxvalue = tmpmaxvalue; } else { if (pressedx > currentx) { - minconcentration = min(minconcentration + tmpmaxconcentration - tmpminconcentration, 1000000.0); - maxconcentration = min(maxconcentration + tmpmaxconcentration - tmpminconcentration, 1000000.0); + minxvalue = min(minxvalue + tmpmaxvalue - tmpminvalue, 1000000.0); + maxxvalue = min(maxxvalue + tmpmaxvalue - tmpminvalue, 1000000.0); } else { - minconcentration = max(0.0, minconcentration - tmpmaxconcentration + tmpminconcentration); - maxconcentration = max(0.0, maxconcentration - tmpmaxconcentration + tmpminconcentration); + minxvalue = max(0.0, minxvalue - tmpmaxvalue + tmpminvalue); + maxxvalue = max(0.0, maxxvalue - tmpmaxvalue + tmpminvalue); } } } -double cCalibrationChartScene::getMaximumIntensity() { - return a * maxconcentration + b; +double cCalibrationChartScene::getMaximumYValue() { + double maxyvalue; + double xsd; + + if (graphtype == 0) { + return a * maxxvalue + b; + } + else { + maxyvalue = 0; + for (size_t i = 0; i < datax.size(); i++) { + xsd = 0; + if (a != 0) { + xsd = (datasd[i] - b) / a; + } + + if ((datax[i] + xsd > maxyvalue) && (datatimevalues[i] >= minxvalue) && (datatimevalues[i] <= maxxvalue)) { + maxyvalue = datax[i] + xsd + 5; + } + } + } + + return maxyvalue; } @@ -923,33 +1092,45 @@ void cCalibrationChartScene::normalSize() { } -void cCalibrationChartScene::setConcentrationInterval(double minconcentration, double maxconcentration) { - if (maxconcentration < minconcentration) { - double tmp = maxconcentration; - maxconcentration = minconcentration; - minconcentration = tmp; +void cCalibrationChartScene::setXValueInterval(double minxvalue, double maxxvalue) { + if (maxxvalue < minxvalue) { + double tmp = maxxvalue; + maxxvalue = minxvalue; + minxvalue = tmp; } - this->minconcentration = std::max(0.0, minconcentration); - this->maxconcentration = std::min(maxconcentration, 1000000.0); - emit updateConcentrationInterval(this->minconcentration, this->maxconcentration); + this->minxvalue = std::max(0.0, minxvalue); + this->maxxvalue = std::min(maxxvalue, 1000000.0); + emit updateXValueInterval(this->minxvalue, this->maxxvalue); redrawScene(); viewport()->update(); } -void cCalibrationChartScene::resetConcentrationInterval() { - minconcentration = 0; - maxconcentration = 1000; - emit updateConcentrationInterval(minconcentration, maxconcentration); +void cCalibrationChartScene::resetXValueInterval() { + minxvalue = 0; + if (graphtype == 0) { + maxxvalue = getMaximumConcentration(); + if (maxxvalue == 0) { + maxxvalue = 1000; + } + } + else { + maxxvalue = (double)getMaximumCollectionTime(); + if (maxxvalue == 0) { + maxxvalue = 240; + } + } + + emit updateXValueInterval(minxvalue, maxxvalue); redrawScene(); } -//void cCalibrationChartScene::enableMouseConcentrationSelectionTool(bool enable) { -// enablemouseconcentrationselection = enable; +//void cCalibrationChartScene::enableMouseXValueSelectionTool(bool enable) { +// enablemousexvalueselection = enable; // pressedx = -1; // pressedy = -1; // diff --git a/CycloBranch/gui/cCalibrationChartScene.h b/CycloBranch/gui/cCalibrationChartScene.h index 7d4a49f..27b56a8 100644 --- a/CycloBranch/gui/cCalibrationChartScene.h +++ b/CycloBranch/gui/cCalibrationChartScene.h @@ -123,7 +123,7 @@ class cCalibrationChartScene : public QGraphicsView \param b b \param xvalues x coordinates of points \param yvalues y coordinates of points - \param sd standard deviation of y-values + \param sd standard deviation of y values */ void setLineParameters(int equationtype, double a, double b, vector xvalues, vector yvalues, vector sd); @@ -132,10 +132,32 @@ class cCalibrationChartScene : public QGraphicsView \brief Set parameters of calibration curve. \param datax x coordinates of data points \param datay y coordinates of data points - \param datasd standard deviation of y-values - \param datagroups vector of group ids + \param datasd standard deviation of y values + \param datagroups vector of group names + \param datatimevalues data collection times corresponding the groups */ - void setData(vector datax, vector datay, vector datasd, vector datagroups); + void setData(vector datax, vector datay, vector datasd, vector datagroups, vector datatimevalues); + + + /** + \brief Set graph type. + \param type graph type + */ + void setGraphType(int type); + + + /** + \brief Get the maximum concentration. + \retval double maximum concentration + */ + double getMaximumConcentration(); + + + /** + \brief Get the maximum collection time. + \retval int maximum value of collection time + */ + int getMaximumCollectionTime(); protected: @@ -197,6 +219,8 @@ class cCalibrationChartScene : public QGraphicsView //cPeaksList isotopicpattern; + int graphtype; + qreal currentscale; qreal factor; @@ -213,8 +237,8 @@ class cCalibrationChartScene : public QGraphicsView int currentx; int currenty; - double minconcentration; - double maxconcentration; + double minxvalue; + double maxxvalue; int topmargin; int bottommargin; @@ -222,7 +246,7 @@ class cCalibrationChartScene : public QGraphicsView int rightmargin; bool firstshow; - bool enablemouseconcentrationselection; + bool enablemousexvalueselection; int equationtype; @@ -238,21 +262,23 @@ class cCalibrationChartScene : public QGraphicsView vector datay; vector datasd; - vector datagroups; + vector datagroups; + + vector datatimevalues; bool hidelabels; - double getConcentrationFromXPosition(int x, int w); + double getValueFromXPosition(int x, int w); - int getXPositionFromConcentration(double concentration, int w); + int getXPositionFromValue(double value, int w); - double getIntensityFromYPosition(int y, int h); + double getValueFromYPosition(int y, int h); - int getYPositionFromIntensity(double intensity, int h); + int getYPositionFromValue(double intensity, int h); void redrawScene(); @@ -261,21 +287,21 @@ class cCalibrationChartScene : public QGraphicsView void updateZoomGroup(); - void calculateMinMaxConcentration(); + void calculateMinMaxXValue(); - double getMaximumIntensity(); + double getMaximumYValue(); signals: /** - \brief The signal is emitted when the range of concentration has been changed. - \param minconcentration a minimum threshold of concentration - \param maxconcentration a maximum threshold of concentration + \brief The signal is emitted when the range of x value has been changed. + \param minxvalue a minimum threshold of x value + \param maxxvalue a maximum threshold of x value */ - void updateConcentrationInterval(double minconcentration, double maxconcentration); + void updateXValueInterval(double minxvalue, double maxxvalue); private slots: @@ -290,13 +316,13 @@ private slots: void normalSize(); - void setConcentrationInterval(double minconcentration, double maxconcentration); + void setXValueInterval(double minxvalue, double maxxvalue); - void resetConcentrationInterval(); + void resetXValueInterval(); - //void enableMouseConcentrationSelectionTool(bool enable); + //void enableMouseXValueSelectionTool(bool enable); }; diff --git a/CycloBranch/gui/cChromatogramWindow.cpp b/CycloBranch/gui/cChromatogramWindow.cpp index 60913d5..518dd81 100644 --- a/CycloBranch/gui/cChromatogramWindow.cpp +++ b/CycloBranch/gui/cChromatogramWindow.cpp @@ -212,6 +212,10 @@ cChromatogramWindow::cChromatogramWindow(cGlobalPreferences* globalpreferences, connect(resetscanidinterval, SIGNAL(released()), chromatogramwindowwidget, SLOT(resetScanIDInterval())); connect(chromatogramwindowwidget, SIGNAL(updateScanIDInterval(int, int)), this, SLOT(updateScanIDInterval(int, int))); + sumofspectra = new QPushButton(" Average Spectrum "); + sumofspectra->setMinimumWidth(100); + connect(sumofspectra, SIGNAL(released()), this, SLOT(showAvgSpectrum())); + hboxscanid = new QHBoxLayout(); hboxscanid->addWidget(labelscanid); hboxscanid->addWidget(minscanid); @@ -221,6 +225,8 @@ cChromatogramWindow::cChromatogramWindow(cGlobalPreferences* globalpreferences, hboxscanid->addWidget(setscanidinterval); hboxscanid->addSpacing(5); hboxscanid->addWidget(resetscanidinterval); + hboxscanid->addSpacing(5); + hboxscanid->addWidget(sumofspectra); widgetscanid = new QWidget(); widgetscanid->setLayout(hboxscanid); @@ -285,6 +291,7 @@ cChromatogramWindow::~cChromatogramWindow() { delete maxscanid; delete setscanidinterval; delete resetscanidinterval; + delete sumofspectra; delete hboxscanid; delete widgetscanid; @@ -453,3 +460,8 @@ void cChromatogramWindow::chromatogramDoubleClickedSlot(int scanid) { emit doubleClickedScanIDSignal(scanid); } + +void cChromatogramWindow::showAvgSpectrum() { + setScanIDInterval(); + emit calculateAvgSpectrum(minscanid->value(), maxscanid->value()); +} \ No newline at end of file diff --git a/CycloBranch/gui/cChromatogramWindow.h b/CycloBranch/gui/cChromatogramWindow.h index 7ce9c99..77b23d1 100644 --- a/CycloBranch/gui/cChromatogramWindow.h +++ b/CycloBranch/gui/cChromatogramWindow.h @@ -135,6 +135,7 @@ class cChromatogramWindow : public QMainWindow QSpinBox* maxscanid; QPushButton* setscanidinterval; QPushButton* resetscanidinterval; + QPushButton* sumofspectra; QToolBar* toolbarHelp; QAction* actionHTMLDocumentation; @@ -180,6 +181,14 @@ class cChromatogramWindow : public QMainWindow void doubleClickedScanIDSignal(int scanid); + /** + \brief The signal is emitted if the average spectrum is calculated. + \param minid minimum scan id + \param maxid maximum scan id + */ + void calculateAvgSpectrum(int minid, int maxid); + + private slots: @@ -209,6 +218,9 @@ private slots: void chromatogramDoubleClickedSlot(int scanid); + + void showAvgSpectrum(); + }; #endif diff --git a/CycloBranch/gui/cChromatogramWindowWidget.cpp b/CycloBranch/gui/cChromatogramWindowWidget.cpp index 31c333c..0cf6027 100644 --- a/CycloBranch/gui/cChromatogramWindowWidget.cpp +++ b/CycloBranch/gui/cChromatogramWindowWidget.cpp @@ -1392,6 +1392,16 @@ void cChromatogramWindowWidget::redrawScene() { int w = origwidth; int h = origheight; + + int numberofchromatograms = 1; + + vector hvec; + int hstep = 50; + int hvalue = (h - hstep * (numberofchromatograms - 1)) / numberofchromatograms; + for (int i = 0; i < numberofchromatograms; i++) { + hvec.push_back(hvalue * (i + 1) + hstep * i); + } + int rulergranularity = 10; QFont myFont("Arial", 8); @@ -1417,504 +1427,610 @@ void cChromatogramWindowWidget::redrawScene() { fronting = true; } - if (!hidetic) { - if (absoluteintensity) { - maxintensitytic = ticchromatogram.getMaximumAbsoluteIntensityFromMZInterval((double)minscan, (double)maxscan, false, false, other, false); - } - else { - maxintensitytic = ticchromatogram.getMaximumRelativeIntensityFromMZInterval((double)minscan, (double)maxscan, false, false, other, false); - } - } + double maxintensity; - if (!hideeic) { - if (absoluteintensity) { - maxintensityeic = localeic.getMaximumAbsoluteIntensityFromMZInterval((double)minscan, (double)maxscan, false, false, other, false); - } - else { - maxintensityeic = localeic.getMaximumRelativeIntensityFromMZInterval((double)minscan, (double)maxscan, false, false, other, false); - } + scene->removeItem(zoomgroup); + scene->clear(); + + if ((ticchromatogram.size() < 2) || (hidetic && (localeic.size() < 2))) { + simpletext = scene->addSimpleText("The chromatogram is not available.", myFont); + simpletext->setPos(0, 0); + scene->setSceneRect(scene->itemsBoundingRect()); + + zoomgroup->setVisible(false); + scene->addItem(zoomgroup); + + return; } - double maxintensity = max(maxintensitytic, maxintensityeic); + zoomgroup->setVisible(false); + scene->addItem(zoomgroup); + + for (int hv = 0; hv < numberofchromatograms; hv++) { - if (rawdatastate && !hideeic && (maxscan > minscan - 1)) { - size_t eicsize = localeic.size(); - for (int i = 0; i < eicsize; i++) { - if ((localeic[i].mzratio < (double)minscan) || (localeic[i].mzratio > (double)maxscan)) { - localeic[i].absoluteintensity = 0; - localeic[i].relativeintensity = 0; + if (!hidetic) { + if (absoluteintensity) { + maxintensitytic = ticchromatogram.getMaximumAbsoluteIntensityFromMZInterval((double)minscan, (double)maxscan, false, false, other, false); + } + else { + maxintensitytic = ticchromatogram.getMaximumRelativeIntensityFromMZInterval((double)minscan, (double)maxscan, false, false, other, false); } } - calculateGaussianParameters(localeic, rtimes, 1, absoluteintensity, false, nys, sigmas, as); - - double newmaxintensity = maxintensity; - for (int i = 0; i < (int)nys.size(); i++) { - if (as[i] / maxintensity > 2 * maxintensity) { - nys[i] = 0; - sigmas[i] = 0; - as[i] = 0; + if (!hideeic) { + if (absoluteintensity) { + maxintensityeic = localeic.getMaximumAbsoluteIntensityFromMZInterval((double)minscan, (double)maxscan, false, false, other, false); } - - if (as[i] > newmaxintensity) { - newmaxintensity = as[i]; + else { + maxintensityeic = localeic.getMaximumRelativeIntensityFromMZInterval((double)minscan, (double)maxscan, false, false, other, false); } } - if (absoluteintensity) { - maxintensity = max(maxintensity, newmaxintensity); - } - else { - if ((newmaxintensity > maxintensity) && (newmaxintensity > 0)) { - for (int i = 0; i < localeic.size(); i++) { - localeic[i].relativeintensity = localeic[i].relativeintensity * maxintensity / newmaxintensity; - } + maxintensity = max(maxintensitytic, maxintensityeic); - for (int i = 0; i < (int)as.size(); i++) { - as[i] = as[i] * maxintensity / newmaxintensity; + if (rawdatastate && !hideeic && (maxscan > minscan - 1)) { + size_t eicsize = localeic.size(); + for (int i = 0; i < eicsize; i++) { + if ((localeic[i].mzratio < (double)minscan) || (localeic[i].mzratio > (double)maxscan)) { + localeic[i].absoluteintensity = 0; + localeic[i].relativeintensity = 0; } } - } - } - scene->removeItem(zoomgroup); - scene->clear(); + calculateGaussianParameters(localeic, rtimes, 1, absoluteintensity, false, nys, sigmas, as); - if ((ticchromatogram.size() < 2) || (hidetic && (localeic.size() < 2))) { - simpletext = scene->addSimpleText("The chromatogram is not available.", myFont); - simpletext->setPos(0, 0); - scene->setSceneRect(scene->itemsBoundingRect()); + double newmaxintensity = maxintensity; + for (int i = 0; i < (int)nys.size(); i++) { + if (as[i] / maxintensity > 2 * maxintensity) { + nys[i] = 0; + sigmas[i] = 0; + as[i] = 0; + } - zoomgroup->setVisible(false); - scene->addItem(zoomgroup); + if (as[i] > newmaxintensity) { + newmaxintensity = as[i]; + } + } - return; - } + if (absoluteintensity) { + maxintensity = max(maxintensity, newmaxintensity); + } + else { + if ((newmaxintensity > maxintensity) && (newmaxintensity > 0)) { + for (int i = 0; i < localeic.size(); i++) { + localeic[i].relativeintensity = localeic[i].relativeintensity * maxintensity / newmaxintensity; + } - zoomgroup->setVisible(false); - scene->addItem(zoomgroup); + for (int i = 0; i < (int)as.size(); i++) { + as[i] = as[i] * maxintensity / newmaxintensity; + } + } + } + } - // x axis - scene->addLine(leftmargin, h - bottommargin, w - rightmargin, h - bottommargin, QPen(Qt::black, 2, Qt::SolidLine)); + // x axis + scene->addLine(leftmargin, hvec[hv] - bottommargin, w - rightmargin, hvec[hv] - bottommargin, QPen(Qt::black, 2, Qt::SolidLine)); - // x axis ruler - xstep = (w - leftmargin - rightmargin) / rulergranularity; - for (int i = 0; i < rulergranularity; i++) { - scene->addLine(leftmargin + xstep * i, h - bottommargin, leftmargin + xstep * i, h - bottommargin + 10, QPen(Qt::black, 2, Qt::SolidLine)); - } - scene->addLine(w - rightmargin, h - bottommargin, w - rightmargin, h - bottommargin + 10, QPen(Qt::black, 2, Qt::SolidLine)); + // x axis ruler + xstep = (w - leftmargin - rightmargin) / rulergranularity; + for (int i = 0; i < rulergranularity; i++) { + scene->addLine(leftmargin + xstep * i, hvec[hv] - bottommargin, leftmargin + xstep * i, hvec[hv] - bottommargin + 10, QPen(Qt::black, 2, Qt::SolidLine)); + } + scene->addLine(w - rightmargin, hvec[hv] - bottommargin, w - rightmargin, hvec[hv] - bottommargin + 10, QPen(Qt::black, 2, Qt::SolidLine)); - printscan = minscan - 1; - if (retentiontime) { - if (printscan - 1 >= 0) { - simpletext = scene->addSimpleText(QString::number(rtimes[printscan - 1]), myFont); + printscan = minscan - 1; + if (retentiontime) { + if (printscan - 1 >= 0) { + simpletext = scene->addSimpleText(QString::number(rtimes[printscan - 1]), myFont); + } + else { + simpletext = scene->addSimpleText(QString::number(0), myFont); + } } else { - simpletext = scene->addSimpleText(QString::number(0), myFont); + simpletext = scene->addSimpleText(QString::number(printscan), myFont); } - } - else { - simpletext = scene->addSimpleText(QString::number(printscan), myFont); - } - simpletext->setPos(QPointF(leftmargin - simpletext->boundingRect().width() / 2, h - bottommargin + 12)); + simpletext->setPos(QPointF(leftmargin - simpletext->boundingRect().width() / 2, hvec[hv] - bottommargin + 12)); - if (maxscan - minscan > rulergranularity) { - xstep = (w - leftmargin - rightmargin) / rulergranularity; - for (int i = 1; i < rulergranularity; i++) { - printscan = (double)minscan + (double)(maxscan - minscan) / (double)rulergranularity * (double)i; - if (retentiontime) { - if (printscan - 1 >= 0) { - simpletext = scene->addSimpleText(QString::number(rtimes[printscan - 1]), myFont); + if (maxscan - minscan > rulergranularity) { + xstep = (w - leftmargin - rightmargin) / rulergranularity; + for (int i = 1; i < rulergranularity; i++) { + printscan = (double)minscan + (double)(maxscan - minscan) / (double)rulergranularity * (double)i; + if (retentiontime) { + if (printscan - 1 >= 0) { + simpletext = scene->addSimpleText(QString::number(rtimes[printscan - 1]), myFont); + } + else { + simpletext = scene->addSimpleText(QString::number(0), myFont); + } } else { - simpletext = scene->addSimpleText(QString::number(0), myFont); + simpletext = scene->addSimpleText(QString::number(printscan), myFont); } + simpletext->setPos(QPointF(leftmargin + xstep * i - simpletext->boundingRect().width() / 2, hvec[hv] - bottommargin + 12)); + } + } + + printscan = maxscan; + if (retentiontime) { + if (printscan - 1 >= 0) { + simpletext = scene->addSimpleText(QString::number(rtimes[printscan - 1]), myFont); } else { - simpletext = scene->addSimpleText(QString::number(printscan), myFont); + simpletext = scene->addSimpleText(QString::number(0), myFont); } - simpletext->setPos(QPointF(leftmargin + xstep * i - simpletext->boundingRect().width() / 2, h - bottommargin + 12)); } - } + else { + simpletext = scene->addSimpleText(QString::number(printscan), myFont); + } + simpletext->setPos(QPointF(w - rightmargin - simpletext->boundingRect().width() / 2, hvec[hv] - bottommargin + 12)); - printscan = maxscan; - if (retentiontime) { - if (printscan - 1 >= 0) { - simpletext = scene->addSimpleText(QString::number(rtimes[printscan - 1]), myFont); + // y axis + if (hv > 0) { + scene->addLine(leftmargin, hvec[hv] - bottommargin, leftmargin, hvec[hv - 1] + hstep - bottommargin, QPen(Qt::black, 2, Qt::SolidLine)); } else { - simpletext = scene->addSimpleText(QString::number(0), myFont); + scene->addLine(leftmargin, hvec[hv] - bottommargin, leftmargin, hvec[hv] - bottommargin - std::max(hvec[hv] - topmargin - bottommargin, 0), QPen(Qt::black, 2, Qt::SolidLine)); } - } - else { - simpletext = scene->addSimpleText(QString::number(printscan), myFont); - } - simpletext->setPos(QPointF(w - rightmargin - simpletext->boundingRect().width() / 2, h - bottommargin + 12)); - // y axis - scene->addLine(leftmargin, h - bottommargin, leftmargin, h - bottommargin - std::max(h - topmargin - bottommargin, 0), QPen(Qt::black, 2, Qt::SolidLine)); + // y axis ruler + if (hv > 0) { + ystep = (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin) / rulergranularity; + } + else { + ystep = (hvec[hv] - topmargin - bottommargin) / rulergranularity; + } + for (int i = 0; i < rulergranularity; i++) { + scene->addLine(leftmargin - 10, hvec[hv] - bottommargin - ystep * i, leftmargin, hvec[hv] - bottommargin - ystep * i, QPen(Qt::black, 2, Qt::SolidLine)); + } - // y axis ruler - ystep = (h - topmargin - bottommargin) / rulergranularity; - for (int i = 0; i < rulergranularity; i++) { - scene->addLine(leftmargin - 10, h - bottommargin - ystep * i, leftmargin, h - bottommargin - ystep * i, QPen(Qt::black, 2, Qt::SolidLine)); - } - scene->addLine(leftmargin - 10, h - bottommargin - std::max(h - topmargin - bottommargin, 0), leftmargin, h - bottommargin - std::max(h - topmargin - bottommargin, 0), QPen(Qt::black, 2, Qt::SolidLine)); + if (hv > 0) { + scene->addLine(leftmargin - 10, hvec[hv - 1] + hstep - bottommargin, leftmargin, hvec[hv - 1] + hstep - bottommargin, QPen(Qt::black, 2, Qt::SolidLine)); + } + else { + scene->addLine(leftmargin - 10, hvec[hv] - bottommargin - std::max(hvec[hv] - topmargin - bottommargin, 0), leftmargin, hvec[hv] - bottommargin - std::max(hvec[hv] - topmargin - bottommargin, 0), QPen(Qt::black, 2, Qt::SolidLine)); + } - if (absoluteintensity) { - simpletext = scene->addSimpleText(QString::number(0), myFont); - } - else { - simpletext = scene->addSimpleText(QString::number(0) + " %", myFont); - } - simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), h - bottommargin - simpletext->boundingRect().height() / 2)); + if (absoluteintensity) { + simpletext = scene->addSimpleText(QString::number(0), myFont); + } + else { + simpletext = scene->addSimpleText(QString::number(0) + " %", myFont); + } + simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), hvec[hv] - bottommargin - simpletext->boundingRect().height() / 2)); - ystep = (h - topmargin - bottommargin) / rulergranularity; - if (absoluteintensity) { - if (maxintensity > rulergranularity) { - for (int i = 1; i < rulergranularity; i++) { - simpletext = scene->addSimpleText(QString::number((unsigned long long)maxintensity / (unsigned long long)rulergranularity * (unsigned long long)i), myFont); - simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), h - bottommargin - simpletext->boundingRect().height() / 2 - ystep * i)); + if (hv > 0) { + ystep = (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin) / rulergranularity; + } + else { + ystep = (hvec[hv] - topmargin - bottommargin) / rulergranularity; + } + if (absoluteintensity) { + if (maxintensity > rulergranularity) { + for (int i = 1; i < rulergranularity; i++) { + simpletext = scene->addSimpleText(QString::number((unsigned long long)maxintensity / (unsigned long long)rulergranularity * (unsigned long long)i), myFont); + simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), hvec[hv] - bottommargin - simpletext->boundingRect().height() / 2 - ystep * i)); + } } } - } - else { - if (maxintensity > 0) { - for (int i = 1; i < rulergranularity; i++) { - simpletext = scene->addSimpleText(QString::number(maxintensity / (double)rulergranularity * (double)i) + " %", myFont); - simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), h - bottommargin - simpletext->boundingRect().height() / 2 - ystep * i)); + else { + if (maxintensity > 0) { + for (int i = 1; i < rulergranularity; i++) { + simpletext = scene->addSimpleText(QString::number(maxintensity / (double)rulergranularity * (double)i) + " %", myFont); + simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), hvec[hv] - bottommargin - simpletext->boundingRect().height() / 2 - ystep * i)); + } } } - } - if (absoluteintensity) { - simpletext = scene->addSimpleText(QString::number((unsigned long long)maxintensity), myFont); - } - else { - simpletext = scene->addSimpleText(QString::number(maxintensity) + " %", myFont); - } - simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), h - bottommargin - std::max(h - topmargin - bottommargin, 0) - simpletext->boundingRect().height() / 2)); + if (absoluteintensity) { + simpletext = scene->addSimpleText(QString::number((unsigned long long)maxintensity), myFont); + } + else { + simpletext = scene->addSimpleText(QString::number(maxintensity) + " %", myFont); + } + if (hv > 0) { + simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), hvec[hv - 1] + hstep - bottommargin - simpletext->boundingRect().height() / 2)); + } + else { + simpletext->setPos(QPointF(leftmargin - 15 - simpletext->boundingRect().width(), hvec[hv] - bottommargin - std::max(hvec[hv] - topmargin - bottommargin, 0) - simpletext->boundingRect().height() / 2)); + } - // TIC peaks - if (!hidetic) { + // TIC peaks + if (!hidetic) { - for (int i = 0; i < ticchromatogram.size(); i++) { + for (int i = 0; i < ticchromatogram.size(); i++) { - if ((ticchromatogram[i].mzratio < (double)minscan) || (ticchromatogram[i].mzratio > (double)maxscan)) { - continue; - } + if ((ticchromatogram[i].mzratio < (double)minscan) || (ticchromatogram[i].mzratio > (double)maxscan)) { + continue; + } - x = getXPositionFromScanID((int)ticchromatogram[i].mzratio, w); + x = getXPositionFromScanID((int)ticchromatogram[i].mzratio, w); - printintensity = true; - if (absoluteintensity) { - y = ticchromatogram[i].absoluteintensity / maxintensity * (h - topmargin - bottommargin); - if (ticchromatogram[i].absoluteintensity == 0) { - printintensity = false; + printintensity = true; + if (hv > 0) { + if (absoluteintensity) { + y = ticchromatogram[i].absoluteintensity / maxintensity * (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + if (ticchromatogram[i].absoluteintensity == 0) { + printintensity = false; + } + } + else { + y = ticchromatogram[i].relativeintensity / maxintensity * (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + if (ticchromatogram[i].relativeintensity == 0) { + printintensity = false; + } + } } - } - else { - y = ticchromatogram[i].relativeintensity / maxintensity * (h - topmargin - bottommargin); - if (ticchromatogram[i].relativeintensity == 0) { - printintensity = false; + else { + if (absoluteintensity) { + y = ticchromatogram[i].absoluteintensity / maxintensity * (hvec[hv] - topmargin - bottommargin); + if (ticchromatogram[i].absoluteintensity == 0) { + printintensity = false; + } + } + else { + y = ticchromatogram[i].relativeintensity / maxintensity * (hvec[hv] - topmargin - bottommargin); + if (ticchromatogram[i].relativeintensity == 0) { + printintensity = false; + } + } } - } - if (printintensity) { - line = scene->addLine(x, h - bottommargin - 2, x, h - bottommargin - std::max((int)y, 2), QPen(Qt::black, 2, Qt::SolidLine)); - peakscount++; + if (printintensity) { + line = scene->addLine(x, hvec[hv] - bottommargin - 2, x, hvec[hv] - bottommargin - std::max((int)y, 2), QPen(Qt::black, 2, Qt::SolidLine)); + peakscount++; + } } } - } - - // EIC peaks - if (!hideeic) { + // EIC peaks + if (!hideeic) { - for (int i = 0; i < localeic.size(); i++) { + for (int i = 0; i < localeic.size(); i++) { - if ((localeic[i].mzratio < (double)minscan) || (localeic[i].mzratio > (double)maxscan)) { - continue; - } + if ((localeic[i].mzratio < (double)minscan) || (localeic[i].mzratio > (double)maxscan)) { + continue; + } - x = getXPositionFromScanID((int)localeic[i].mzratio, w); + x = getXPositionFromScanID((int)localeic[i].mzratio, w); - printintensity = true; - if (absoluteintensity) { - y = localeic[i].absoluteintensity / maxintensity * (h - topmargin - bottommargin); - if (localeic[i].absoluteintensity == 0) { - printintensity = false; + printintensity = true; + if (hv > 0) { + if (absoluteintensity) { + y = localeic[i].absoluteintensity / maxintensity * (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + if (localeic[i].absoluteintensity == 0) { + printintensity = false; + } + } + else { + y = localeic[i].relativeintensity / maxintensity * (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + if (localeic[i].relativeintensity == 0) { + printintensity = false; + } + } } - } - else { - y = localeic[i].relativeintensity / maxintensity * (h - topmargin - bottommargin); - if (localeic[i].relativeintensity == 0) { - printintensity = false; + else { + if (absoluteintensity) { + y = localeic[i].absoluteintensity / maxintensity * (hvec[hv] - topmargin - bottommargin); + if (localeic[i].absoluteintensity == 0) { + printintensity = false; + } + } + else { + y = localeic[i].relativeintensity / maxintensity * (hvec[hv] - topmargin - bottommargin); + if (localeic[i].relativeintensity == 0) { + printintensity = false; + } + } + } + + if (printintensity) { + line = scene->addLine(x, hvec[hv] - bottommargin - 2, x, hvec[hv] - bottommargin - std::max((int)y, 2), QPen(Qt::red, 2, Qt::SolidLine)); + line->setZValue(1); + peakscount++; } - } - if (printintensity) { - line = scene->addLine(x, h - bottommargin - 2, x, h - bottommargin - std::max((int)y, 2), QPen(Qt::red, 2, Qt::SolidLine)); - line->setZValue(1); - peakscount++; } } - } - - // TIC descriptions - if (!hidetic && (peakscount < 500)) { + // TIC descriptions + if (!hidetic && (peakscount < 500)) { - for (int i = 0; i < ticchromatogram.size(); i++) { - - if ((ticchromatogram[i].mzratio < (double)minscan) || (ticchromatogram[i].mzratio > (double)maxscan)) { - continue; - } + for (int i = 0; i < ticchromatogram.size(); i++) { - x = getXPositionFromScanID((int)ticchromatogram[i].mzratio, w); - - printintensity = true; - if (absoluteintensity) { - y = ticchromatogram[i].absoluteintensity / maxintensity * (h - topmargin - bottommargin); - if (ticchromatogram[i].absoluteintensity == 0) { - printintensity = false; - } - } - else { - y = ticchromatogram[i].relativeintensity / maxintensity * (h - topmargin - bottommargin); - if (ticchromatogram[i].relativeintensity == 0) { - printintensity = false; + if ((ticchromatogram[i].mzratio < (double)minscan) || (ticchromatogram[i].mzratio > (double)maxscan)) { + continue; } - } - if (printintensity) { - - if (retentiontime) { - simpletext = scene->addSimpleText(QString::number(rtimes[i]) + " ", myFont); + x = getXPositionFromScanID((int)ticchromatogram[i].mzratio, w); + + printintensity = true; + if (hv > 0) { + if (absoluteintensity) { + y = ticchromatogram[i].absoluteintensity / maxintensity * (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + if (ticchromatogram[i].absoluteintensity == 0) { + printintensity = false; + } + } + else { + y = ticchromatogram[i].relativeintensity / maxintensity * (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + if (ticchromatogram[i].relativeintensity == 0) { + printintensity = false; + } + } } else { - simpletext = scene->addSimpleText(QString::number((int)ticchromatogram[i].mzratio) + " ", myFont); + if (absoluteintensity) { + y = ticchromatogram[i].absoluteintensity / maxintensity * (hvec[hv] - topmargin - bottommargin); + if (ticchromatogram[i].absoluteintensity == 0) { + printintensity = false; + } + } + else { + y = ticchromatogram[i].relativeintensity / maxintensity * (hvec[hv] - topmargin - bottommargin); + if (ticchromatogram[i].relativeintensity == 0) { + printintensity = false; + } + } } - tx = x - 2; - ty = h - bottommargin - std::max((int)y, 2) - simpletext->boundingRect().height() - 1 - 4; - simpletext->setPos(tx, ty); - simpletext->setBrush(Qt::black); - if (scene->collidingItems(simpletext, Qt::IntersectsItemBoundingRect).size() > 0) { - scene->removeItem(simpletext); - } + if (printintensity) { - } + if (retentiontime) { + simpletext = scene->addSimpleText(QString::number(rtimes[i]) + " ", myFont); + } + else { + simpletext = scene->addSimpleText(QString::number((int)ticchromatogram[i].mzratio) + " ", myFont); + } + tx = x - 2; + ty = hvec[hv] - bottommargin - std::max((int)y, 2) - simpletext->boundingRect().height() - 1 - 4; + simpletext->setPos(tx, ty); + simpletext->setBrush(Qt::black); - } + if (scene->collidingItems(simpletext, Qt::IntersectsItemBoundingRect).size() > 0) { + scene->removeItem(simpletext); + } - } + } - // EIC descriptions - if (!hideeic && (peakscount < 500)) { + } - for (int i = 0; i < localeic.size(); i++) { + } - if ((localeic[i].mzratio < (double)minscan) || (localeic[i].mzratio >(double)maxscan)) { - continue; - } + // EIC descriptions + if (!hideeic && (peakscount < 500)) { - x = getXPositionFromScanID((int)localeic[i].mzratio, w); + for (int i = 0; i < localeic.size(); i++) { - printintensity = true; - if (absoluteintensity) { - y = localeic[i].absoluteintensity / maxintensity * (h - topmargin - bottommargin); - if (localeic[i].absoluteintensity == 0) { - printintensity = false; - } - } - else { - y = localeic[i].relativeintensity / maxintensity * (h - topmargin - bottommargin); - if (localeic[i].relativeintensity == 0) { - printintensity = false; + if ((localeic[i].mzratio < (double)minscan) || (localeic[i].mzratio > (double)maxscan)) { + continue; } - } - - if (printintensity) { - QList hiddenitems; - qreal tx, ty, tw, th, sumh; + x = getXPositionFromScanID((int)localeic[i].mzratio, w); - vector hits; - string tmplong; - string tmpshort; - size_t pos; - - hits.clear(); - - if (!hidelabels) { - tmplong = localeic[i].description.c_str(); - pos = tmplong.find("
"); - while (pos != string::npos) { - tmpshort = tmplong.substr(0, pos); - hits.push_back(tmpshort); - tmplong = tmplong.substr(pos + 5); - pos = tmplong.find("
"); + printintensity = true; + if (hv > 0) { + if (absoluteintensity) { + y = localeic[i].absoluteintensity / maxintensity * (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + if (localeic[i].absoluteintensity == 0) { + printintensity = false; + } } - if (tmplong.size() > 0) { - hits.push_back(tmplong); + else { + y = localeic[i].relativeintensity / maxintensity * (hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + if (localeic[i].relativeintensity == 0) { + printintensity = false; + } } - sort(hits.rbegin(), hits.rend()); - } - - if (retentiontime) { - tmpshort = QString::number(rtimes[i]).toStdString(); } else { - tmpshort = QString::number((int)localeic[i].mzratio).toStdString(); - } - - hits.push_back(tmpshort); - - hiddenitems.clear(); - sumh = 0; - for (vector::reverse_iterator rit = hits.rbegin(); rit != hits.rend(); ++rit) { - text = scene->addText(""); - text->setDefaultTextColor(QColor(Qt::red)); - text->setFont(myFont); - text->setTextInteractionFlags(Qt::TextBrowserInteraction); - text->setOpenExternalLinks(true); - text->setHtml(rit->c_str()); - - tw = text->boundingRect().width(); - th = text->boundingRect().height(); - sumh += th + 1; - tx = x - 2 - 4; - ty = h - bottommargin - std::max((int)y, 2) - sumh - 4; - text->setPos(tx, ty); - text->setZValue(2); - - hiddenitems.append(text); - - if (scene->items(tx, ty, tw, th, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder).size() > 1) { - for (int k = 0; k < (int)hiddenitems.size(); k++) { - scene->removeItem(hiddenitems[k]); + if (absoluteintensity) { + y = localeic[i].absoluteintensity / maxintensity * (hvec[hv] - topmargin - bottommargin); + if (localeic[i].absoluteintensity == 0) { + printintensity = false; + } + } + else { + y = localeic[i].relativeintensity / maxintensity * (hvec[hv] - topmargin - bottommargin); + if (localeic[i].relativeintensity == 0) { + printintensity = false; } - break; } - } - } + if (printintensity) { - } + QList hiddenitems; + qreal tx, ty, tw, th, sumh; - } + vector hits; + string tmplong; + string tmpshort; + size_t pos; - // estimate chromatographic profile peaks - if (rawdatastate && !hideeic && (maxscan > minscan - 1)) { + hits.clear(); - double ynorm = (double)(h - topmargin - bottommargin); + if (!hidelabels) { + tmplong = localeic[i].description.c_str(); + pos = tmplong.find("
"); + while (pos != string::npos) { + tmpshort = tmplong.substr(0, pos); + hits.push_back(tmpshort); + tmplong = tmplong.substr(pos + 5); + pos = tmplong.find("
"); + } + if (tmplong.size() > 0) { + hits.push_back(tmplong); + } + sort(hits.rbegin(), hits.rend()); + } - if (peakshape > 0) { - calculateExponentialParameters(localeic, rtimes, 1, absoluteintensity, false, fronting, ynorm, bases, taus); - } + if (retentiontime) { + tmpshort = QString::number(rtimes[i]).toStdString(); + } + else { + tmpshort = QString::number((int)localeic[i].mzratio).toStdString(); + } - for (int i = 0; i < (int)nys.size(); i++) { - nys[i] = nys[i] - ((double)minscan - 1.0); - nys[i] /= (double)maxscan - ((double)minscan - 1.0); - nys[i] *= (double)(w - leftmargin - rightmargin); - nys[i] += leftmargin; + hits.push_back(tmpshort); + + hiddenitems.clear(); + sumh = 0; + for (vector::reverse_iterator rit = hits.rbegin(); rit != hits.rend(); ++rit) { + text = scene->addText(""); + text->setDefaultTextColor(QColor(Qt::red)); + text->setFont(myFont); + text->setTextInteractionFlags(Qt::TextBrowserInteraction); + text->setOpenExternalLinks(true); + text->setHtml(rit->c_str()); + + tw = text->boundingRect().width(); + th = text->boundingRect().height(); + sumh += th + 1; + tx = x - 2 - 4; + ty = hvec[hv] - bottommargin - std::max((int)y, 2) - sumh - 4; + text->setPos(tx, ty); + text->setZValue(2); + + hiddenitems.append(text); + + if (scene->items(tx, ty, tw, th, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder).size() > 1) { + for (int k = 0; k < (int)hiddenitems.size(); k++) { + scene->removeItem(hiddenitems[k]); + } + break; + } - sigmas[i] /= (double)maxscan - ((double)minscan - 1.0); - sigmas[i] *= (double)(w - leftmargin - rightmargin); + } - as[i] /= maxintensity; - as[i] *= (double)(h - topmargin - bottommargin); + } - if (peakshape > 0) { - taus[i] /= (double)maxscan - ((double)minscan - 1.0); - taus[i] *= (double)(w - leftmargin - rightmargin); } - } - const int step = 1; - - int xmin = getXPositionFromScanID(minscan - 1.0, w); - int xmax = getXPositionFromScanID(maxscan, w); + } - double relint; - int yval; + // estimate chromatographic profile peaks + if (rawdatastate && !hideeic && (maxscan > minscan - 1)) { - QPainterPath rpath; + double ynorm; + if (hv > 0) { + ynorm = (double)(hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); + } + else { + ynorm = (double)(hvec[hv] - topmargin - bottommargin); + } - if (peakshape == 0) { - for (int i = xmin; i < xmax; i += step) { - relint = 0; + if (peakshape > 0) { + calculateExponentialParameters(localeic, rtimes, 1, absoluteintensity, false, fronting, ynorm, bases, taus); + } - for (int j = 0; j < (int)as.size(); j++) { - relint += computeGaussFunction((double)i, as[j], nys[j], sigmas[j]); - } + for (int i = 0; i < (int)nys.size(); i++) { + nys[i] = nys[i] - ((double)minscan - 1.0); + nys[i] /= (double)maxscan - ((double)minscan - 1.0); + nys[i] *= (double)(w - leftmargin - rightmargin); + nys[i] += leftmargin; - yval = h - topmargin - bottommargin - (int)relint; + sigmas[i] /= (double)maxscan - ((double)minscan - 1.0); + sigmas[i] *= (double)(w - leftmargin - rightmargin); - if (i == xmin) { - rpath.moveTo(i, yval); + as[i] /= maxintensity; + if (hv > 0) { + as[i] *= (double)(hvec[hv] - hvec[hv - 1] - hstep - topmargin - bottommargin); } else { - rpath.lineTo(i, yval); + as[i] *= (double)(hvec[hv] - topmargin - bottommargin); + } + + if (peakshape > 0) { + taus[i] /= (double)maxscan - ((double)minscan - 1.0); + taus[i] *= (double)(w - leftmargin - rightmargin); } } - scene->addPath(rpath, QPen(Qt::gray, 1, Qt::SolidLine)); - } + const int step = 1; - if (as.size() == taus.size()) { + int xmin = getXPositionFromScanID(minscan - 1.0, w); + int xmax = getXPositionFromScanID(maxscan, w); - QPainterPath rpath2; + double relint; + int yval; - if (peakshape > 0) { + QPainterPath rpath; + + if (peakshape == 0) { for (int i = xmin; i < xmax; i += step) { relint = 0; for (int j = 0; j < (int)as.size(); j++) { - relint += computeExponentiallyModifiedGaussFunction((double)i, as[j], nys[j], sigmas[j], taus[j], fronting); + relint += computeGaussFunction((double)i, as[j], nys[j], sigmas[j]); } - yval = h - topmargin - bottommargin - (int)relint; + yval = hvec[hv] - topmargin - bottommargin - (int)relint; if (i == xmin) { - rpath2.moveTo(i, yval); + rpath.moveTo(i, yval); } else { - rpath2.lineTo(i, yval); + rpath.lineTo(i, yval); } } - scene->addPath(rpath2, QPen(Qt::gray, 1, Qt::SolidLine)); + scene->addPath(rpath, QPen(Qt::gray, 1, Qt::SolidLine)); } - //if (taus.size() == bases.size()) { + if (as.size() == taus.size()) { + + QPainterPath rpath2; + + if (peakshape > 0) { + for (int i = xmin; i < xmax; i += step) { + relint = 0; + + for (int j = 0; j < (int)as.size(); j++) { + relint += computeExponentiallyModifiedGaussFunction((double)i, as[j], nys[j], sigmas[j], taus[j], fronting); + } + + yval = hvec[hv] - topmargin - bottommargin - (int)relint; + + if (i == xmin) { + rpath2.moveTo(i, yval); + } + else { + rpath2.lineTo(i, yval); + } + } + + scene->addPath(rpath2, QPen(Qt::gray, 1, Qt::SolidLine)); + } + + //if (taus.size() == bases.size()) { - // QPainterPath rpath3; + // QPainterPath rpath3; - // for (int i = xmin; i < xmax; i += step) { - // relint = 0; + // for (int i = xmin; i < xmax; i += step) { + // relint = 0; - // for (int j = 0; j < (int)taus.size(); j++) { - // relint += ynorm * taus[j] * computeExponentialFunction((double)i /** log(bases[j])*/, econst, taus[j], fronting); - // } + // for (int j = 0; j < (int)taus.size(); j++) { + // relint += ynorm * taus[j] * computeExponentialFunction((double)i /** log(bases[j])*/, econst, taus[j], fronting); + // } - // yval = h - topmargin - bottommargin - (int)relint; + // yval = hvec[hv] - topmargin - bottommargin - (int)relint; - // if (i == xmin) { - // rpath3.moveTo(i, yval); - // } - // else { - // rpath3.lineTo(i, yval); - // } - // } + // if (i == xmin) { + // rpath3.moveTo(i, yval); + // } + // else { + // rpath3.lineTo(i, yval); + // } + // } - // scene->addPath(rpath3, QPen(Qt::blue, 1, Qt::SolidLine)); + // scene->addPath(rpath3, QPen(Qt::blue, 1, Qt::SolidLine)); - //} + //} + + } } diff --git a/CycloBranch/gui/cDefineCalibrationWidget.cpp b/CycloBranch/gui/cDefineCalibrationWidget.cpp index 5a7c715..84af969 100644 --- a/CycloBranch/gui/cDefineCalibrationWidget.cpp +++ b/CycloBranch/gui/cDefineCalibrationWidget.cpp @@ -31,12 +31,14 @@ cDefineCalibrationWidget::cDefineCalibrationWidget() { datatypelabel = new QLabel("Data Type: "); grouplabel = new QLabel("Group: "); concentrationlabel = new QLabel("Concentration: "); + timelabel = new QLabel("Time: "); filelistwidget->setLayout(gridlayout); compoundslabel = new QLabel("Ion Types: "); compoundslist = new QListWidget(); compoundslist->setSelectionMode(QAbstractItemView::MultiSelection); + compoundslist->setMinimumHeight(250); compoundslayout = new QVBoxLayout(); compoundswidget = new QWidget(); @@ -135,6 +137,7 @@ cDefineCalibrationWidget::cDefineCalibrationWidget() { internaldatatypesvector.clear(); internalgroupsvector.clear(); internalconcentrationsvector.clear(); + internaltimesvector.clear(); internalcompounds.clear(); internalselectedionsvector.clear(); @@ -154,6 +157,7 @@ cDefineCalibrationWidget::~cDefineCalibrationWidget() { delete datatypelabel; delete grouplabel; delete concentrationlabel; + delete timelabel; for (auto& it : checkboxes) { delete it; @@ -167,7 +171,7 @@ cDefineCalibrationWidget::~cDefineCalibrationWidget() { delete it; } - for (auto& it : spinboxes) { + for (auto& it : groupnames) { delete it; } @@ -175,6 +179,10 @@ cDefineCalibrationWidget::~cDefineCalibrationWidget() { delete it; } + for (auto& it : timespinboxes) { + delete it; + } + delete gridlayout; delete filelistwidget; @@ -216,8 +224,9 @@ void cDefineCalibrationWidget::store(ofstream& os) { storeIntVector(internalusedvector, os); storeStringVector(internalfilenames, os); storeIntVector(internaldatatypesvector, os); - storeIntVector(internalgroupsvector, os); + storeStringVector(internalgroupsvector, os); storeDoubleVector(internalconcentrationsvector, os); + storeIntVector(internaltimesvector, os); storeStringVector(internalcompounds, os); storeIntVector(internalselectedionsvector, os); @@ -238,7 +247,19 @@ void cDefineCalibrationWidget::load(ifstream& is, int fileversionpart1, int file if (isCompatibleVersion(fileversionpart1, fileversionpart2, fileversionpart3, 2, 1, 18)) { loadIntVector(internaldatatypesvector, is); - loadIntVector(internalgroupsvector, is); + + if (isCompatibleVersion(fileversionpart1, fileversionpart2, fileversionpart3, 2, 1, 27)) { + loadStringVector(internalgroupsvector, is); + } + else { + vector tmpgroupsvector; + loadIntVector(tmpgroupsvector, is); + + internalgroupsvector.clear(); + for (auto it : tmpgroupsvector) { + internalgroupsvector.push_back(to_string(it)); + } + } } else { internaldatatypesvector.clear(); @@ -254,6 +275,14 @@ void cDefineCalibrationWidget::load(ifstream& is, int fileversionpart1, int file loadDoubleVector(internalconcentrationsvector, is); + if (isCompatibleVersion(fileversionpart1, fileversionpart2, fileversionpart3, 2, 1, 25)) { + loadIntVector(internaltimesvector, is); + } + else { + internaltimesvector.clear(); + internaltimesvector.resize(internalusedvector.size(), 0); + } + loadStringVector(internalcompounds, is); loadIntVector(internalselectedionsvector, is); @@ -287,6 +316,7 @@ void cDefineCalibrationWidget::prepareWidget(vector& filenames, vector& filenames, vector& filenames, vector& filenames, vectorsetLayout(gridlayout); @@ -342,14 +393,16 @@ void cDefineCalibrationWidget::prepareWidget(vector& filenames, vectoraddWidget(uselabel, 0, 0, 1, 1); gridlayout->addWidget(filelabel, 0, 1, 1, 10); gridlayout->addWidget(datatypelabel, 0, 11, 1, 2); - gridlayout->addWidget(grouplabel, 0, 13, 1, 1); - gridlayout->addWidget(concentrationlabel, 0, 14, 1, 1); + gridlayout->addWidget(grouplabel, 0, 13, 1, 10); + gridlayout->addWidget(concentrationlabel, 0, 23, 1, 1); + gridlayout->addWidget(timelabel, 0, 24, 1, 1); int size = (int)filenames.size(); for (int i = 0; i < size; i++) { @@ -369,12 +422,10 @@ void cDefineCalibrationWidget::prepareWidget(vector& filenames, vectorsetToolTip("Enter a number. Items with the same number form a group of technical replicates and the results are averaged."); - spinbox->setRange(0, 1000000); - spinbox->setSingleStep(1); - spinboxes.push_back(spinbox); - spinbox->setValue((int)spinboxes.size()); + QLineEdit* groupname = new QLineEdit(); + groupname->setText(QVariant(i + 1).toString()); + groupname->setToolTip("Enter a group name. Rows with the same group name form a group of technical replicates and the results are averaged."); + groupnames.push_back(groupname); QDoubleSpinBox* doublespinbox = new QDoubleSpinBox(); doublespinbox->setToolTip("Enter the concentration of compound in corresponding dataset. Units are dataset dependent. Multiple datasets can have the same value (results are averaged)."); @@ -383,25 +434,35 @@ void cDefineCalibrationWidget::prepareWidget(vector& filenames, vectorsetSingleStep(1); doublespinboxes.push_back(doublespinbox); + QSpinBox* timespinbox = new QSpinBox(); + timespinbox->setToolTip("Enter a number representing time. Items with the same number form a group of technical replicates and the results are averaged."); + timespinbox->setRange(0, 1000000000); + timespinbox->setSingleStep(1); + timespinboxes.push_back(timespinbox); + timespinbox->setValue(0); + doublespinbox->setDisabled(true); gridlayout->addWidget(checkbox, i + 1, 0, 1, 1); gridlayout->addWidget(lineedit, i + 1, 1, 1, 10); gridlayout->addWidget(combobox, i + 1, 11, 1, 2); - gridlayout->addWidget(spinbox, i + 1, 13, 1, 1); - gridlayout->addWidget(doublespinbox, i + 1, 14, 1, 1); + gridlayout->addWidget(groupname, i + 1, 13, 1, 10); + gridlayout->addWidget(doublespinbox, i + 1, 23, 1, 1); + gridlayout->addWidget(timespinbox, i + 1, 24, 1, 1); - if (load) { + if (loadfiles) { checkbox->setChecked(internalusedvector[i]); combobox->setCurrentIndex(internaldatatypesvector[i]); - spinbox->setValue(internalgroupsvector[i]); + groupname->setText(internalgroupsvector[i].c_str()); doublespinbox->setValue(internalconcentrationsvector[i]); + timespinbox->setValue(internaltimesvector[i]); } else { internalusedvector.push_back(checkbox->isChecked()); internaldatatypesvector.push_back(combobox->currentIndex()); - internalgroupsvector.push_back(spinbox->value()); + internalgroupsvector.push_back(groupname->text().toStdString()); internalconcentrationsvector.push_back(doublespinbox->value()); + internaltimesvector.push_back(timespinbox->value()); } } @@ -414,7 +475,7 @@ void cDefineCalibrationWidget::prepareWidget(vector& filenames, vectoraddItem(compounds[i].c_str()); - if (load) { + if (loadfiles && loadcompounds) { compoundslist->item(i)->setSelected(internalselectedionsvector[i]); } else { @@ -433,11 +494,12 @@ void cDefineCalibrationWidget::prepareWidget(vector& filenames, vector& usedvector, vector& datatypesvector, vector& groupsvector, vector& concentrationsvector, vector& selectedionsvector, int& equationtype, double& manuala, double& manualb, int& eictype, int& peakshape, int& standard) { +void cDefineCalibrationWidget::getData(vector& usedvector, vector& datatypesvector, vector& groupsvector, vector& concentrationsvector, vector& timesvector, vector& selectedionsvector, int& equationtype, double& manuala, double& manualb, int& eictype, int& peakshape, int& standard) { usedvector = internalusedvector; datatypesvector = internaldatatypesvector; groupsvector = internalgroupsvector; concentrationsvector = internalconcentrationsvector; + timesvector = internaltimesvector; selectedionsvector = internalselectedionsvector; equationtype = internalequationtype; @@ -470,6 +532,10 @@ void cDefineCalibrationWidget::okButtonReleased() { int firstvalue = -1; bool allzeros = true; int size; + string groupname; + int timeval; + + map grouptime; if (equationcombobox->currentIndex() < 2) { @@ -509,6 +575,39 @@ void cDefineCalibrationWidget::okButtonReleased() { } + size = (int)checkboxes.size(); + for (int i = 0; i < size; i++) { + if (checkboxes[i]->isChecked() && (comboboxes[i]->currentIndex() == 0)) { + groupname = groupnames[i]->text().toStdString(); + timeval = timespinboxes[i]->value(); + + if (groupname.empty()) { + QMessageBox msgBox; + QString errstr = "The group name in the row no. "; + errstr += QVariant(i + 1).toString(); + errstr += " cannot be empty !"; + msgBox.setText(errstr); + msgBox.exec(); + return; + } + + if (grouptime.count(groupname) == 0) { + grouptime[groupname] = timeval; + } + else { + if (grouptime[groupname] != timeval) { + QMessageBox msgBox; + QString errstr = "The data files in the group "; + errstr += groupname.c_str(); + errstr += " must have the same collection time value !"; + msgBox.setText(errstr); + msgBox.exec(); + return; + } + } + } + } + allzeros = true; size = (int)compoundslist->count(); @@ -532,14 +631,16 @@ void cDefineCalibrationWidget::okButtonReleased() { internaldatatypesvector.clear(); internalgroupsvector.clear(); internalconcentrationsvector.clear(); + internaltimesvector.clear(); size = (int)lineedits.size(); for (int i = 0; i < size; i++) { internalusedvector.push_back(checkboxes[i]->isChecked()); internalfilenames.push_back(lineedits[i]->text().toStdString()); internaldatatypesvector.push_back(comboboxes[i]->currentIndex()); - internalgroupsvector.push_back(spinboxes[i]->value()); + internalgroupsvector.push_back(groupnames[i]->text().toStdString()); internalconcentrationsvector.push_back(doublespinboxes[i]->value()); + internaltimesvector.push_back(timespinboxes[i]->value()); } internalcompounds.clear(); @@ -570,8 +671,9 @@ void cDefineCalibrationWidget::cancelButtonReleased() { checkboxes[i]->setChecked(internalusedvector[i]); lineedits[i]->setText(internalfilenames[i].c_str()); comboboxes[i]->setCurrentIndex(internaldatatypesvector[i]); - spinboxes[i]->setValue(internalgroupsvector[i]); + groupnames[i]->setText(internalgroupsvector[i].c_str()); doublespinboxes[i]->setValue(internalconcentrationsvector[i]); + timespinboxes[i]->setValue(internaltimesvector[i]); } compoundslist->clear(); @@ -607,13 +709,15 @@ void cDefineCalibrationWidget::dataTypeChanged(int index) { } if (index == 0) { - spinboxes[row]->setDisabled(false); + groupnames[row]->setDisabled(false); doublespinboxes[row]->setDisabled(true); + timespinboxes[row]->setDisabled(false); } if (index == 1) { - spinboxes[row]->setDisabled(true); + groupnames[row]->setDisabled(true); doublespinboxes[row]->setDisabled(false); + timespinboxes[row]->setDisabled(true); } } diff --git a/CycloBranch/gui/cDefineCalibrationWidget.h b/CycloBranch/gui/cDefineCalibrationWidget.h index 4323286..68ad75b 100644 --- a/CycloBranch/gui/cDefineCalibrationWidget.h +++ b/CycloBranch/gui/cDefineCalibrationWidget.h @@ -89,8 +89,9 @@ class cDefineCalibrationWidget : public QWidget \brief Get data from dialog. \param usedvector vector of used items \param datatypesvector vector of sample types - \param groupsvector vector of groups of technical replicates + \param groupsvector vector of groups of names of technical replicates \param concentrationsvector vector of concentrations + \param timesvector vector of time values \param selectedionsvector vector of selected ions \param equationtype type of linear equation (y = a*x, y = a*x + b or manual mode) \param manuala the parameter 'a' in manual mode @@ -99,7 +100,7 @@ class cDefineCalibrationWidget : public QWidget \param peakshape shape of chromatographic peak \param standard compound standard */ - void getData(vector& usedvector, vector& datatypesvector, vector& groupsvector, vector& concentrationsvector, vector& selectedionsvector, int& equationtype, double& manuala, double& manualb, int& eictype, int& peakshape, int& standard); + void getData(vector& usedvector, vector& datatypesvector, vector& groupsvector, vector& concentrationsvector, vector& timesvector, vector& selectedionsvector, int& equationtype, double& manuala, double& manualb, int& eictype, int& peakshape, int& standard); private: @@ -118,12 +119,14 @@ class cDefineCalibrationWidget : public QWidget QLabel* grouplabel; QLabel* datatypelabel; QLabel* concentrationlabel; + QLabel* timelabel; vector checkboxes; vector lineedits; vector comboboxes; - vector spinboxes; + vector groupnames; vector doublespinboxes; + vector timespinboxes; QLabel* compoundslabel; QListWidget* compoundslist; @@ -148,8 +151,9 @@ class cDefineCalibrationWidget : public QWidget vector internalusedvector; vector internalfilenames; vector internaldatatypesvector; - vector internalgroupsvector; + vector internalgroupsvector; vector internalconcentrationsvector; + vector internaltimesvector; vector internalcompounds; vector internalselectedionsvector; diff --git a/CycloBranch/gui/cMainWindow.cpp b/CycloBranch/gui/cMainWindow.cpp index 1cb1814..c2e85f4 100644 --- a/CycloBranch/gui/cMainWindow.cpp +++ b/CycloBranch/gui/cMainWindow.cpp @@ -383,6 +383,8 @@ cMainWindow::cMainWindow() { connect(chromatogramwindow, SIGNAL(doubleClickedScanIDSignal(int)), this, SLOT(chromatogramDoubleClicked(int))); connect(imagewindow, SIGNAL(doubleClickedSpectrumIDSignal(int)), this, SLOT(imageWindowDoubleClicked(int))); + connect(chromatogramwindow, SIGNAL(calculateAvgSpectrum(int, int)), this, SLOT(showAvgSpectrum(int, int))); + menuFile->addAction(actionOpenResults); menuFile->addAction(actionSaveResults); menuFile->addSeparator(); @@ -487,6 +489,7 @@ cMainWindow::cMainWindow() { listoftheoreticalspectra.clear(); eicchromatograms.clear(); spectradetails.clear(); + avgspectra.clear(); parameters.clear(); @@ -495,7 +498,7 @@ cMainWindow::cMainWindow() { profilemz64precision = false; profileintensity64precision = false; - resultsbasecolumncount = 10; + resultsbasecolumncount = 11; resultsspecificcolumncount = 0; searchspecificcolumncount = 0; @@ -505,7 +508,7 @@ cMainWindow::cMainWindow() { multipledatasetsisprepared = false; lastactivedetail = -1; - + othernormalgeometry = QRect(); otherismaximized = false; otherprofilespectrum = false; @@ -518,6 +521,11 @@ cMainWindow::cMainWindow() { activefileid = 0; + avgspectrumused = -1; + avgspectrumabsoluteintensityenabled = true; + avgspectrumgeometry = QRect(); + avgspectrummaximized = false; + quitapp = false; } @@ -690,6 +698,9 @@ void cMainWindow::reportSpectrum(int row, cTheoreticalSpectrum& theoreticalspect string peptidesequence; cSummaryFormula formula; + string scantitle; + scantitle.clear(); + resultsmodel->setItem(row, 0, new QStandardItem()); resultsmodel->item(row, 0)->setText(""); @@ -769,6 +780,9 @@ void cMainWindow::reportSpectrum(int row, cTheoreticalSpectrum& theoreticalspect resultsmodel->setItem(row, 9 + searchspecificcolumncount + resultsspecificcolumncount, new QStandardItem()); resultsmodel->item(row, 9 + searchspecificcolumncount + resultsspecificcolumncount)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(theoreticalspectrum.getWeightedRatioOfMatchedPeaks() * 100)), Qt::DisplayRole); + resultsmodel->setItem(row, 10 + searchspecificcolumncount + resultsspecificcolumncount, new QStandardItem()); + resultsmodel->item(row, 10 + searchspecificcolumncount + resultsspecificcolumncount)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(theoreticalspectrum.getCosineSimilarity())), Qt::DisplayRole); + int index = resultsbasecolumncount + searchspecificcolumncount + resultsspecificcolumncount; for (int i = 0; i < (int)parameters.ionsfortheoreticalspectraMS2.size(); i++) { for (int j = -1; j < (int)parameters.neutrallossesfortheoreticalspectra.size(); j++) { @@ -805,6 +819,7 @@ void cMainWindow::reportSpectrum(int row, cTheoreticalSpectrum& theoreticalspect resultsmodel->setItem(row, mscol, new QStandardItem()); resultsmodel->item(row, mscol)->setText(theoreticalspectrum.getExperimentalSpectrum().getTitle().c_str()); + scantitle = theoreticalspectrum.getExperimentalSpectrum().getTitle(); mscol++; resultsmodel->setItem(row, mscol, new QStandardItem()); @@ -823,6 +838,10 @@ void cMainWindow::reportSpectrum(int row, cTheoreticalSpectrum& theoreticalspect resultsmodel->item(row, mscol)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(theoreticalspectrum.getWeightedRatioOfMatchedPeaks() * 100)), Qt::DisplayRole); mscol++; + //resultsmodel->setItem(row, mscol, new QStandardItem()); + //resultsmodel->item(row, mscol)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(theoreticalspectrum.getCosineSimilarity())), Qt::DisplayRole); + //mscol++; + if ((parameters.peaklistfileformats[activefileid] == mis) || (parameters.peaklistfileformats[activefileid] == imzML)) { resultsmodel->setItem(row, mscol, new QStandardItem()); resultsmodel->item(row, mscol)->setData(QVariant::fromValue(theoreticalspectrum.getExperimentalSpectrum().getCoordinateX()), Qt::DisplayRole); @@ -834,12 +853,276 @@ void cMainWindow::reportSpectrum(int row, cTheoreticalSpectrum& theoreticalspect } - spectradetails[row].initialize(row + 1, activefileid, &globalpreferences, ¶meters, theoreticalspectrum, this); + spectradetails[row].initialize(row + 1, scantitle, activefileid, &globalpreferences, ¶meters, theoreticalspectrum, this); connect(&spectradetails[row], SIGNAL(lastActiveDetail(int)), this, SLOT(lastActiveDetailSlot(int))); } +void cMainWindow::calculateAvgSpectrum(int minscan, int maxscan) { + int numberofspectra = maxscan - minscan + 1; + if (numberofspectra <= 0) { + return; + } + + cPeaksList averagespectrum; + for (int i = minscan - 1; i < maxscan; i++) { + averagespectrum.attach(listoftheoreticalspectra.get(activefileid, i).getExperimentalSpectrum()); + } + + int asize = averagespectrum.size(); + + QProgressDialog progress("Calculating average spectrum...", /*"Cancel"*/0, 0, 3 * asize, this); + progress.setMinimumWidth(250); + cEventFilter filter; + progress.installEventFilter(&filter); + progress.setMinimumDuration(0); + progress.setWindowModality(Qt::ApplicationModal); + progress.setValue(0); + + bool quadraticapproach = false; + + if (quadraticapproach) { + + averagespectrum.sortbyAbsoluteIntensityDesc(); + + // initialize clusters + vector clusters; + clusters.resize(averagespectrum.size()); + for (int i = 0; i < asize; i++) { + clusters[i].add(averagespectrum[i]); + + if (i % 100 == 0) { + progress.setValue(i); + } + } + + // merge clusters + size_t csize = clusters.size(); + for (int i = 0; i < csize; i++) { + if ((asize + i) % 100 == 0) { + progress.setValue(asize + i); + } + + if (clusters[i].size() == 0) { + continue; + } + for (int j = i + 1; j < csize; j++) { + if (clusters[j].size() == 0) { + continue; + } + if (isInPpmMassErrorTolerance(clusters[i][0].mzratio, clusters[j][0].mzratio, parameters.fragmentmasserrortolerance)) { + clusters[i].add(clusters[j][0]); + clusters[j].clear(); + } + } + } + + // reduce peaks + averagespectrum.clear(); + double relsum; + int isize; + for (int i = 0; i < csize; i++) { + if ((2 * asize + i) % 100 == 0) { + progress.setValue(2 * asize + i); + } + + isize = clusters[i].size(); + + if (isize == 0) { + continue; + } + + cPeak peak; + relsum = 0; + + for (int j = 0; j < isize; j++) { + relsum += clusters[i][j].absoluteintensity; + } + + for (int j = 0; j < isize; j++) { + peak.mzratio += clusters[i][j].mzratio*clusters[i][j].absoluteintensity; + peak.absoluteintensity += clusters[i][j].absoluteintensity; + } + + peak.mzratio /= relsum; + + averagespectrum.add(peak); + } + + } + else { + + // initialize clusters + vector clusters; + clusters.reserve(averagespectrum.size()); + + averagespectrum.sortbyMass(); + averagespectrum.fillOrderIDs(); + + cPeaksList outer = averagespectrum; + outer.sortbyAbsoluteIntensityDesc(); + + cPeaksList tmplist; + + int isize = outer.size(); + int j; + + // merge clusters + for (int i = 0; i < isize; i++) { + if (averagespectrum[outer[i].orderid].orderid == -1) { + continue; + } + + tmplist.clear(); + + tmplist.add(averagespectrum[outer[i].orderid]); + averagespectrum[outer[i].orderid].orderid = -1; + + j = outer[i].orderid + 1; + while (j < isize) { + if (isInPpmMassErrorTolerance(averagespectrum[outer[i].orderid].mzratio, averagespectrum[j].mzratio, parameters.fragmentmasserrortolerance)) { + if (averagespectrum[j].orderid != -1) { + tmplist.add(averagespectrum[j]); + averagespectrum[j].orderid = -1; + } + } + else { + break; + } + j++; + } + + j = outer[i].orderid - 1; + while (j >= 0) { + if (isInPpmMassErrorTolerance(averagespectrum[outer[i].orderid].mzratio, averagespectrum[j].mzratio, parameters.fragmentmasserrortolerance)) { + if (averagespectrum[j].orderid != -1) { + tmplist.add(averagespectrum[j]); + averagespectrum[j].orderid = -1; + } + } + else { + break; + } + j--; + } + + clusters.push_back(tmplist); + } + + progress.setValue(asize); + + // reduce peaks + averagespectrum.clear(); + double relsum; + int csize = (int)clusters.size(); + for (int i = 0; i < csize; i++) { + isize = clusters[i].size(); + + if (isize == 0) { + continue; + } + + cPeak peak; + relsum = 0; + + for (int j = 0; j < isize; j++) { + relsum += clusters[i][j].absoluteintensity; + } + + for (int j = 0; j < isize; j++) { + peak.mzratio += clusters[i][j].mzratio*clusters[i][j].absoluteintensity; + peak.absoluteintensity += clusters[i][j].absoluteintensity; + } + + peak.mzratio /= relsum; + + averagespectrum.add(peak); + } + + progress.setValue(2 * asize); + + } + + averagespectrum.sortbyMass(); + averagespectrum.normalizeIntenzity(); + + averagespectrum.cropRelativeIntenzity(parameters.minimumrelativeintensitythreshold); + + QRect geometry; + bool usegeometry = false; + bool ismaximized = false; + + if (avgspectra.size() > 0) { + geometry = avgspectra[0].normalGeometry(); + usegeometry = true; + ismaximized = avgspectra[0].isMaximized(); + } + else { + if (avgspectrumused >= 0) { + geometry = avgspectrumgeometry; + usegeometry = true; + ismaximized = avgspectrummaximized; + } + } + + avgspectra.clear(); + avgspectra.resize(1); + + cTheoreticalSpectrum tsfull; + tsfull.setParameters(¶meters); + + bool terminatecomputation = false; + if (parameters.generateisotopepattern) { + if (parameters.calculatefdrs) { + tsfull.generateFineMSSpectrum(0, parameters.sequencedatabase.size() / 2, terminatecomputation); + } + else { + tsfull.generateFineMSSpectrum(0, parameters.sequencedatabase.size(), terminatecomputation); + } + } + else { + tsfull.generateMSSpectrum(0, parameters.sequencedatabase.size(), terminatecomputation, true); + } + + cTheoreticalSpectrum tsaverage; + cPeaksList unmatchedpeaksinmatchedpatterns; + tsaverage.setParameters(¶meters); + tsaverage.compareAverageMSSpectrum(averagespectrum, tsfull, unmatchedpeaksinmatchedpatterns); + tsaverage.finalizeMSSpectrum(unmatchedpeaksinmatchedpatterns, true); + + string scantitle; + avgspectra[0].initialize(1, scantitle, activefileid, &globalpreferences, ¶meters, tsaverage, this); + avgspectra[0].prepareToShow(actionShowIsomers, &rawdata, &imzmlprofilemetadata, profilemz64precision, profileintensity64precision, true); + + string title = "Average Spectrum " + to_string(minscan) + " - " + to_string(maxscan); + avgspectra[0].setWindowTitle(title.c_str()); + avgspectra[0].setAbsoluteIntensityEnabled(avgspectrumabsoluteintensityenabled); + avgspectra[0].disableProfileMode(); + + progress.setValue(3 * asize); + + chromatogramwindow->activateWindow(); + + if (usegeometry) { + avgspectra[0].setGeometry(geometry); + } + + if (ismaximized) { + avgspectra[0].showMaximized(); + } + else { + avgspectra[0].showNormal(); + } + + connect(&avgspectra[0], SIGNAL(absoluteIntensityStateChangedSignal(bool)), this, SLOT(avgSpectrumAbsoluteIntensityStateChanged(bool))); + + avgspectrumused = 0; + avgspectrummaximized = avgspectra[0].isMaximized(); + avgspectrumgeometry = avgspectra[0].normalGeometry(); +} + + void cMainWindow::showHideLog() { bool state = logWindow->isVisible(); @@ -1023,6 +1306,14 @@ void cMainWindow::run() { eicchromatograms.clear(); spectradetails.clear(); + if (avgspectra.size() > 0) { + avgspectrumused = 0; + avgspectrummaximized = avgspectra[0].isMaximized(); + avgspectrumgeometry = avgspectra[0].normalGeometry(); + } + + avgspectra.clear(); + parameters.clear(); rawdata.clear(); @@ -1393,7 +1684,6 @@ void cMainWindow::reportSpectra() { resultsmodel->setHorizontalHeaderItem(7 + searchspecificcolumncount, new QStandardItem()); resultsmodel->horizontalHeaderItem(7 + searchspecificcolumncount)->setText("Right Terminal Modification"); results->setItemDelegateForColumn(7 + searchspecificcolumncount, new QItemDelegate()); - break; case other: break; @@ -1417,6 +1707,10 @@ void cMainWindow::reportSpectra() { resultsmodel->horizontalHeaderItem(9 + searchspecificcolumncount + resultsspecificcolumncount)->setText("Weighted Ratio of Matched Peaks [%]"); results->setItemDelegateForColumn(9 + searchspecificcolumncount + resultsspecificcolumncount, new QItemDelegate()); + resultsmodel->setHorizontalHeaderItem(10 + searchspecificcolumncount + resultsspecificcolumncount, new QStandardItem()); + resultsmodel->horizontalHeaderItem(10 + searchspecificcolumncount + resultsspecificcolumncount)->setText("Cosine Similarity"); + results->setItemDelegateForColumn(10 + searchspecificcolumncount + resultsspecificcolumncount, new QItemDelegate()); + string name; int index = resultsbasecolumncount + searchspecificcolumncount + resultsspecificcolumncount; for (int i = 0; i < (int)parameters.ionsfortheoreticalspectraMS2.size(); i++) { @@ -1444,10 +1738,10 @@ void cMainWindow::reportSpectra() { if ((parameters.mode == dereplication) || (parameters.mode == compoundsearch)) { if ((parameters.peaklistfileformats[activefileid] == mis) || (parameters.peaklistfileformats[activefileid] == imzML)) { - resultsmodel->setColumnCount(9); + resultsmodel->setColumnCount(/*10*/9); } else { - resultsmodel->setColumnCount(8); + resultsmodel->setColumnCount(/*9*/8); } int mscol = 0; @@ -1494,6 +1788,11 @@ void cMainWindow::reportSpectra() { results->setItemDelegateForColumn(mscol, new QItemDelegate()); mscol++; + //resultsmodel->setHorizontalHeaderItem(mscol, new QStandardItem()); + //resultsmodel->horizontalHeaderItem(mscol)->setText("Cosine Similarity"); + //results->setItemDelegateForColumn(mscol, new QItemDelegate()); + //mscol++; + if ((parameters.peaklistfileformats[activefileid] == mis) || (parameters.peaklistfileformats[activefileid] == imzML)) { resultsmodel->setHorizontalHeaderItem(mscol, new QStandardItem()); resultsmodel->horizontalHeaderItem(mscol)->setText("Coordinate X"); @@ -1583,6 +1882,14 @@ void cMainWindow::reportSpectra() { //} } + if (avgspectra.size() > 0) { + avgspectrumused = 0; + avgspectrummaximized = avgspectra[0].isMaximized(); + avgspectrumgeometry = avgspectra[0].normalGeometry(); + } + + avgspectra.clear(); + resultsproxymodel->setSourceModel(resultsmodel); results->setModel(resultsproxymodel); results->setSortingEnabled(true); @@ -2510,6 +2817,14 @@ void cMainWindow::openResultsFile() { eicchromatograms.clear(); spectradetails.clear(); + if (avgspectra.size() > 0) { + avgspectrumused = 0; + avgspectrummaximized = avgspectra[0].isMaximized(); + avgspectrumgeometry = avgspectra[0].normalGeometry(); + } + + avgspectra.clear(); + lastactivedetail = -1; othernormalgeometry = QRect(); @@ -2883,6 +3198,14 @@ void cMainWindow::inputFilterButtonReleased() { spectradetails.clear(); + if (avgspectra.size() > 0) { + avgspectrumused = 0; + avgspectrummaximized = avgspectra[0].isMaximized(); + avgspectrumgeometry = avgspectra[0].normalGeometry(); + } + + avgspectra.clear(); + rawdata.clear(); activefileid = inputfiltercombobox->currentIndex(); @@ -2909,6 +3232,16 @@ void cMainWindow::filterSummaryTableIfPrepared() { } +void cMainWindow::showAvgSpectrum(int minscan, int maxscan) { + calculateAvgSpectrum(minscan, maxscan); +} + + +void cMainWindow::avgSpectrumAbsoluteIntensityStateChanged(bool state) { + avgspectrumabsoluteintensityenabled = state; +} + + /* void cMainWindow::showContextMenu(const QPoint &pt) { QMenu *menu = logWindow->createStandardContextMenu(); diff --git a/CycloBranch/gui/cMainWindow.h b/CycloBranch/gui/cMainWindow.h index 5adab0b..02baa2f 100644 --- a/CycloBranch/gui/cMainWindow.h +++ b/CycloBranch/gui/cMainWindow.h @@ -158,6 +158,7 @@ class cMainWindow : public QMainWindow cTheoreticalSpectrumList listoftheoreticalspectra; cPeakListSeries eicchromatograms; vector spectradetails; + vector avgspectra; cGlobalPreferences globalpreferences; cParameters parameters; @@ -213,6 +214,11 @@ class cMainWindow : public QMainWindow int activefileid; + int avgspectrumused; + bool avgspectrumabsoluteintensityenabled; + QRect avgspectrumgeometry; + bool avgspectrummaximized; + bool quitapp; void closeEvent(QCloseEvent *event); @@ -227,6 +233,8 @@ class cMainWindow : public QMainWindow void openDetail(int rowid); + void calculateAvgSpectrum(int minscan, int maxscan); + private slots: @@ -350,6 +358,10 @@ private slots: void filterSummaryTableIfPrepared(); + void showAvgSpectrum(int minscan, int maxscan); + + void avgSpectrumAbsoluteIntensityStateChanged(bool state); + //void showContextMenu(const QPoint &pt); signals: diff --git a/CycloBranch/gui/cMultipleDatasetsTableProxyModel.cpp b/CycloBranch/gui/cMultipleDatasetsTableProxyModel.cpp index bcb2654..ddfa59b 100644 --- a/CycloBranch/gui/cMultipleDatasetsTableProxyModel.cpp +++ b/CycloBranch/gui/cMultipleDatasetsTableProxyModel.cpp @@ -18,6 +18,16 @@ bool cMultipleDatasetsTableProxyModel::lessThan(const QModelIndex &left, const Q return (sortOrder() == Qt::AscendingOrder) ? true : false; } + if (leftData.type() != rightData.type()) { + if (leftData.type() == QVariant::String) { + return (sortOrder() == Qt::AscendingOrder) ? false : true; + } + + if (rightData.type() == QVariant::String) { + return (sortOrder() == Qt::AscendingOrder) ? true : false; + } + } + if (leftData.type() == QVariant::ByteArray) { return leftData.toDouble() < rightData.toDouble(); } diff --git a/CycloBranch/gui/cMultipleDatasetsTableWidget.cpp b/CycloBranch/gui/cMultipleDatasetsTableWidget.cpp index 07b2ea9..70f3dde 100644 --- a/CycloBranch/gui/cMultipleDatasetsTableWidget.cpp +++ b/CycloBranch/gui/cMultipleDatasetsTableWidget.cpp @@ -237,7 +237,7 @@ cMultipleDatasetsTableWidget::cMultipleDatasetsTableWidget(cGlobalPreferences* g datatypelabel->setText("View: "); comboboxdatatype = new QComboBox(); - comboboxdatatype->setToolTip("Select data to be displayed."); + comboboxdatatype->setToolTip("Select the data to be displayed."); comboboxdatatype->setSizeAdjustPolicy(QComboBox::AdjustToContents); connect(comboboxdatatype, SIGNAL(currentIndexChanged(int)), this, SLOT(dataTypeViewChanged(int))); @@ -324,6 +324,30 @@ cMultipleDatasetsTableWidget::cMultipleDatasetsTableWidget(cGlobalPreferences* g calibrationwidget = new QWidget(); calibrationwidget->setLayout(calibrationhboxlayout); + columnsizelabel = new QLabel(); + columnsizelabel->setText("Column size: "); + + columnsizespinbox = new QSpinBox(); + columnsizespinbox->setRange(10, 1000); + columnsizespinbox->setValue(200); + columnsizespinbox->setSingleStep(10); + columnsizespinbox->setToolTip("Define the column size."); + + columnsizesetbutton = new QPushButton("Set"); + connect(columnsizesetbutton, SIGNAL(released()), this, SLOT(setColumnSize())); + + columnsizeresetbutton = new QPushButton("Reset"); + connect(columnsizeresetbutton, SIGNAL(released()), this, SLOT(resetColumnSize())); + + columnsizehboxlayout = new QHBoxLayout(); + columnsizehboxlayout->addWidget(columnsizelabel); + columnsizehboxlayout->addWidget(columnsizespinbox); + columnsizehboxlayout->addWidget(columnsizesetbutton); + columnsizehboxlayout->addWidget(columnsizeresetbutton); + + columnsizewidget = new QWidget(); + columnsizewidget->setLayout(columnsizehboxlayout); + database = new QTableView(this); databasemodel = new QStandardItemModel(0, 0, this); proxymodel = new cMultipleDatasetsTableProxyModel(this); @@ -336,6 +360,7 @@ cMultipleDatasetsTableWidget::cMultipleDatasetsTableWidget(cGlobalPreferences* g database->setEditTriggers(QAbstractItemView::NoEditTriggers); database->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); database->horizontalHeader()->setSectionsMovable(true); + database->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter | (Qt::Alignment)Qt::TextWordWrap); //database->verticalHeader()->setDefaultSectionSize(30); connect(database, SIGNAL(clicked(const QModelIndex&)), this, SLOT(rowClicked(const QModelIndex&))); @@ -381,6 +406,7 @@ cMultipleDatasetsTableWidget::cMultipleDatasetsTableWidget(cGlobalPreferences* g toolbarView->addWidget(datatypewidget); toolbarView->addWidget(peakshapewidget); toolbarView->addWidget(standardwidget); + toolbarView->addWidget(columnsizewidget); addToolBarBreak(); @@ -459,6 +485,13 @@ cMultipleDatasetsTableWidget::~cMultipleDatasetsTableWidget() { delete calibrationhboxlayout; delete calibrationwidget; + delete columnsizelabel; + delete columnsizespinbox; + delete columnsizesetbutton; + delete columnsizeresetbutton; + delete columnsizehboxlayout; + delete columnsizewidget; + delete pubchemsearchwidget; delete definecalibrationwidget; delete calibrationchartwidget; @@ -527,6 +560,7 @@ bool cMultipleDatasetsTableWidget::prepareToShow(cParameters* parameters, cTheor comboboxdatatype->addItem("Concentration - All Isotopes"); comboboxdatatype->addItem("Peak Area (Chromatogram) - Highest Peak"); comboboxdatatype->addItem("Concentration - Highest Peak"); + comboboxdatatype->addItem("Retention Time"); standardlabel->show(); comboboxstandard->show(); @@ -976,6 +1010,9 @@ bool cMultipleDatasetsTableWidget::prepareToShow(cParameters* parameters, cTheor value = -1; } break; + case 6: + value = listoftheoreticalspectra->get(i - systemcolumns, it.second[i - systemcolumns].first).getExperimentalSpectrum().getRetentionTime(); + break; default: break; } @@ -1008,6 +1045,9 @@ bool cMultipleDatasetsTableWidget::prepareToShow(cParameters* parameters, cTheor case 5: databasemodel->item(currentrow, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(value)), Qt::DisplayRole); break; + case 6: + databasemodel->item(currentrow, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(value)), Qt::DisplayRole); + break; default: break; } @@ -1415,6 +1455,9 @@ void cMultipleDatasetsTableWidget::updateTable() { value = -1; } break; + case 6: + value = listoftheoreticalspectra->get(i - systemcolumns, it.second[i - systemcolumns].first).getExperimentalSpectrum().getRetentionTime(); + break; default: break; } @@ -1444,6 +1487,9 @@ void cMultipleDatasetsTableWidget::updateTable() { case 5: databasemodel->item(currentrow, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(value)), Qt::DisplayRole); break; + case 6: + databasemodel->item(currentrow, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(value)), Qt::DisplayRole); + break; default: break; } @@ -1926,8 +1972,9 @@ void cMultipleDatasetsTableWidget::calibrationViewButtonReleased() { void cMultipleDatasetsTableWidget::calibrationCurveRedefined() { vector usedvector; vector datatypes; - vector groupsvector; + vector groupsvector; vector concentrationsvector; + vector timesvector; vector selectedionsvector; int equationtype; @@ -1937,7 +1984,7 @@ void cMultipleDatasetsTableWidget::calibrationCurveRedefined() { int peakshapetype; int standardtype; - definecalibrationwidget->getData(usedvector, datatypes, groupsvector, concentrationsvector, selectedionsvector, equationtype, manuala, manualb, eictype, peakshapetype, standardtype); + definecalibrationwidget->getData(usedvector, datatypes, groupsvector, concentrationsvector, timesvector, selectedionsvector, equationtype, manuala, manualb, eictype, peakshapetype, standardtype); comboboxdatatype->blockSignals(true); comboboxpeakshape->blockSignals(true); @@ -2018,14 +2065,16 @@ void cMultipleDatasetsTableWidget::calibrationCurveRedefined() { multimap calibrationsubareas; map calibrationcounts; - map dataareas; - multimap datasubareas; - map datacounts; + map dataareas; + multimap datasubareas; + map datacounts; + map datatimes; double stdarea; double cumarea; int c, k; + string g; for (int i = systemcolumns; i < numberofdatasets + systemcolumns; i++) { @@ -2092,6 +2141,7 @@ void cMultipleDatasetsTableWidget::calibrationCurveRedefined() { case 1: case 4: case 5: + case 6: getEICFromMultiMap(i - systemcolumns, identifieditemswithmultimap[it.first], eicchromatogram, true); calculateGaussianParameters(eicchromatogram, rtimes[i - systemcolumns], rtimeunits[i - systemcolumns], true, true, nys, sigmas, as); @@ -2157,39 +2207,42 @@ void cMultipleDatasetsTableWidget::calibrationCurveRedefined() { if (datatypes[i - systemcolumns] == 0) { - c = groupsvector[i - systemcolumns]; + g = groupsvector[i - systemcolumns]; - if (dataareas.count(c) == 0) { + if (dataareas.count(g) == 0) { if (stdarea > 0) { - dataareas[c] = cumarea / stdarea; + dataareas[g] = cumarea / stdarea; } else { - dataareas[c] = cumarea; + dataareas[g] = cumarea; } } else { if (stdarea > 0) { - dataareas[c] += cumarea / stdarea; + dataareas[g] += cumarea / stdarea; } else { - dataareas[c] += cumarea; + dataareas[g] += cumarea; } } if (stdarea > 0) { - datasubareas.insert(pair(c, cumarea / stdarea)); + datasubareas.insert(pair(g, cumarea / stdarea)); } else { - datasubareas.insert(pair(c, cumarea)); + datasubareas.insert(pair(g, cumarea)); } - if (datacounts.count(c) == 0) { - datacounts[c] = 1; + if (datacounts.count(g) == 0) { + datacounts[g] = 1; } else { - datacounts[c] += 1; + datacounts[g] += 1; } + if (datatimes.count(g) == 0) { + datatimes[g] = timesvector[i - systemcolumns]; + } } else { c = (int)(concentrationsvector[i - systemcolumns] * 1000.0); @@ -2297,7 +2350,8 @@ void cMultipleDatasetsTableWidget::calibrationCurveRedefined() { vector dataxvalues; vector datayvalues; vector datasd; - vector datagroups; + vector datagroups; + vector datatimevalues; for (auto& it : dataareas) { yvalue = it.second / (double)(datacounts[it.first]); @@ -2338,11 +2392,12 @@ void cMultipleDatasetsTableWidget::calibrationCurveRedefined() { } datagroups.push_back(it.first); + datatimevalues.push_back(datatimes[it.first]); } - calibrationchartwidget->setData(dataxvalues, datayvalues, datasd, datagroups); + calibrationchartwidget->setData(dataxvalues, datayvalues, datasd, datagroups, datatimevalues); - calibrationchartwidget->createTable(a, b, calibrationxvalues, calibrationyvalues, calibrationsd, datagroups, dataxvalues, datayvalues, datasd); + calibrationchartwidget->createTable(a, b, calibrationxvalues, calibrationyvalues, calibrationsd, datagroups, dataxvalues, datayvalues, datasd, datatimevalues); } @@ -2889,3 +2944,18 @@ void cMultipleDatasetsTableWidget::searchPubChem() { pubchemsearchwidget->showNormal(); } } + + +void cMultipleDatasetsTableWidget::setColumnSize() { + for (int i = systemcolumns; i < databasemodel->columnCount(); i++) { + database->setColumnWidth(i, columnsizespinbox->value()); + } +} + + +void cMultipleDatasetsTableWidget::resetColumnSize() { + for (int i = 0; i < databasemodel->columnCount(); i++) { + database->resizeColumnToContents(i); + } +} + diff --git a/CycloBranch/gui/cMultipleDatasetsTableWidget.h b/CycloBranch/gui/cMultipleDatasetsTableWidget.h index f539660..9eefa4c 100644 --- a/CycloBranch/gui/cMultipleDatasetsTableWidget.h +++ b/CycloBranch/gui/cMultipleDatasetsTableWidget.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -224,6 +225,13 @@ class cMultipleDatasetsTableWidget : public QMainWindow { QHBoxLayout* calibrationhboxlayout; QWidget* calibrationwidget; + QLabel* columnsizelabel; + QSpinBox* columnsizespinbox; + QPushButton* columnsizesetbutton; + QPushButton* columnsizeresetbutton; + QHBoxLayout* columnsizehboxlayout; + QWidget* columnsizewidget; + QTableView* database; QStandardItemModel* databasemodel; cMultipleDatasetsTableProxyModel* proxymodel; @@ -298,6 +306,12 @@ private slots: void searchPubChem(); + void setColumnSize(); + + + void resetColumnSize(); + + signals: diff --git a/CycloBranch/gui/cParametersWidget.cpp b/CycloBranch/gui/cParametersWidget.cpp index d1a4414..033dd9c 100644 --- a/CycloBranch/gui/cParametersWidget.cpp +++ b/CycloBranch/gui/cParametersWidget.cpp @@ -285,8 +285,18 @@ cParametersWidget::cParametersWidget(cGlobalPreferences* globalpreferences, QWid experimentalspectragridlayout->addWidget(fwhmlabel, 12, 0); experimentalspectragridlayout->addWidget(fwhm, 12, 1); + experimentalspectragroupbox = new QGroupBox("Experimental Spectrum/Spectra"); + experimentalspectragroupbox->setLayout(experimentalspectragridlayout); + + + isotoperatiosgridlayout = new QGridLayout(); + + int isotoperow = 0; + + ratio54Fe56FeEnabled = new QCheckBox(); + minratio54Fe56Fe = new QDoubleSpinBox(); - minratio54Fe56Fe->setToolTip("Enter the minimum intensity ratio of 54Fe/56Fe."); + minratio54Fe56Fe->setToolTip("Enter the minimum ratio of 54Fe/56Fe intensities.\nUse 0 if the presence of 54Fe in the spectrum is NOT mandatory."); minratio54Fe56Fe->setDecimals(3); minratio54Fe56Fe->setRange(0, 1); minratio54Fe56Fe->setSingleStep(0.01); @@ -294,26 +304,221 @@ cParametersWidget::cParametersWidget(cGlobalPreferences* globalpreferences, QWid minratio54Fe56Fe->setPrefix("minimum: "); maxratio54Fe56Fe = new QDoubleSpinBox(); - maxratio54Fe56Fe->setToolTip("Enter the maximum intensity ratio of 54Fe/56Fe."); + maxratio54Fe56Fe->setToolTip("Enter the maximum ratio of 54Fe/56Fe intensities.\nThe default value is 0.1."); maxratio54Fe56Fe->setDecimals(3); maxratio54Fe56Fe->setRange(0, 1); maxratio54Fe56Fe->setSingleStep(0.01); maxratio54Fe56Fe->setValue(0.1); maxratio54Fe56Fe->setPrefix("maximum: "); - ratio54Fe56Felayout = new QHBoxLayout(); - ratio54Fe56Felayout->addWidget(minratio54Fe56Fe); - ratio54Fe56Felayout->addWidget(maxratio54Fe56Fe); - ratio54Fe56Felayout->setMargin(0); - ratio54Fe56Fewidget = new QWidget(); - ratio54Fe56Fewidget->setLayout(ratio54Fe56Felayout); - ratio54Fe56Fewidget->setFixedWidth(leftdefaultwidth); - ratio54Fe56Felabel = new QLabel("54Fe/56Fe Ratio:"); - experimentalspectragridlayout->addWidget(ratio54Fe56Felabel, 13, 0); - experimentalspectragridlayout->addWidget(ratio54Fe56Fewidget, 13, 1); - - experimentalspectragroupbox = new QGroupBox("Experimental Spectrum/Spectra"); - experimentalspectragroupbox->setLayout(experimentalspectragridlayout); + ratio54Fe56FeLayout = new QHBoxLayout(); + ratio54Fe56FeLayout->addWidget(ratio54Fe56FeEnabled); + ratio54Fe56FeLayout->addWidget(minratio54Fe56Fe, 10); + ratio54Fe56FeLayout->addWidget(maxratio54Fe56Fe, 10); + ratio54Fe56FeLayout->setMargin(0); + ratio54Fe56FeWidget = new QWidget(); + ratio54Fe56FeWidget->setLayout(ratio54Fe56FeLayout); + ratio54Fe56FeWidget->setFixedWidth(leftdefaultwidth); + ratio54Fe56FeLabel = new QLabel("54Fe/56Fe Ratio:"); + + isotoperatiosgridlayout->addWidget(ratio54Fe56FeLabel, isotoperow, 0); + isotoperatiosgridlayout->addWidget(ratio54Fe56FeWidget, isotoperow, 1); + isotoperow++; + + ratio60Ni58NiEnabled = new QCheckBox(); + + minratio60Ni58Ni = new QDoubleSpinBox(); + minratio60Ni58Ni->setToolTip("Enter the minimum ratio of 60Ni/58Ni intensities.\nUse 0 if the presence of 60Ni in the spectrum is NOT mandatory."); + minratio60Ni58Ni->setDecimals(3); + minratio60Ni58Ni->setRange(0, 1); + minratio60Ni58Ni->setSingleStep(0.01); + minratio60Ni58Ni->setValue(0); + minratio60Ni58Ni->setPrefix("minimum: "); + + maxratio60Ni58Ni = new QDoubleSpinBox(); + maxratio60Ni58Ni->setToolTip("Enter the maximum ratio of 60Ni/58Ni intensities.\nThe default value is 0.5 (for FWHM <= 0.001 only)."); + maxratio60Ni58Ni->setDecimals(3); + maxratio60Ni58Ni->setRange(0, 1); + maxratio60Ni58Ni->setSingleStep(0.01); + maxratio60Ni58Ni->setValue(0.5); + maxratio60Ni58Ni->setPrefix("maximum: "); + + ratio60Ni58NiLayout = new QHBoxLayout(); + ratio60Ni58NiLayout->addWidget(ratio60Ni58NiEnabled); + ratio60Ni58NiLayout->addWidget(minratio60Ni58Ni, 10); + ratio60Ni58NiLayout->addWidget(maxratio60Ni58Ni, 10); + ratio60Ni58NiLayout->setMargin(0); + ratio60Ni58NiWidget = new QWidget(); + ratio60Ni58NiWidget->setLayout(ratio60Ni58NiLayout); + ratio60Ni58NiWidget->setFixedWidth(leftdefaultwidth); + ratio60Ni58NiLabel = new QLabel("60Ni/58Ni Ratio:"); + + isotoperatiosgridlayout->addWidget(ratio60Ni58NiLabel, isotoperow, 0); + isotoperatiosgridlayout->addWidget(ratio60Ni58NiWidget, isotoperow, 1); + isotoperow++; + + ratio62Ni58NiEnabled = new QCheckBox(); + + minratio62Ni58Ni = new QDoubleSpinBox(); + minratio62Ni58Ni->setToolTip("Enter the minimum ratio of 62Ni/58Ni intensities.\nUse 0 if the presence of 62Ni in the spectrum is NOT mandatory."); + minratio62Ni58Ni->setDecimals(3); + minratio62Ni58Ni->setRange(0, 1); + minratio62Ni58Ni->setSingleStep(0.01); + minratio62Ni58Ni->setValue(0); + minratio62Ni58Ni->setPrefix("minimum: "); + + maxratio62Ni58Ni = new QDoubleSpinBox(); + maxratio62Ni58Ni->setToolTip("Enter the maximum ratio of 62Ni/58Ni intensities.\nThe default value is 0.1 (for FWHM <= 0.001 only)."); + maxratio62Ni58Ni->setDecimals(3); + maxratio62Ni58Ni->setRange(0, 1); + maxratio62Ni58Ni->setSingleStep(0.01); + maxratio62Ni58Ni->setValue(0.1); + maxratio62Ni58Ni->setPrefix("maximum: "); + + ratio62Ni58NiLayout = new QHBoxLayout(); + ratio62Ni58NiLayout->addWidget(ratio62Ni58NiEnabled); + ratio62Ni58NiLayout->addWidget(minratio62Ni58Ni, 10); + ratio62Ni58NiLayout->addWidget(maxratio62Ni58Ni, 10); + ratio62Ni58NiLayout->setMargin(0); + ratio62Ni58NiWidget = new QWidget(); + ratio62Ni58NiWidget->setLayout(ratio62Ni58NiLayout); + ratio62Ni58NiWidget->setFixedWidth(leftdefaultwidth); + ratio62Ni58NiLabel = new QLabel("62Ni/58Ni Ratio:"); + + //isotoperatiosgridlayout->addWidget(ratio62Ni58NiLabel, isotoperow, 0); + //isotoperatiosgridlayout->addWidget(ratio62Ni58NiWidget, isotoperow, 1); + //isotoperow++; + + ratio65Cu63CuEnabled = new QCheckBox(); + + minratio65Cu63Cu = new QDoubleSpinBox(); + minratio65Cu63Cu->setToolTip("Enter the minimum ratio of 65Cu/63Cu intensities.\nUse 0 if the presence of 65Cu in the spectrum is NOT mandatory."); + minratio65Cu63Cu->setDecimals(3); + minratio65Cu63Cu->setRange(0, 1); + minratio65Cu63Cu->setSingleStep(0.01); + minratio65Cu63Cu->setValue(0); + minratio65Cu63Cu->setPrefix("minimum: "); + + maxratio65Cu63Cu = new QDoubleSpinBox(); + maxratio65Cu63Cu->setToolTip("Enter the maximum ratio of 65Cu/63Cu intensities.\nThe default value is 0.6 (for FWHM <= 0.001 only)."); + maxratio65Cu63Cu->setDecimals(3); + maxratio65Cu63Cu->setRange(0, 1); + maxratio65Cu63Cu->setSingleStep(0.01); + maxratio65Cu63Cu->setValue(0.6); + maxratio65Cu63Cu->setPrefix("maximum: "); + + ratio65Cu63CuLayout = new QHBoxLayout(); + ratio65Cu63CuLayout->addWidget(ratio65Cu63CuEnabled); + ratio65Cu63CuLayout->addWidget(minratio65Cu63Cu, 10); + ratio65Cu63CuLayout->addWidget(maxratio65Cu63Cu, 10); + ratio65Cu63CuLayout->setMargin(0); + ratio65Cu63CuWidget = new QWidget(); + ratio65Cu63CuWidget->setLayout(ratio65Cu63CuLayout); + ratio65Cu63CuWidget->setFixedWidth(leftdefaultwidth); + ratio65Cu63CuLabel = new QLabel("65Cu/63Cu Ratio:"); + + isotoperatiosgridlayout->addWidget(ratio65Cu63CuLabel, isotoperow, 0); + isotoperatiosgridlayout->addWidget(ratio65Cu63CuWidget, isotoperow, 1); + isotoperow++; + + ratio66Zn64ZnEnabled = new QCheckBox(); + + minratio66Zn64Zn = new QDoubleSpinBox(); + minratio66Zn64Zn->setToolTip("Enter the minimum ratio of 66Zn/64Zn intensities.\nUse 0 if the presence of 66Zn in the spectrum is NOT mandatory."); + minratio66Zn64Zn->setDecimals(3); + minratio66Zn64Zn->setRange(0, 1); + minratio66Zn64Zn->setSingleStep(0.01); + minratio66Zn64Zn->setValue(0); + minratio66Zn64Zn->setPrefix("minimum: "); + + maxratio66Zn64Zn = new QDoubleSpinBox(); + maxratio66Zn64Zn->setToolTip("Enter the maximum ratio of 66Zn/64Zn intensities.\nThe default value is 0.7 (for FWHM <= 0.001 only)."); + maxratio66Zn64Zn->setDecimals(3); + maxratio66Zn64Zn->setRange(0, 1); + maxratio66Zn64Zn->setSingleStep(0.01); + maxratio66Zn64Zn->setValue(0.7); + maxratio66Zn64Zn->setPrefix("maximum: "); + + ratio66Zn64ZnLayout = new QHBoxLayout(); + ratio66Zn64ZnLayout->addWidget(ratio66Zn64ZnEnabled); + ratio66Zn64ZnLayout->addWidget(minratio66Zn64Zn, 10); + ratio66Zn64ZnLayout->addWidget(maxratio66Zn64Zn, 10); + ratio66Zn64ZnLayout->setMargin(0); + ratio66Zn64ZnWidget = new QWidget(); + ratio66Zn64ZnWidget->setLayout(ratio66Zn64ZnLayout); + ratio66Zn64ZnWidget->setFixedWidth(leftdefaultwidth); + ratio66Zn64ZnLabel = new QLabel("66Zn/64Zn Ratio:"); + + isotoperatiosgridlayout->addWidget(ratio66Zn64ZnLabel, isotoperow, 0); + isotoperatiosgridlayout->addWidget(ratio66Zn64ZnWidget, isotoperow, 1); + isotoperow++; + + ratio67Zn64ZnEnabled = new QCheckBox(); + + minratio67Zn64Zn = new QDoubleSpinBox(); + minratio67Zn64Zn->setToolTip("Enter the minimum ratio of 67Zn/64Zn intensities.\nUse 0 if the presence of 67Zn in the spectrum is NOT mandatory."); + minratio67Zn64Zn->setDecimals(3); + minratio67Zn64Zn->setRange(0, 1); + minratio67Zn64Zn->setSingleStep(0.01); + minratio67Zn64Zn->setValue(0); + minratio67Zn64Zn->setPrefix("minimum: "); + + maxratio67Zn64Zn = new QDoubleSpinBox(); + maxratio67Zn64Zn->setToolTip("Enter the maximum ratio of 67Zn/64Zn intensities.\nThe default value is 0.2 (for FWHM <= 0.001 only)."); + maxratio67Zn64Zn->setDecimals(3); + maxratio67Zn64Zn->setRange(0, 1); + maxratio67Zn64Zn->setSingleStep(0.01); + maxratio67Zn64Zn->setValue(0.2); + maxratio67Zn64Zn->setPrefix("maximum: "); + + ratio67Zn64ZnLayout = new QHBoxLayout(); + ratio67Zn64ZnLayout->addWidget(ratio67Zn64ZnEnabled); + ratio67Zn64ZnLayout->addWidget(minratio67Zn64Zn, 10); + ratio67Zn64ZnLayout->addWidget(maxratio67Zn64Zn, 10); + ratio67Zn64ZnLayout->setMargin(0); + ratio67Zn64ZnWidget = new QWidget(); + ratio67Zn64ZnWidget->setLayout(ratio67Zn64ZnLayout); + ratio67Zn64ZnWidget->setFixedWidth(leftdefaultwidth); + ratio67Zn64ZnLabel = new QLabel("67Zn/64Zn Ratio:"); + + //isotoperatiosgridlayout->addWidget(ratio67Zn64ZnLabel, isotoperow, 0); + //isotoperatiosgridlayout->addWidget(ratio67Zn64ZnWidget, isotoperow, 1); + //isotoperow++; + + ratio68Zn64ZnEnabled = new QCheckBox(); + + minratio68Zn64Zn = new QDoubleSpinBox(); + minratio68Zn64Zn->setToolTip("Enter the minimum ratio of 68Zn/64Zn intensities.\nUse 0 if the presence of 68Zn in the spectrum is NOT mandatory."); + minratio68Zn64Zn->setDecimals(3); + minratio68Zn64Zn->setRange(0, 1); + minratio68Zn64Zn->setSingleStep(0.01); + minratio68Zn64Zn->setValue(0); + minratio68Zn64Zn->setPrefix("minimum: "); + + maxratio68Zn64Zn = new QDoubleSpinBox(); + maxratio68Zn64Zn->setToolTip("Enter the maximum ratio of 68Zn/64Zn intensities.\nThe default value is 0.5 (for FWHM <= 0.001 only)."); + maxratio68Zn64Zn->setDecimals(3); + maxratio68Zn64Zn->setRange(0, 1); + maxratio68Zn64Zn->setSingleStep(0.01); + maxratio68Zn64Zn->setValue(0.5); + maxratio68Zn64Zn->setPrefix("maximum: "); + + ratio68Zn64ZnLayout = new QHBoxLayout(); + ratio68Zn64ZnLayout->addWidget(ratio68Zn64ZnEnabled); + ratio68Zn64ZnLayout->addWidget(minratio68Zn64Zn, 10); + ratio68Zn64ZnLayout->addWidget(maxratio68Zn64Zn, 10); + ratio68Zn64ZnLayout->setMargin(0); + ratio68Zn64ZnWidget = new QWidget(); + ratio68Zn64ZnWidget->setLayout(ratio68Zn64ZnLayout); + ratio68Zn64ZnWidget->setFixedWidth(leftdefaultwidth); + ratio68Zn64ZnLabel = new QLabel("68Zn/64Zn Ratio:"); + + isotoperatiosgridlayout->addWidget(ratio68Zn64ZnLabel, isotoperow, 0); + isotoperatiosgridlayout->addWidget(ratio68Zn64ZnWidget, isotoperow, 1); + isotoperow++; + + isotoperatiosgroupbox = new QGroupBox("Isotope Ratios"); + isotoperatiosgroupbox->setLayout(isotoperatiosgridlayout); brickdatabasegridlayout = new QGridLayout(); @@ -480,6 +685,7 @@ cParametersWidget::cParametersWidget(cGlobalPreferences* globalpreferences, QWid scoretype->addItem(tr("Number of y-ions")); scoretype->addItem(tr("Number of b-ions and y-ions")); scoretype->addItem(tr("Weighted Ratio of Matched Peaks")); + scoretype->addItem(tr("Cosine Similarity")); scoretype->setFixedWidth(rightdefaultwidth); scoretypelabel = new QLabel("Score Type:"); theoreticalspectragridlayout->addWidget(scoretypelabel, 1, 0); @@ -724,6 +930,7 @@ cParametersWidget::cParametersWidget(cGlobalPreferences* globalpreferences, QWid vlayout1 = new QVBoxLayout(); vlayout1->addWidget(searchgroupbox); vlayout1->addWidget(experimentalspectragroupbox); + vlayout1->addWidget(isotoperatiosgroupbox); vlayout1->addWidget(brickdatabasegroupbox); vlayout1->addWidget(miscgroupbox); if (hideunusedparameters) { @@ -838,14 +1045,62 @@ cParametersWidget::~cParametersWidget() { delete rtwidget; delete fwhmlabel; delete fwhm; - delete ratio54Fe56Felabel; - delete minratio54Fe56Fe; - delete maxratio54Fe56Fe; - delete ratio54Fe56Felayout; - delete ratio54Fe56Fewidget; + delete experimentalspectragridlayout; delete experimentalspectragroupbox; + delete ratio54Fe56FeLabel; + delete ratio54Fe56FeEnabled; + delete minratio54Fe56Fe; + delete maxratio54Fe56Fe; + delete ratio54Fe56FeLayout; + delete ratio54Fe56FeWidget; + + delete ratio60Ni58NiLabel; + delete ratio60Ni58NiEnabled; + delete minratio60Ni58Ni; + delete maxratio60Ni58Ni; + delete ratio60Ni58NiLayout; + delete ratio60Ni58NiWidget; + + delete ratio62Ni58NiLabel; + delete ratio62Ni58NiEnabled; + delete minratio62Ni58Ni; + delete maxratio62Ni58Ni; + delete ratio62Ni58NiLayout; + delete ratio62Ni58NiWidget; + + delete ratio65Cu63CuLabel; + delete ratio65Cu63CuEnabled; + delete minratio65Cu63Cu; + delete maxratio65Cu63Cu; + delete ratio65Cu63CuLayout; + delete ratio65Cu63CuWidget; + + delete ratio66Zn64ZnLabel; + delete ratio66Zn64ZnEnabled; + delete minratio66Zn64Zn; + delete maxratio66Zn64Zn; + delete ratio66Zn64ZnLayout; + delete ratio66Zn64ZnWidget; + + delete ratio67Zn64ZnLabel; + delete ratio67Zn64ZnEnabled; + delete minratio67Zn64Zn; + delete maxratio67Zn64Zn; + delete ratio67Zn64ZnLayout; + delete ratio67Zn64ZnWidget; + + delete ratio68Zn64ZnLabel; + delete ratio68Zn64ZnEnabled; + delete minratio68Zn64Zn; + delete maxratio68Zn64Zn; + delete ratio68Zn64ZnLayout; + delete ratio68Zn64ZnWidget; + + delete isotoperatiosgridlayout; + delete isotoperatiosgroupbox; + delete brickdatabaselabel; delete brickdatabaseline; delete brickdatabasebutton; @@ -1097,9 +1352,42 @@ void cParametersWidget::loadSettings() { minimumrt->setValue(settings.value("minimumrt", 0).toDouble()); maximumrt->setValue(settings.value("maximumrt", 0).toDouble()); fwhm->setValue(settings.value("fwhm", 0.05).toDouble()); + + settings.value("enableratio54Fe56Fe", 1).toInt() == 0 ? ratio54Fe56FeEnabled->setChecked(false) : ratio54Fe56FeEnabled->setChecked(true); + minratio54Fe56Fe->setValue(settings.value("minratio54Fe56Fe", 0.01).toDouble()); maxratio54Fe56Fe->setValue(settings.value("maxratio54Fe56Fe", 0.1).toDouble()); + settings.value("enableratio60Ni58Ni", 1).toInt() == 0 ? ratio60Ni58NiEnabled->setChecked(false) : ratio60Ni58NiEnabled->setChecked(true); + + minratio60Ni58Ni->setValue(settings.value("minratio60Ni58Ni", 0).toDouble()); + maxratio60Ni58Ni->setValue(settings.value("maxratio60Ni58Ni", 0.5).toDouble()); + + settings.value("enableratio62Ni58Ni", 1).toInt() == 0 ? ratio62Ni58NiEnabled->setChecked(false) : ratio62Ni58NiEnabled->setChecked(true); + + minratio62Ni58Ni->setValue(settings.value("minratio62Ni58Ni", 0).toDouble()); + maxratio62Ni58Ni->setValue(settings.value("maxratio62Ni58Ni", 0.1).toDouble()); + + settings.value("enableratio65Cu63Cu", 1).toInt() == 0 ? ratio65Cu63CuEnabled->setChecked(false) : ratio65Cu63CuEnabled->setChecked(true); + + minratio65Cu63Cu->setValue(settings.value("minratio65Cu63Cu", 0).toDouble()); + maxratio65Cu63Cu->setValue(settings.value("maxratio65Cu63Cu", 0.6).toDouble()); + + settings.value("enableratio66Zn64Zn", 1).toInt() == 0 ? ratio66Zn64ZnEnabled->setChecked(false) : ratio66Zn64ZnEnabled->setChecked(true); + + minratio66Zn64Zn->setValue(settings.value("minratio66Zn64Zn", 0).toDouble()); + maxratio66Zn64Zn->setValue(settings.value("maxratio66Zn64Zn", 0.7).toDouble()); + + settings.value("enableratio67Zn64Zn", 1).toInt() == 0 ? ratio67Zn64ZnEnabled->setChecked(false) : ratio67Zn64ZnEnabled->setChecked(true); + + minratio67Zn64Zn->setValue(settings.value("minratio67Zn64Zn", 0).toDouble()); + maxratio67Zn64Zn->setValue(settings.value("maxratio67Zn64Zn", 0.2).toDouble()); + + settings.value("enableratio68Zn64Zn", 1).toInt() == 0 ? ratio68Zn64ZnEnabled->setChecked(false) : ratio68Zn64ZnEnabled->setChecked(true); + + minratio68Zn64Zn->setValue(settings.value("minratio68Zn64Zn", 0).toDouble()); + maxratio68Zn64Zn->setValue(settings.value("maxratio68Zn64Zn", 0.5).toDouble()); + brickdatabaseline->setText(settings.value("brickdatabase", "").toString()); maximumbricksincombinationbegin->setValue(settings.value("maximumbricksincombinationbegin", 1).toInt()); maximumbricksincombinationmiddle->setValue(settings.value("maximumbricksincombinationmiddle", 1).toInt()); @@ -1117,7 +1405,7 @@ void cParametersWidget::loadSettings() { sequencedatabaseline->setText(settings.value("sequencedatabase", "").toString()); scoretype->setCurrentIndex(settings.value("scoretype", (int)number_of_matched_peaks).toInt()); - if ((scoretype->currentIndex() < (int)number_of_matched_peaks) || (scoretype->currentIndex() > (int)number_of_b_and_y_ions)) { + if ((scoretype->currentIndex() < (int)number_of_matched_peaks) || (scoretype->currentIndex() > (int)cosine_similarity)) { scoretype->setCurrentIndex((int)number_of_matched_peaks); } hitsreported->setValue(settings.value("hitsreported", 100).toInt()); @@ -1254,9 +1542,42 @@ void cParametersWidget::saveSettings() { settings.setValue("minimumrt", minimumrt->value()); settings.setValue("maximumrt", maximumrt->value()); settings.setValue("fwhm", fwhm->value()); + + ratio54Fe56FeEnabled->isChecked() ? settings.setValue("enableratio54Fe56Fe", 1) : settings.setValue("enableratio54Fe56Fe", 0); + settings.setValue("minratio54Fe56Fe", minratio54Fe56Fe->value()); settings.setValue("maxratio54Fe56Fe", maxratio54Fe56Fe->value()); + ratio60Ni58NiEnabled->isChecked() ? settings.setValue("enableratio60Ni58Ni", 1) : settings.setValue("enableratio60Ni58Ni", 0); + + settings.setValue("minratio60Ni58Ni", minratio60Ni58Ni->value()); + settings.setValue("maxratio60Ni58Ni", maxratio60Ni58Ni->value()); + + ratio62Ni58NiEnabled->isChecked() ? settings.setValue("enableratio62Ni58Ni", 1) : settings.setValue("enableratio62Ni58Ni", 0); + + settings.setValue("minratio62Ni58Ni", minratio62Ni58Ni->value()); + settings.setValue("maxratio62Ni58Ni", maxratio62Ni58Ni->value()); + + ratio65Cu63CuEnabled->isChecked() ? settings.setValue("enableratio65Cu63Cu", 1) : settings.setValue("enableratio65Cu63Cu", 0); + + settings.setValue("minratio65Cu63Cu", minratio65Cu63Cu->value()); + settings.setValue("maxratio65Cu63Cu", maxratio65Cu63Cu->value()); + + ratio66Zn64ZnEnabled->isChecked() ? settings.setValue("enableratio66Zn64Zn", 1) : settings.setValue("enableratio66Zn64Zn", 0); + + settings.setValue("minratio66Zn64Zn", minratio66Zn64Zn->value()); + settings.setValue("maxratio66Zn64Zn", maxratio66Zn64Zn->value()); + + ratio67Zn64ZnEnabled->isChecked() ? settings.setValue("enableratio67Zn64Zn", 1) : settings.setValue("enableratio67Zn64Zn", 0); + + settings.setValue("minratio67Zn64Zn", minratio67Zn64Zn->value()); + settings.setValue("maxratio67Zn64Zn", maxratio67Zn64Zn->value()); + + ratio68Zn64ZnEnabled->isChecked() ? settings.setValue("enableratio68Zn64Zn", 1) : settings.setValue("enableratio68Zn64Zn", 0); + + settings.setValue("minratio68Zn64Zn", minratio68Zn64Zn->value()); + settings.setValue("maxratio68Zn64Zn", maxratio68Zn64Zn->value()); + settings.setValue("brickdatabase", brickdatabaseline->text()); settings.setValue("maximumbricksincombinationbegin", maximumbricksincombinationbegin->value()); settings.setValue("maximumbricksincombinationmiddle", maximumbricksincombinationmiddle->value()); @@ -1610,12 +1931,54 @@ bool cParametersWidget::updateParameters() { } } - if (minratio54Fe56Fe->value() >= maxratio54Fe56Fe->value()) { + if (ratio54Fe56FeEnabled->isChecked() && (minratio54Fe56Fe->value() >= maxratio54Fe56Fe->value())) { errstr = "The minimum ratio 54Fe/56Fe must be lower than the maximum ratio of 54Fe/56Fe !"; msgBox.setText(errstr); msgBox.exec(); return false; } + + if (ratio60Ni58NiEnabled->isChecked() && (minratio60Ni58Ni->value() >= maxratio60Ni58Ni->value())) { + errstr = "The minimum ratio 60Ni/58Ni must be lower than the maximum ratio of 60Ni/58Ni !"; + msgBox.setText(errstr); + msgBox.exec(); + return false; + } + + if (ratio62Ni58NiEnabled->isChecked() && (minratio62Ni58Ni->value() >= maxratio62Ni58Ni->value())) { + errstr = "The minimum ratio 62Ni/58Ni must be lower than the maximum ratio of 62Ni/58Ni !"; + msgBox.setText(errstr); + msgBox.exec(); + return false; + } + + if (ratio65Cu63CuEnabled->isChecked() && (minratio65Cu63Cu->value() >= maxratio65Cu63Cu->value())) { + errstr = "The minimum ratio 65Cu/63Cu must be lower than the maximum ratio of 65Cu/63Cu !"; + msgBox.setText(errstr); + msgBox.exec(); + return false; + } + + if (ratio66Zn64ZnEnabled->isChecked() && (minratio66Zn64Zn->value() >= maxratio66Zn64Zn->value())) { + errstr = "The minimum ratio 66Zn/64Zn must be lower than the maximum ratio of 66Zn/64Zn !"; + msgBox.setText(errstr); + msgBox.exec(); + return false; + } + + if (ratio67Zn64ZnEnabled->isChecked() && (minratio67Zn64Zn->value() >= maxratio67Zn64Zn->value())) { + errstr = "The minimum ratio 67Zn/64Zn must be lower than the maximum ratio of 67Zn/64Zn !"; + msgBox.setText(errstr); + msgBox.exec(); + return false; + } + + if (ratio68Zn64ZnEnabled->isChecked() && (minratio68Zn64Zn->value() >= maxratio68Zn64Zn->value())) { + errstr = "The minimum ratio 68Zn/64Zn must be lower than the maximum ratio of 68Zn/64Zn !"; + msgBox.setText(errstr); + msgBox.exec(); + return false; + } } if ((eModeType)mode->currentIndex() == denovoengine) { @@ -1746,9 +2109,42 @@ bool cParametersWidget::updateParameters() { parameters.minimumrt = minimumrt->value(); parameters.maximumrt = maximumrt->value(); parameters.fwhm = fwhm->value(); + + parameters.enableratio54Fe56Fe = ratio54Fe56FeEnabled->isChecked(); + parameters.minratio54Fe56Fe = minratio54Fe56Fe->value(); parameters.maxratio54Fe56Fe = maxratio54Fe56Fe->value(); + parameters.enableratio60Ni58Ni = ratio60Ni58NiEnabled->isChecked(); + + parameters.minratio60Ni58Ni = minratio60Ni58Ni->value(); + parameters.maxratio60Ni58Ni = maxratio60Ni58Ni->value(); + + parameters.enableratio62Ni58Ni = ratio62Ni58NiEnabled->isChecked(); + + parameters.minratio62Ni58Ni = minratio62Ni58Ni->value(); + parameters.maxratio62Ni58Ni = maxratio62Ni58Ni->value(); + + parameters.enableratio65Cu63Cu = ratio65Cu63CuEnabled->isChecked(); + + parameters.minratio65Cu63Cu = minratio65Cu63Cu->value(); + parameters.maxratio65Cu63Cu = maxratio65Cu63Cu->value(); + + parameters.enableratio66Zn64Zn = ratio66Zn64ZnEnabled->isChecked(); + + parameters.minratio66Zn64Zn = minratio66Zn64Zn->value(); + parameters.maxratio66Zn64Zn = maxratio66Zn64Zn->value(); + + parameters.enableratio67Zn64Zn = ratio67Zn64ZnEnabled->isChecked(); + + parameters.minratio67Zn64Zn = minratio67Zn64Zn->value(); + parameters.maxratio67Zn64Zn = maxratio67Zn64Zn->value(); + + parameters.enableratio68Zn64Zn = ratio68Zn64ZnEnabled->isChecked(); + + parameters.minratio68Zn64Zn = minratio68Zn64Zn->value(); + parameters.maxratio68Zn64Zn = maxratio68Zn64Zn->value(); + parameters.bricksdatabasefilename = brickdatabaseline->text().toStdString(); parameters.maximumbricksincombinationbegin = maximumbricksincombinationbegin->value(); parameters.maximumbricksincombinationmiddle = maximumbricksincombinationmiddle->value(); @@ -1912,9 +2308,42 @@ void cParametersWidget::restoreParameters() { minimumrt->setValue(parameters.minimumrt); maximumrt->setValue(parameters.maximumrt); fwhm->setValue(parameters.fwhm); + + ratio54Fe56FeEnabled->setChecked(parameters.enableratio54Fe56Fe); + minratio54Fe56Fe->setValue(parameters.minratio54Fe56Fe); maxratio54Fe56Fe->setValue(parameters.maxratio54Fe56Fe); + ratio60Ni58NiEnabled->setChecked(parameters.enableratio60Ni58Ni); + + minratio60Ni58Ni->setValue(parameters.minratio60Ni58Ni); + maxratio60Ni58Ni->setValue(parameters.maxratio60Ni58Ni); + + ratio62Ni58NiEnabled->setChecked(parameters.enableratio62Ni58Ni); + + minratio62Ni58Ni->setValue(parameters.minratio62Ni58Ni); + maxratio62Ni58Ni->setValue(parameters.maxratio62Ni58Ni); + + ratio65Cu63CuEnabled->setChecked(parameters.enableratio65Cu63Cu); + + minratio65Cu63Cu->setValue(parameters.minratio65Cu63Cu); + maxratio65Cu63Cu->setValue(parameters.maxratio65Cu63Cu); + + ratio66Zn64ZnEnabled->setChecked(parameters.enableratio66Zn64Zn); + + minratio66Zn64Zn->setValue(parameters.minratio66Zn64Zn); + maxratio66Zn64Zn->setValue(parameters.maxratio66Zn64Zn); + + ratio67Zn64ZnEnabled->setChecked(parameters.enableratio67Zn64Zn); + + minratio67Zn64Zn->setValue(parameters.minratio67Zn64Zn); + maxratio67Zn64Zn->setValue(parameters.maxratio67Zn64Zn); + + ratio68Zn64ZnEnabled->setChecked(parameters.enableratio68Zn64Zn); + + minratio68Zn64Zn->setValue(parameters.minratio68Zn64Zn); + maxratio68Zn64Zn->setValue(parameters.maxratio68Zn64Zn); + brickdatabaseline->setText(parameters.bricksdatabasefilename.c_str()); maximumbricksincombinationbegin->setValue(parameters.maximumbricksincombinationbegin); maximumbricksincombinationmiddle->setValue(parameters.maximumbricksincombinationmiddle); @@ -2238,8 +2667,35 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setDisabled(true); maximumrt->setDisabled(true); fwhm->setDisabled(false); + + ratio54Fe56FeEnabled->setDisabled(true); minratio54Fe56Fe->setDisabled(true); maxratio54Fe56Fe->setDisabled(true); + + ratio60Ni58NiEnabled->setDisabled(true); + minratio60Ni58Ni->setDisabled(true); + maxratio60Ni58Ni->setDisabled(true); + + ratio62Ni58NiEnabled->setDisabled(true); + minratio62Ni58Ni->setDisabled(true); + maxratio62Ni58Ni->setDisabled(true); + + ratio65Cu63CuEnabled->setDisabled(true); + minratio65Cu63Cu->setDisabled(true); + maxratio65Cu63Cu->setDisabled(true); + + ratio66Zn64ZnEnabled->setDisabled(true); + minratio66Zn64Zn->setDisabled(true); + maxratio66Zn64Zn->setDisabled(true); + + ratio67Zn64ZnEnabled->setDisabled(true); + minratio67Zn64Zn->setDisabled(true); + maxratio67Zn64Zn->setDisabled(true); + + ratio68Zn64ZnEnabled->setDisabled(true); + minratio68Zn64Zn->setDisabled(true); + maxratio68Zn64Zn->setDisabled(true); + brickdatabaseline->setDisabled(false); brickdatabasebutton->setDisabled(false); maximumbricksincombinationbegin->setDisabled(false); @@ -2304,9 +2760,40 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setHidden(true); maximumrt->setHidden(true); - ratio54Fe56Felabel->setHidden(true); - minratio54Fe56Fe->setHidden(true); - maxratio54Fe56Fe->setHidden(true); + //ratio54Fe56FeLabel->setHidden(true); + //ratio54Fe56FeEnabled->setHidden(true); + //minratio54Fe56Fe->setHidden(true); + //maxratio54Fe56Fe->setHidden(true); + + //ratio60Ni58NiLabel->setHidden(true); + //ratio60Ni58NiEnabled->setHidden(true); + //minratio60Ni58Ni->setHidden(true); + //maxratio60Ni58Ni->setHidden(true); + + //ratio62Ni58NiLabel->setHidden(true); + //ratio62Ni58NiEnabled->setHidden(true); + //minratio62Ni58Ni->setHidden(true); + //maxratio62Ni58Ni->setHidden(true); + + //ratio65Cu63CuLabel->setHidden(true); + //ratio65Cu63CuEnabled->setHidden(true); + //minratio65Cu63Cu->setHidden(true); + //maxratio65Cu63Cu->setHidden(true); + + //ratio66Zn64ZnLabel->setHidden(true); + //ratio66Zn64ZnEnabled->setHidden(true); + //minratio66Zn64Zn->setHidden(true); + //maxratio66Zn64Zn->setHidden(true); + + //ratio67Zn64ZnLabel->setHidden(true); + //ratio67Zn64ZnEnabled->setHidden(true); + //minratio67Zn64Zn->setHidden(true); + //maxratio67Zn64Zn->setHidden(true); + + //ratio68Zn64ZnLabel->setHidden(true); + //ratio68Zn64ZnEnabled->setHidden(true); + //minratio68Zn64Zn->setHidden(true); + //maxratio68Zn64Zn->setHidden(true); maximumbricksincombinatiolabel->setHidden(false); maximumbricksincombinationbegin->setHidden(false); @@ -2369,6 +2856,7 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { intensitytolerancelabel->setHidden(true); intensitytolerance->setHidden(true); + isotoperatiosgroupbox->setHidden(true); brickdatabasegroupbox->setHidden(false); miscgroupbox->setHidden(false); searchedsequencegroupbox->setHidden(false); @@ -2387,8 +2875,35 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setDisabled(true); maximumrt->setDisabled(true); fwhm->setDisabled(false); + + ratio54Fe56FeEnabled->setDisabled(true); minratio54Fe56Fe->setDisabled(true); maxratio54Fe56Fe->setDisabled(true); + + ratio60Ni58NiEnabled->setDisabled(true); + minratio60Ni58Ni->setDisabled(true); + maxratio60Ni58Ni->setDisabled(true); + + ratio62Ni58NiEnabled->setDisabled(true); + minratio62Ni58Ni->setDisabled(true); + maxratio62Ni58Ni->setDisabled(true); + + ratio65Cu63CuEnabled->setDisabled(true); + minratio65Cu63Cu->setDisabled(true); + maxratio65Cu63Cu->setDisabled(true); + + ratio66Zn64ZnEnabled->setDisabled(true); + minratio66Zn64Zn->setDisabled(true); + maxratio66Zn64Zn->setDisabled(true); + + ratio67Zn64ZnEnabled->setDisabled(true); + minratio67Zn64Zn->setDisabled(true); + maxratio67Zn64Zn->setDisabled(true); + + ratio68Zn64ZnEnabled->setDisabled(true); + minratio68Zn64Zn->setDisabled(true); + maxratio68Zn64Zn->setDisabled(true); + brickdatabaseline->setDisabled(false); brickdatabasebutton->setDisabled(false); maximumbricksincombinationbegin->setDisabled(true); @@ -2453,9 +2968,40 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setHidden(true); maximumrt->setHidden(true); - ratio54Fe56Felabel->setHidden(true); - minratio54Fe56Fe->setHidden(true); - maxratio54Fe56Fe->setHidden(true); + //ratio54Fe56FeLabel->setHidden(true); + //ratio54Fe56FeEnabled->setHidden(true); + //minratio54Fe56Fe->setHidden(true); + //maxratio54Fe56Fe->setHidden(true); + + //ratio60Ni58NiLabel->setHidden(true); + //ratio60Ni58NiEnabled->setHidden(true); + //minratio60Ni58Ni->setHidden(true); + //maxratio60Ni58Ni->setHidden(true); + + //ratio62Ni58NiLabel->setHidden(true); + //ratio62Ni58NiEnabled->setHidden(true); + //minratio62Ni58Ni->setHidden(true); + //maxratio62Ni58Ni->setHidden(true); + + //ratio65Cu63CuLabel->setHidden(true); + //ratio65Cu63CuEnabled->setHidden(true); + //minratio65Cu63Cu->setHidden(true); + //maxratio65Cu63Cu->setHidden(true); + + //ratio66Zn64ZnLabel->setHidden(true); + //ratio66Zn64ZnEnabled->setHidden(true); + //minratio66Zn64Zn->setHidden(true); + //maxratio66Zn64Zn->setHidden(true); + + //ratio67Zn64ZnLabel->setHidden(true); + //ratio67Zn64ZnEnabled->setHidden(true); + //minratio67Zn64Zn->setHidden(true); + //maxratio67Zn64Zn->setHidden(true); + + //ratio68Zn64ZnLabel->setHidden(true); + //ratio68Zn64ZnEnabled->setHidden(true); + //minratio68Zn64Zn->setHidden(true); + //maxratio68Zn64Zn->setHidden(true); maximumbricksincombinatiolabel->setHidden(true); maximumbricksincombinationbegin->setHidden(true); @@ -2518,6 +3064,7 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { intensitytolerancelabel->setHidden(true); intensitytolerance->setHidden(true); + isotoperatiosgroupbox->setHidden(true); brickdatabasegroupbox->setHidden(false); miscgroupbox->setHidden(false); searchedsequencegroupbox->setHidden(false); @@ -2536,8 +3083,35 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setDisabled(true); maximumrt->setDisabled(true); fwhm->setDisabled(false); + + ratio54Fe56FeEnabled->setDisabled(true); minratio54Fe56Fe->setDisabled(true); maxratio54Fe56Fe->setDisabled(true); + + ratio60Ni58NiEnabled->setDisabled(true); + minratio60Ni58Ni->setDisabled(true); + maxratio60Ni58Ni->setDisabled(true); + + ratio62Ni58NiEnabled->setDisabled(true); + minratio62Ni58Ni->setDisabled(true); + maxratio62Ni58Ni->setDisabled(true); + + ratio65Cu63CuEnabled->setDisabled(true); + minratio65Cu63Cu->setDisabled(true); + maxratio65Cu63Cu->setDisabled(true); + + ratio66Zn64ZnEnabled->setDisabled(true); + minratio66Zn64Zn->setDisabled(true); + maxratio66Zn64Zn->setDisabled(true); + + ratio67Zn64ZnEnabled->setDisabled(true); + minratio67Zn64Zn->setDisabled(true); + maxratio67Zn64Zn->setDisabled(true); + + ratio68Zn64ZnEnabled->setDisabled(true); + minratio68Zn64Zn->setDisabled(true); + maxratio68Zn64Zn->setDisabled(true); + brickdatabaseline->setDisabled(false); brickdatabasebutton->setDisabled(false); maximumbricksincombinationbegin->setDisabled(true); @@ -2602,9 +3176,40 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setHidden(true); maximumrt->setHidden(true); - ratio54Fe56Felabel->setHidden(true); - minratio54Fe56Fe->setHidden(true); - maxratio54Fe56Fe->setHidden(true); + //ratio54Fe56FeLabel->setHidden(true); + //ratio54Fe56FeEnabled->setHidden(true); + //minratio54Fe56Fe->setHidden(true); + //maxratio54Fe56Fe->setHidden(true); + + //ratio60Ni58NiLabel->setHidden(true); + //ratio60Ni58NiEnabled->setHidden(true); + //minratio60Ni58Ni->setHidden(true); + //maxratio60Ni58Ni->setHidden(true); + + //ratio62Ni58NiLabel->setHidden(true); + //ratio62Ni58NiEnabled->setHidden(true); + //minratio62Ni58Ni->setHidden(true); + //maxratio62Ni58Ni->setHidden(true); + + //ratio65Cu63CuLabel->setHidden(true); + //ratio65Cu63CuEnabled->setHidden(true); + //minratio65Cu63Cu->setHidden(true); + //maxratio65Cu63Cu->setHidden(true); + + //ratio66Zn64ZnLabel->setHidden(true); + //ratio66Zn64ZnEnabled->setHidden(true); + //minratio66Zn64Zn->setHidden(true); + //maxratio66Zn64Zn->setHidden(true); + + //ratio67Zn64ZnLabel->setHidden(true); + //ratio67Zn64ZnEnabled->setHidden(true); + //minratio67Zn64Zn->setHidden(true); + //maxratio67Zn64Zn->setHidden(true); + + //ratio68Zn64ZnLabel->setHidden(true); + //ratio68Zn64ZnEnabled->setHidden(true); + //minratio68Zn64Zn->setHidden(true); + //maxratio68Zn64Zn->setHidden(true); maximumbricksincombinatiolabel->setHidden(true); maximumbricksincombinationbegin->setHidden(true); @@ -2667,6 +3272,7 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { intensitytolerancelabel->setHidden(true); intensitytolerance->setHidden(true); + isotoperatiosgroupbox->setHidden(true); brickdatabasegroupbox->setHidden(false); miscgroupbox->setHidden(false); searchedsequencegroupbox->setHidden(false); @@ -2685,8 +3291,35 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setDisabled(false); maximumrt->setDisabled(false); fwhm->setDisabled(false); + + ratio54Fe56FeEnabled->setDisabled(false); minratio54Fe56Fe->setDisabled(false); maxratio54Fe56Fe->setDisabled(false); + + ratio60Ni58NiEnabled->setDisabled(false); + minratio60Ni58Ni->setDisabled(false); + maxratio60Ni58Ni->setDisabled(false); + + ratio62Ni58NiEnabled->setDisabled(false); + minratio62Ni58Ni->setDisabled(false); + maxratio62Ni58Ni->setDisabled(false); + + ratio65Cu63CuEnabled->setDisabled(false); + minratio65Cu63Cu->setDisabled(false); + maxratio65Cu63Cu->setDisabled(false); + + ratio66Zn64ZnEnabled->setDisabled(false); + minratio66Zn64Zn->setDisabled(false); + maxratio66Zn64Zn->setDisabled(false); + + ratio67Zn64ZnEnabled->setDisabled(false); + minratio67Zn64Zn->setDisabled(false); + maxratio67Zn64Zn->setDisabled(false); + + ratio68Zn64ZnEnabled->setDisabled(false); + minratio68Zn64Zn->setDisabled(false); + maxratio68Zn64Zn->setDisabled(false); + brickdatabaseline->setDisabled(true); brickdatabasebutton->setDisabled(true); maximumbricksincombinationbegin->setDisabled(true); @@ -2769,9 +3402,40 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setHidden(false); maximumrt->setHidden(false); - ratio54Fe56Felabel->setHidden(false); - minratio54Fe56Fe->setHidden(false); - maxratio54Fe56Fe->setHidden(false); + //ratio54Fe56FeLabel->setHidden(false); + //ratio54Fe56FeEnabled->setHidden(false); + //minratio54Fe56Fe->setHidden(false); + //maxratio54Fe56Fe->setHidden(false); + + //ratio60Ni58NiLabel->setHidden(false); + //ratio60Ni58NiEnabled->setHidden(false); + //minratio60Ni58Ni->setHidden(false); + //maxratio60Ni58Ni->setHidden(false); + + //ratio62Ni58NiLabel->setHidden(false); + //ratio62Ni58NiEnabled->setHidden(false); + //minratio62Ni58Ni->setHidden(false); + //maxratio62Ni58Ni->setHidden(false); + + //ratio65Cu63CuLabel->setHidden(false); + //ratio65Cu63CuEnabled->setHidden(false); + //minratio65Cu63Cu->setHidden(false); + //maxratio65Cu63Cu->setHidden(false); + + //ratio66Zn64ZnLabel->setHidden(false); + //ratio66Zn64ZnEnabled->setHidden(false); + //minratio66Zn64Zn->setHidden(false); + //maxratio66Zn64Zn->setHidden(false); + + //ratio67Zn64ZnLabel->setHidden(false); + //ratio67Zn64ZnEnabled->setHidden(false); + //minratio67Zn64Zn->setHidden(false); + //maxratio67Zn64Zn->setHidden(false); + + //ratio68Zn64ZnLabel->setHidden(false); + //ratio68Zn64ZnEnabled->setHidden(false); + //minratio68Zn64Zn->setHidden(false); + //maxratio68Zn64Zn->setHidden(false); maximumbricksincombinatiolabel->setHidden(true); maximumbricksincombinationbegin->setHidden(true); @@ -2834,6 +3498,7 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { intensitytolerancelabel->setHidden(false); intensitytolerance->setHidden(false); + isotoperatiosgroupbox->setHidden(false); brickdatabasegroupbox->setHidden(true); miscgroupbox->setHidden(true); searchedsequencegroupbox->setHidden(true); @@ -2852,8 +3517,35 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setDisabled(false); maximumrt->setDisabled(false); fwhm->setDisabled(false); + + ratio54Fe56FeEnabled->setDisabled(false); minratio54Fe56Fe->setDisabled(false); maxratio54Fe56Fe->setDisabled(false); + + ratio60Ni58NiEnabled->setDisabled(false); + minratio60Ni58Ni->setDisabled(false); + maxratio60Ni58Ni->setDisabled(false); + + ratio62Ni58NiEnabled->setDisabled(false); + minratio62Ni58Ni->setDisabled(false); + maxratio62Ni58Ni->setDisabled(false); + + ratio65Cu63CuEnabled->setDisabled(false); + minratio65Cu63Cu->setDisabled(false); + maxratio65Cu63Cu->setDisabled(false); + + ratio66Zn64ZnEnabled->setDisabled(false); + minratio66Zn64Zn->setDisabled(false); + maxratio66Zn64Zn->setDisabled(false); + + ratio67Zn64ZnEnabled->setDisabled(false); + minratio67Zn64Zn->setDisabled(false); + maxratio67Zn64Zn->setDisabled(false); + + ratio68Zn64ZnEnabled->setDisabled(false); + minratio68Zn64Zn->setDisabled(false); + maxratio68Zn64Zn->setDisabled(false); + brickdatabaseline->setDisabled(true); brickdatabasebutton->setDisabled(true); maximumbricksincombinationbegin->setDisabled(true); @@ -2936,9 +3628,40 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { minimumrt->setHidden(false); maximumrt->setHidden(false); - ratio54Fe56Felabel->setHidden(false); - minratio54Fe56Fe->setHidden(false); - maxratio54Fe56Fe->setHidden(false); + //ratio54Fe56FeLabel->setHidden(false); + //ratio54Fe56FeEnabled->setHidden(false); + //minratio54Fe56Fe->setHidden(false); + //maxratio54Fe56Fe->setHidden(false); + + //ratio60Ni58NiLabel->setHidden(false); + //ratio60Ni58NiEnabled->setHidden(false); + //minratio60Ni58Ni->setHidden(false); + //maxratio60Ni58Ni->setHidden(false); + + //ratio62Ni58NiLabel->setHidden(false); + //ratio62Ni58NiEnabled->setHidden(false); + //minratio62Ni58Ni->setHidden(false); + //maxratio62Ni58Ni->setHidden(false); + + //ratio65Cu63CuLabel->setHidden(false); + //ratio65Cu63CuEnabled->setHidden(false); + //minratio65Cu63Cu->setHidden(false); + //maxratio65Cu63Cu->setHidden(false); + + //ratio66Zn64ZnLabel->setHidden(false); + //ratio66Zn64ZnEnabled->setHidden(false); + //minratio66Zn64Zn->setHidden(false); + //maxratio66Zn64Zn->setHidden(false); + + //ratio67Zn64ZnLabel->setHidden(false); + //ratio67Zn64ZnEnabled->setHidden(false); + //minratio67Zn64Zn->setHidden(false); + //maxratio67Zn64Zn->setHidden(false); + + //ratio68Zn64ZnLabel->setHidden(false); + //ratio68Zn64ZnEnabled->setHidden(false); + //minratio68Zn64Zn->setHidden(false); + //maxratio68Zn64Zn->setHidden(false); maximumbricksincombinatiolabel->setHidden(true); maximumbricksincombinationbegin->setHidden(true); @@ -3001,6 +3724,7 @@ void cParametersWidget::updateSettingsWhenModeChanged(int index) { intensitytolerancelabel->setHidden(false); intensitytolerance->setHidden(false); + isotoperatiosgroupbox->setHidden(false); brickdatabasegroupbox->setHidden(true); miscgroupbox->setHidden(true); searchedsequencegroupbox->setHidden(true); diff --git a/CycloBranch/gui/cParametersWidget.h b/CycloBranch/gui/cParametersWidget.h index ae577ae..bf84199 100644 --- a/CycloBranch/gui/cParametersWidget.h +++ b/CycloBranch/gui/cParametersWidget.h @@ -187,11 +187,57 @@ class cParametersWidget : public QWidget QLabel* fwhmlabel; QDoubleSpinBox* fwhm; - QLabel* ratio54Fe56Felabel; + QGroupBox* isotoperatiosgroupbox; + QGridLayout* isotoperatiosgridlayout; + + QLabel* ratio54Fe56FeLabel; + QCheckBox* ratio54Fe56FeEnabled; QDoubleSpinBox* minratio54Fe56Fe; QDoubleSpinBox* maxratio54Fe56Fe; - QHBoxLayout* ratio54Fe56Felayout; - QWidget* ratio54Fe56Fewidget; + QHBoxLayout* ratio54Fe56FeLayout; + QWidget* ratio54Fe56FeWidget; + + QLabel* ratio60Ni58NiLabel; + QCheckBox* ratio60Ni58NiEnabled; + QDoubleSpinBox* minratio60Ni58Ni; + QDoubleSpinBox* maxratio60Ni58Ni; + QHBoxLayout* ratio60Ni58NiLayout; + QWidget* ratio60Ni58NiWidget; + + QLabel* ratio62Ni58NiLabel; + QCheckBox* ratio62Ni58NiEnabled; + QDoubleSpinBox* minratio62Ni58Ni; + QDoubleSpinBox* maxratio62Ni58Ni; + QHBoxLayout* ratio62Ni58NiLayout; + QWidget* ratio62Ni58NiWidget; + + QLabel* ratio65Cu63CuLabel; + QCheckBox* ratio65Cu63CuEnabled; + QDoubleSpinBox* minratio65Cu63Cu; + QDoubleSpinBox* maxratio65Cu63Cu; + QHBoxLayout* ratio65Cu63CuLayout; + QWidget* ratio65Cu63CuWidget; + + QLabel* ratio66Zn64ZnLabel; + QCheckBox* ratio66Zn64ZnEnabled; + QDoubleSpinBox* minratio66Zn64Zn; + QDoubleSpinBox* maxratio66Zn64Zn; + QHBoxLayout* ratio66Zn64ZnLayout; + QWidget* ratio66Zn64ZnWidget; + + QLabel* ratio67Zn64ZnLabel; + QCheckBox* ratio67Zn64ZnEnabled; + QDoubleSpinBox* minratio67Zn64Zn; + QDoubleSpinBox* maxratio67Zn64Zn; + QHBoxLayout* ratio67Zn64ZnLayout; + QWidget* ratio67Zn64ZnWidget; + + QLabel* ratio68Zn64ZnLabel; + QCheckBox* ratio68Zn64ZnEnabled; + QDoubleSpinBox* minratio68Zn64Zn; + QDoubleSpinBox* maxratio68Zn64Zn; + QHBoxLayout* ratio68Zn64ZnLayout; + QWidget* ratio68Zn64ZnWidget; QGroupBox* brickdatabasegroupbox; QGridLayout* brickdatabasegridlayout; diff --git a/CycloBranch/gui/cPatternSimulatorSceneWidget.cpp b/CycloBranch/gui/cPatternSimulatorSceneWidget.cpp index 82af3d0..41607a9 100644 --- a/CycloBranch/gui/cPatternSimulatorSceneWidget.cpp +++ b/CycloBranch/gui/cPatternSimulatorSceneWidget.cpp @@ -433,7 +433,7 @@ void cPatternSimulatorSceneWidget::redrawScene() { double y; qreal tx, ty, tw, th, sumh; - char tmpbuf[30]; + char tmpbuf[500]; string s; int xstep, ystep; diff --git a/CycloBranch/gui/cSpectrumDetailWidget.cpp b/CycloBranch/gui/cSpectrumDetailWidget.cpp index 2cfe1eb..2615843 100644 --- a/CycloBranch/gui/cSpectrumDetailWidget.cpp +++ b/CycloBranch/gui/cSpectrumDetailWidget.cpp @@ -32,6 +32,7 @@ cSpectrumDetailWidget::cSpectrumDetailWidget() { profileintensity64precision = false; rowid = 0; + scantitle.clear(); preparedToShow = false; localneutralosses.clear(); theoreticalspectrum = new cTheoreticalSpectrum(); @@ -58,7 +59,7 @@ cSpectrumDetailWidget& cSpectrumDetailWidget::operator=(const cSpectrumDetailWid theoreticalspectrum = new cTheoreticalSpectrum(); if (parameters && sd.theoreticalspectrum) { - initialize(sd.rowid, sd.activefileid, globalpreferences, parameters, *sd.theoreticalspectrum, sd.parent); + initialize(sd.rowid, sd.scantitle, sd.activefileid, globalpreferences, parameters, *sd.theoreticalspectrum, sd.parent); } if (parameters && sd.preparedToShow) { @@ -71,8 +72,9 @@ cSpectrumDetailWidget& cSpectrumDetailWidget::operator=(const cSpectrumDetailWid } -void cSpectrumDetailWidget::initialize(int rowid, int activefileid, cGlobalPreferences* globalpreferences, cParameters* parameters, cTheoreticalSpectrum& theoreticalspectrum, QWidget* parent) { +void cSpectrumDetailWidget::initialize(int rowid, string scantitle, int activefileid, cGlobalPreferences* globalpreferences, cParameters* parameters, cTheoreticalSpectrum& theoreticalspectrum, QWidget* parent) { this->rowid = rowid; + this->scantitle = scantitle; this->activefileid = activefileid; this->globalpreferences = globalpreferences; this->parameters = parameters; @@ -840,6 +842,7 @@ void cSpectrumDetailWidget::prepareToShow(QAction* actionShowIsomers, cPeakListS actionAbsoluteIntensity->setCheckable(true); toolbarView->addAction(actionAbsoluteIntensity); connect(actionAbsoluteIntensity, SIGNAL(toggled(bool)), spectrumscene, SLOT(absoluteIntensityStateChanged(bool))); + connect(actionAbsoluteIntensity, SIGNAL(toggled(bool)), this, SLOT(absoluteIntensityStateChanged(bool))); actionRawData = new QAction(QIcon(":/images/icons/chromatography.png"), tr("&Profile Spectrum"), this); actionRawData->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P)); @@ -1421,6 +1424,11 @@ bool cSpectrumDetailWidget::hasProfileSpectrumEnabled() { } +void cSpectrumDetailWidget::disableProfileMode() { + actionRawData->setEnabled(false); +} + + void cSpectrumDetailWidget::setAbsoluteIntensityEnabled(bool enable) { actionAbsoluteIntensity->setChecked(enable); } @@ -1742,12 +1750,22 @@ void cSpectrumDetailWidget::preparePeaksTable(QRect geometry) { if (parameters->generateisotopepattern && parameters->calculatefdrs) { peakstablemodel->setItem(i, currentcolumn, new QStandardItem()); peakstablemodel->item(i, currentcolumn)->setForeground(brush); - peakstablemodel->item(i, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(theoreticalspectrum->getTargetPatternScore(peak->groupid))), Qt::DisplayRole); + if (theoreticalspectrum->getTargetPatternScore(peak->groupid) != DBL_MAX) { + peakstablemodel->item(i, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(theoreticalspectrum->getTargetPatternScore(peak->groupid))), Qt::DisplayRole); + } + else { + peakstablemodel->item(i, currentcolumn)->setText("N/A"); + } currentcolumn++; peakstablemodel->setItem(i, currentcolumn, new QStandardItem()); peakstablemodel->item(i, currentcolumn)->setForeground(brush); - peakstablemodel->item(i, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(theoreticalspectrum->getTargetPatternFDR(peak->groupid))), Qt::DisplayRole); + if (theoreticalspectrum->getTargetPatternFDR(peak->groupid) != DBL_MAX) { + peakstablemodel->item(i, currentcolumn)->setData(QVariant::fromValue(cropPrecisionToSixDecimalsByteArray(theoreticalspectrum->getTargetPatternFDR(peak->groupid))), Qt::DisplayRole); + } + else { + peakstablemodel->item(i, currentcolumn)->setText("N/A"); + } currentcolumn++; } } @@ -2392,7 +2410,13 @@ void cSpectrumDetailWidget::rawDataStateChanged(bool state) { fileid = parameters->scannumber; } else { - fileid = rowid; + size_t scanpos = scantitle.find("scan="); + if (scanpos != string::npos) { + fileid = QVariant(scantitle.substr(scanpos + 5).c_str()).toInt(); + } + else { + fileid = rowid; + } } targetid = rowid - 1; @@ -2737,6 +2761,11 @@ void cSpectrumDetailWidget::rawDataStateChanged(bool state) { } +void cSpectrumDetailWidget::absoluteIntensityStateChanged(bool state) { + emit absoluteIntensityStateChangedSignal(actionAbsoluteIntensity->isChecked()); +} + + void cSpectrumDetailWidget::hideMatchedPeaks(bool hide) { spectrumscene->hideMatchedPeaks(hide); filterPeaksTable(); diff --git a/CycloBranch/gui/cSpectrumDetailWidget.h b/CycloBranch/gui/cSpectrumDetailWidget.h index 756fffb..a0b6dc4 100644 --- a/CycloBranch/gui/cSpectrumDetailWidget.h +++ b/CycloBranch/gui/cSpectrumDetailWidget.h @@ -120,13 +120,14 @@ class cSpectrumDetailWidget : public QMainWindow /** \brief Initialize the widget. \param rowid id of a row + \param scantitle scan title \param activefileid id of an active file \param globalpreferences global preferences of the application \param parameters a pointer to parameters \param theoreticalspectrum a reference to a theoretical spectrum \param parent pointer to a parent widget */ - void initialize(int rowid, int activefileid, cGlobalPreferences* globalpreferences, cParameters* parameters, cTheoreticalSpectrum& theoreticalspectrum, QWidget* parent); + void initialize(int rowid, string scantitle, int activefileid, cGlobalPreferences* globalpreferences, cParameters* parameters, cTheoreticalSpectrum& theoreticalspectrum, QWidget* parent); /** @@ -218,6 +219,12 @@ class cSpectrumDetailWidget : public QMainWindow bool hasProfileSpectrumEnabled(); + /** + \brief Permanently disable the visualization in profile mode. + */ + void disableProfileMode(); + + /** \brief Set the state of absolute intensity mode. \param enable state of absolute intensity mode @@ -408,6 +415,7 @@ class cSpectrumDetailWidget : public QMainWindow cTheoreticalSpectrum* theoreticalspectrum; int rowid; + string scantitle; bool preparedToShow; set localneutralosses; @@ -451,6 +459,13 @@ class cSpectrumDetailWidget : public QMainWindow void rawDataStateChangedSignal(bool state); + /** + \brief The signal is emitted when the absolute intensity state was changed. + \param state current state + */ + void absoluteIntensityStateChangedSignal(bool state); + + /** \brief The signal is emitted when the widget has been moved. \param rowid rowid of the widget @@ -497,6 +512,9 @@ private slots: void rawDataStateChanged(bool state); + void absoluteIntensityStateChanged(bool state); + + void hideMatchedPeaks(bool hide); diff --git a/CycloBranch/gui/cSpectrumSceneWidget.cpp b/CycloBranch/gui/cSpectrumSceneWidget.cpp index 0993b41..3b476d8 100644 --- a/CycloBranch/gui/cSpectrumSceneWidget.cpp +++ b/CycloBranch/gui/cSpectrumSceneWidget.cpp @@ -429,7 +429,7 @@ void cSpectrumSceneWidget::redrawScene() { double y; qreal tx, ty, tw, th, sumh; - char tmpbuf[30]; + char tmpbuf[500]; string s; int xstep, ystep; @@ -586,7 +586,12 @@ void cSpectrumSceneWidget::redrawScene() { } if ((parameters->mode == dereplication) || (parameters->mode == compoundsearch)) { - visiblepeaks[visiblepeakscount].description += parameters->peakidtodesc[thpeaks[*it].descriptionid].substr(0, parameters->peakidtodesc[thpeaks[*it].descriptionid].rfind(':')); + if (thpeaks[*it].descriptionid >= 0) { + visiblepeaks[visiblepeakscount].description += parameters->peakidtodesc[thpeaks[*it].descriptionid].substr(0, parameters->peakidtodesc[thpeaks[*it].descriptionid].rfind(':')); + } + else { + visiblepeaks[visiblepeakscount].description += thpeaks[*it].description.substr(0, thpeaks[*it].description.rfind(':')); + } } else { visiblepeaks[visiblepeakscount].description += parameters->peakidtodesc[thpeaks[*it].descriptionid].substr(0, parameters->peakidtodesc[thpeaks[*it].descriptionid].find(':')); @@ -625,7 +630,7 @@ void cSpectrumSceneWidget::redrawScene() { string tmpvisibleneutralloss; size_t tmpposition; set localneutrallosses = ((cSpectrumDetailWidget *)parent)->getLocalNeutralLosses(); - for (int i = 0; i < (int)visiblepeaks.size(); i++) { + for (int i = 0; i < visiblepeaks.size(); i++) { x = getXPositionFromMZRatio(visiblepeaks[i].mzratio, w); @@ -840,36 +845,38 @@ void cSpectrumSceneWidget::redrawScene() { line = scene->addLine(x, h - bottommargin - 2, x, h - bottommargin - std::max((int)y, 2), QPen(Qt::red, 2, Qt::SolidLine)); line->setZValue(2); - hiddenitems.clear(); - sumh = 0; - for (vector::reverse_iterator rit = hits.rbegin(); rit != hits.rend(); ++rit) { - text = scene->addText(""); - text->setDefaultTextColor(QColor(Qt::red)); - text->setFont(myFont); - if ((parameters->mode == dereplication) || (parameters->mode == compoundsearch)) { - text->setTextInteractionFlags(Qt::TextBrowserInteraction); - text->setOpenExternalLinks(true); - } - text->setHtml(rit->c_str()); - tw = text->boundingRect().width(); - th = text->boundingRect().height(); - sumh += th + 1; - tx = x - 2 - 4; - ty = h - bottommargin - std::max((int)y, 2) - sumh - 4; - text->setPos(tx, ty); - text->setZValue(2); - - hiddenitems.append(text); - - if (scene->items(tx, ty, tw, th, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder).size() > 1) { - for (int k = 0; k < (int)hiddenitems.size(); k++) { - scene->removeItem(hiddenitems[k]); + if (i < 100) { + hiddenitems.clear(); + sumh = 0; + for (vector::reverse_iterator rit = hits.rbegin(); rit != hits.rend(); ++rit) { + text = scene->addText(""); + text->setDefaultTextColor(QColor(Qt::red)); + text->setFont(myFont); + if ((parameters->mode == dereplication) || (parameters->mode == compoundsearch)) { + text->setTextInteractionFlags(Qt::TextBrowserInteraction); + text->setOpenExternalLinks(true); + } + text->setHtml(rit->c_str()); + tw = text->boundingRect().width(); + th = text->boundingRect().height(); + sumh += th + 1; + tx = x - 2 - 4; + ty = h - bottommargin - std::max((int)y, 2) - sumh - 4; + text->setPos(tx, ty); + text->setZValue(2); + + hiddenitems.append(text); + + if (scene->items(tx, ty, tw, th, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder).size() > 1) { + for (int k = 0; k < (int)hiddenitems.size(); k++) { + scene->removeItem(hiddenitems[k]); + } + break; } - break; - } - if (hidelabels) { - break; + if (hidelabels) { + break; + } } } } @@ -877,17 +884,19 @@ void cSpectrumSceneWidget::redrawScene() { line = scene->addLine(x, h - bottommargin - 2, x, h - bottommargin - std::max((int)y, 2), QPen(Qt::black, 2, Qt::SolidLine)); line->setZValue(1); - simpletext = scene->addSimpleText(hits[0].c_str(), myFont); - tw = simpletext->boundingRect().width(); - th = simpletext->boundingRect().height(); - tx = x - 2; - ty = h - bottommargin - std::max((int)y, 2) - th - 1 - 4; - simpletext->setPos(tx, ty); - simpletext->setBrush(Qt::black); - simpletext->setZValue(1); - - if (scene->items(tx, ty, tw, th, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder).size() > 1) { - scene->removeItem(simpletext); + if (i < 100) { + simpletext = scene->addSimpleText(hits[0].c_str(), myFont); + tw = simpletext->boundingRect().width(); + th = simpletext->boundingRect().height(); + tx = x - 2; + ty = h - bottommargin - std::max((int)y, 2) - th - 1 - 4; + simpletext->setPos(tx, ty); + simpletext->setBrush(Qt::black); + simpletext->setZValue(1); + + if (scene->items(tx, ty, tw, th, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder).size() > 1) { + scene->removeItem(simpletext); + } } } diff --git a/CycloBranch/gui/cSummaryPeaksTableWidget.cpp b/CycloBranch/gui/cSummaryPeaksTableWidget.cpp index 35b8305..71e418c 100644 --- a/CycloBranch/gui/cSummaryPeaksTableWidget.cpp +++ b/CycloBranch/gui/cSummaryPeaksTableWidget.cpp @@ -44,9 +44,20 @@ void addEICPeak(cParameters* parameters, cPeaksList& eicchromatogram, cTheoretic if (theoreticalspectrum[i].matched > 0) { matcheditem.clear(); - pos = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].find(""); + if (theoreticalspectrum[i].descriptionid >= 0) { + pos = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].find(""); + } + else { + pos = theoreticalspectrum[i].description.find(""); + } + if (pos != string::npos) { - matcheditem = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].substr(0, pos + 4); + if (theoreticalspectrum[i].descriptionid >= 0) { + matcheditem = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].substr(0, pos + 4); + } + else { + matcheditem = theoreticalspectrum[i].description.substr(0, pos + 4); + } } if (!matcheditem.empty()) { @@ -976,7 +987,7 @@ void cSummaryPeaksTableWidget::filterTablerows() { void cSummaryPeaksTableWidget::filterCompound(string name, string iontype, int datatypeview, string mzstr) { - if ((datatypeview == 0) || (datatypeview == 1) || (datatypeview == 4) || (datatypeview == 5)) { + if ((datatypeview == 0) || (datatypeview == 1) || (datatypeview == 4) || (datatypeview == 5) || (datatypeview == 6)) { rowsfiltercombobox1->setCurrentText("Theoretical m/z"); rowsfiltercomparatorcombobox1->setCurrentText("="); rowsfilterline1->setText(mzstr.c_str()); @@ -1026,14 +1037,35 @@ void cSummaryPeaksTableWidget::addCoordinateInfo(int spectrumindex, vector 0) { matcheditem.clear(); - pos1 = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].find('<'); + if (theoreticalspectrum[i].descriptionid >= 0) { + pos1 = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].find('<'); + } + else { + pos1 = theoreticalspectrum[i].description.find('<'); + } + if (pos1 != string::npos) { - matcheditem = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].substr(0, pos1 - 1); - pos1 = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].rfind(""); - pos2 = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].find('>'); + if (theoreticalspectrum[i].descriptionid >= 0) { + matcheditem = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].substr(0, pos1 - 1); + pos1 = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].rfind(""); + pos2 = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].find('>'); + } + else { + matcheditem = theoreticalspectrum[i].description.substr(0, pos1 - 1); + pos1 = theoreticalspectrum[i].description.rfind(""); + pos2 = theoreticalspectrum[i].description.find('>'); + } + if ((pos1 != string::npos) && (pos2 != string::npos)) { - tmpstr = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].substr(pos2 + 1, pos1 - pos2 - 1); + + if (theoreticalspectrum[i].descriptionid >= 0) { + tmpstr = parameters->peakidtodesc[theoreticalspectrum[i].descriptionid].substr(pos2 + 1, pos1 - pos2 - 1); + } + else { + tmpstr = theoreticalspectrum[i].description.substr(pos2 + 1, pos1 - pos2 - 1); + } + if (tmpstr.size() > 40) { matcheditem += tmpstr.substr(0, 37) + "..."; } diff --git a/CycloBranch/parallel/cSpectrumComparatorThreadMS2.cpp b/CycloBranch/parallel/cSpectrumComparatorThreadMS2.cpp index da408cf..c1a0bd7 100644 --- a/CycloBranch/parallel/cSpectrumComparatorThreadMS2.cpp +++ b/CycloBranch/parallel/cSpectrumComparatorThreadMS2.cpp @@ -184,6 +184,28 @@ bool compareWeightedRatioDesc(const cTheoreticalSpectrum& a, const cTheoreticalS } +bool compareCosineSimilarityDesc(const cTheoreticalSpectrum& a, const cTheoreticalSpectrum& b) { + if (a.getCosineSimilarity() > b.getCosineSimilarity()) { + return true; + } + if (a.getCosineSimilarity() < b.getCosineSimilarity()) { + return false; + } + + if (a.getPathId() < b.getPathId()) { + return true; + } + if (a.getPathId() > b.getPathId()) { + return false; + } + + vector v1 = ((cTheoreticalSpectrum&)a).getCandidate().getPath(); + vector v2 = ((cTheoreticalSpectrum&)b).getCandidate().getPath(); + + return comparePaths(v1, v2); +} + + void cSpectrumComparatorThreadMS2::initialize(cCandidate& candidate, cPeaksList& peaklist, cBricksDatabase* bricksdatabasewithcombinations, cTheoreticalSpectrumList* theoreticalspectrumlist, cParameters* parameters, regex* rxsequencetag, regex* rxsearchedsequence, double currentworstscore, bool* terminatecomputation) { this->candidate = candidate; this->peaklist = peaklist; @@ -287,6 +309,9 @@ void cSpectrumComparatorThreadMS2::run() { case weighted_ratio_of_matched_peaks: score = tsp.getWeightedRatioOfMatchedPeaks(); break; + case cosine_similarity: + score = tsp.getCosineSimilarity(); + break; default: break; } diff --git a/CycloBranch/parallel/cSpectrumComparatorThreadMS2.h b/CycloBranch/parallel/cSpectrumComparatorThreadMS2.h index f72913b..5b6f592 100644 --- a/CycloBranch/parallel/cSpectrumComparatorThreadMS2.h +++ b/CycloBranch/parallel/cSpectrumComparatorThreadMS2.h @@ -78,6 +78,15 @@ bool compareNumberOfMatchedPeaksDesc(const cTheoreticalSpectrum& a, const cTheor bool compareWeightedRatioDesc(const cTheoreticalSpectrum& a, const cTheoreticalSpectrum& b); +/** + \brief Compare scores of two theoretical spectra (cosine similarity). + \param a first theoretical spectrum + \param b second theoretical spectrum + \retval bool true if the score of \a a is greater than the score of \a b +*/ +bool compareCosineSimilarityDesc(const cTheoreticalSpectrum& a, const cTheoreticalSpectrum& b); + + /** \brief The class representing a thread for comparison of a theoretical spectrum with a peak list (MS2 level). */ diff --git a/README.md b/README.md index 0e06b76..dc5964c 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,12 @@ A tool for mass spectrometry data analysis. * imaging mass spectra (MSI) * tandem mass spectra (MS/MS) * main features - * MS, LC-MC, MSI + * MS, LC-MS, MSI * dereplication / database search * prediction of elemental compositions of unknown compounds * fine isotopic structure + * LC-MS + * quantitation of small molecules * MSI * pixel-by-pixel analysis of imaging mass spectra (imzML) * fusion of imzML files with optical and histology images @@ -56,8 +58,10 @@ A tool for mass spectrometry data analysis. https://ms.biomed.cas.cz/cyclobranch/ ## References and More Information + * quantitation of small molecules in LC-MS data + * Novak J. et al. Quantitation of Small Molecules from Liquid Chromatography-Mass Spectrometric Accurate Mass Datasets using CycloBranch. *Eur. J. Mass Spectrom.*, 29(2):102-110, 2023. DOI: [10.1177/14690667231164766](https://doi.org/10.1177/14690667231164766) * molecular formula annotations - * Novak J. et al. CycloBranch 2: Molecular Formula Annotations Applied to imzML Data Sets in Bimodal Fusion and LC-MS Data Files. *Anal. Chem.*, 92(10):6844–6849, 2020. DOI: [10.1021/acs.analchem.0c00170](https://doi.org/10.1021/acs.analchem.0c00170) + * Novak J. et al. CycloBranch 2: Molecular Formula Annotations Applied to imzML Data Sets in Bimodal Fusion and LC-MS Data Files. *Anal. Chem.*, 92(10):6844–6849, 2020. DOI: [10.1021/acs.analchem.0c00170](https://doi.org/10.1021/acs.analchem.0c00170) * configuration of the tool for different use cases * Pluhacek T. et al. Analysis of Microbial Siderophores by Mass Spectrometry. In Sanjoy K. Bhattacharya (ed.), *Metabolomics: Methods and Protocols*, Methods in Molecular Biology, 1996:131-153, Springer, 2019. DOI: [10.1007/978-1-4939-9488-5_12](https://doi.org/10.1007/978-1-4939-9488-5_12) * isotopic fine structure