diff --git a/CycloBranch/CycloBranch.vcxproj b/CycloBranch/CycloBranch.vcxproj index 58c9984..8f40608 100644 --- a/CycloBranch/CycloBranch.vcxproj +++ b/CycloBranch/CycloBranch.vcxproj @@ -157,6 +157,7 @@ + @@ -187,6 +188,10 @@ true true + + true + true + true true @@ -239,6 +244,10 @@ true true + + true + true + true true @@ -269,6 +278,7 @@ + @@ -289,7 +299,26 @@ + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing cLassoWidget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing cLassoWidget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing cLassoWidget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing cLassoWidget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" + $(QTDIR)\bin\moc.exe;%(FullPath) Moc%27ing cLinearWidget.h... diff --git a/CycloBranch/CycloBranch.vcxproj.filters b/CycloBranch/CycloBranch.vcxproj.filters index cd10613..8b5ead7 100644 --- a/CycloBranch/CycloBranch.vcxproj.filters +++ b/CycloBranch/CycloBranch.vcxproj.filters @@ -200,6 +200,18 @@ Source Files\gui + + Generated Files\Debug + + + Generated Files\Release + + + Source Files\gui + + + Source Files\core + @@ -244,6 +256,9 @@ Header Files\gui + + Header Files\gui + @@ -279,5 +294,8 @@ Header Files\core + + Header Files\core + \ No newline at end of file diff --git a/CycloBranch/core/cBricksDatabase.cpp b/CycloBranch/core/cBricksDatabase.cpp index 9236a5b..6e462d6 100644 --- a/CycloBranch/core/cBricksDatabase.cpp +++ b/CycloBranch/core/cBricksDatabase.cpp @@ -117,6 +117,7 @@ int cBricksDatabase::loadFromPlainTextStream(ifstream &stream, string& errormess bool error = false; errormessage = ""; + cSummaryFormula formula; while (stream.good()) { getline(stream,s); @@ -182,9 +183,13 @@ int cBricksDatabase::loadFromPlainTextStream(ifstream &stream, string& errormess if (!b.empty()) { // calculate mass from the summary - b.setMass(getMassFromResidueSummary(b.getSummary(), error, errormessage)); - - if (error) { + formula.clear(); + formula.setFormula(b.getSummary()); + if (formula.isValid(errormessage)) { + b.setMass(formula.getMass()); + } + else { + error = true; break; } @@ -195,7 +200,6 @@ int cBricksDatabase::loadFromPlainTextStream(ifstream &stream, string& errormess } bricks.push_back(b); - //cout << b.getSummary() << " " << b.getMass() << endl; } } diff --git a/CycloBranch/core/cBricksDatabase.h b/CycloBranch/core/cBricksDatabase.h index 969c17b..1d39c27 100644 --- a/CycloBranch/core/cBricksDatabase.h +++ b/CycloBranch/core/cBricksDatabase.h @@ -15,6 +15,7 @@ #include "core/cBrick.h" +#include "core/cSummaryFormula.h" using namespace std; diff --git a/CycloBranch/core/cCandidate.cpp b/CycloBranch/core/cCandidate.cpp index 7c87673..7c96f73 100644 --- a/CycloBranch/core/cCandidate.cpp +++ b/CycloBranch/core/cCandidate.cpp @@ -487,38 +487,6 @@ int cCandidate::getBranchEnd() { } -void cCandidate::getBackboneAcronyms(cBricksDatabase& bricksdatabase, vector& acronyms) { - vector bricks; - cBrick b; - b.clear(); - b.setComposition(getComposition(), false); - b.explodeToIntComposition(bricks); - - acronyms.clear(); - for (int i = 0; i < (int)bricks.size(); i++) { - if ((branchstart >= 0) && (branchend >= 0) && ((i <= branchstart) || (i > branchend))) { - acronyms.push_back(bricksdatabase[bricks[i] - 1].getAcronymsAsString()); - } - } -} - - -void cCandidate::getBranchAcronyms(cBricksDatabase& bricksdatabase, vector& acronyms) { - vector bricks; - cBrick b; - b.clear(); - b.setComposition(getComposition(), false); - b.explodeToIntComposition(bricks); - - acronyms.clear(); - for (int i = 0; i < (int)bricks.size(); i++) { - if ((branchstart >= 0) && (branchend >= 0) && (i > branchstart) && (i <= branchend)) { - acronyms.push_back(bricksdatabase[bricks[i] - 1].getAcronymsAsString()); - } - } -} - - void cCandidate::getPermutationsOfBranches(vector& tpermutations) { tpermutations.resize(6); for (int i = 0; i < (int)tpermutations.size(); i++) { @@ -738,7 +706,6 @@ double cCandidate::getPrecursorMass(cBricksDatabase& brickdatabasewithcombinatio } return mass; - } @@ -906,6 +873,52 @@ void cCandidate::getLassoRotations(vector& lassorotations, bool incl } +string cCandidate::getSummaryFormula(cParameters& parameters) { + cBrick b; + vector bricks; + b.setComposition(internalcomposition, false); + b.explodeToIntComposition(bricks); + + cSummaryFormula formula; + string summary; + + switch (parameters.peptidetype) + { + case linear: + case linearpolysaccharide: + summary = "H2O"; + formula.addFormula(summary); + formula.addFormula(parameters.searchedmodifications[startmodifID].summary); + formula.addFormula(parameters.searchedmodifications[endmodifID].summary); + break; + case cyclic: + break; + case branched: + summary = "H2O"; + formula.addFormula(summary); + formula.addFormula(parameters.searchedmodifications[startmodifID].summary); + formula.addFormula(parameters.searchedmodifications[endmodifID].summary); + formula.addFormula(parameters.searchedmodifications[middlemodifID].summary); + break; + case lasso: + formula.addFormula(parameters.searchedmodifications[middlemodifID].summary); + break; + } + + bool partial = false; + for (int i = 0; i < (int)bricks.size(); i++) { + if (bricks[i] - 1 < (int)parameters.bricksdatabase.size()) { + formula.addFormula(parameters.bricksdatabase[bricks[i] - 1].getSummary()); + } + else { + partial = true; + } + } + + return partial?formula.getFormula() + " (partial)":formula.getFormula(); +} + + void cCandidate::store(ofstream& os) { int size; diff --git a/CycloBranch/core/cCandidate.h b/CycloBranch/core/cCandidate.h index 4f0df3f..f9f06fd 100644 --- a/CycloBranch/core/cCandidate.h +++ b/CycloBranch/core/cCandidate.h @@ -12,9 +12,9 @@ #include #include "core/cParameters.h" -#include "core/cFragmentIons.h" #include "core/cBricksDatabase.h" #include "core/cDeNovoGraphNode.h" +#include "core/cSummaryFormula.h" class cCandidateSet; @@ -289,22 +289,6 @@ class cCandidate { int getBranchEnd(); - /** - \brief Get acronyms of blocks on a backbone of a branched peptide. - \param bricksdatabase reference to the database of bricks - \param acronyms an output vector of string acronyms - */ - void getBackboneAcronyms(cBricksDatabase& bricksdatabase, vector& acronyms); - - - /** - \brief Get acronyms of blocks on a branch of a branched peptide. - \param bricksdatabase reference to the database of bricks - \param acronyms an output vector of string acronyms - */ - void getBranchAcronyms(cBricksDatabase& bricksdatabase, vector& acronyms); - - /** \brief Get permutations of branches a branched peptide. \param tpermutations reference to an output vector of auxiliary structures where permutations will be stored @@ -426,6 +410,14 @@ class cCandidate { void getLassoRotations(vector& lassorotations, bool includerevertedrotations); + /** + \brief Get the summary formula of the peptide sequence candidate. + \param parameters a reference to the parameters of the application + \retval string the summary formula + */ + string getSummaryFormula(cParameters& parameters); + + /** \brief Store the structure into an output stream. \param os an output stream diff --git a/CycloBranch/core/cFragmentIons.cpp b/CycloBranch/core/cFragmentIons.cpp index fe4c28b..82758cf 100644 --- a/CycloBranch/core/cFragmentIons.cpp +++ b/CycloBranch/core/cFragmentIons.cpp @@ -46,99 +46,6 @@ int cPeriodicTableMap::count(string& element) { } -double getMassFromResidueSummary(string& summary, bool& error, string& errormessage) { - if ((int)summary.size() == 0) { - return 0; - } - - regex rx; - rx = "^([A-Z][a-z]*((-[0-9]+)|([0-9]*))*)+$"; - - try { - if (!regex_search(summary, rx)) { - error = true; - errormessage = "Invalid summary: " + summary + ".\n\n"; - return 0; - } - } - catch (std::regex_error& e) { - error = true; - errormessage = "getMassFromResidueSummary: regex_search failed, error no. " + to_string((int)e.code()) + "\n"; - return 0; - } - - // calculate mass from summary - error = false; - errormessage = ""; - - cPeriodicTableMap map; - double sum = 0; - - string tmps; - tmps = summary[0]; - - int tmpc = 0; - - bool minus = false; - - for (int i = 1; i < (int)summary.size(); i++) { - - if ((summary[i] >= 'A') && (summary[i] <= 'Z')) { - if (map.count(tmps) > 0) { - if (tmpc == 0) { - sum += map[tmps]; - } - else { - sum += minus?-tmpc*map[tmps]:tmpc*map[tmps]; - } - //cout << tmps << " " << (minus?"-":"") << tmpc << endl; - } - else { - error = true; - errormessage = "Undefined atom name: " + tmps + ".\n\n"; - return 0; - } - - tmps = summary[i]; - tmpc = 0; - minus = false; - } - - if ((summary[i] >= 'a') && (summary[i] <= 'z')) { - tmps += summary[i]; - } - - if ((summary[i] >= '0') && (summary[i] <= '9')) { - tmpc *= 10; - tmpc += summary[i] - '0'; - } - - if (summary[i] == '-') { - minus = true; - } - - } - - // last element - if (map.count(tmps) > 0) { - if (tmpc == 0) { - sum += map[tmps]; - } - else { - sum += minus?-tmpc*map[tmps]:tmpc*map[tmps]; - } - //cout << tmps << " " << (minus?"-":"") << tmpc << endl; - } - else { - error = true; - errormessage = "Undefined atom name: " + tmps + ".\n\n"; - return 0; - } - - return sum; -} - - double charge(double mass, int charge) { return (mass + ((double)(charge - 1))*Hplus)/(double)charge; } @@ -294,112 +201,112 @@ void cFragmentIons::recalculateFragments(bool cyclicnterminus, bool cyclicctermi // initialize precursor ion fragmentions[precursor_ion].nterminal = false; fragmentions[precursor_ion].cterminal = false; - fragmentions[precursor_ion].name = "M"; + fragmentions[precursor_ion].name = "[M+zH]+"; fragmentions[precursor_ion].massdifference = PRECURSOR_ION + nterminusshift + cterminusshift; fragmentions[precursor_ion].parent = precursor_ion; // initialize precursor ion - H2O fragmentions[precursor_ion_water_loss].nterminal = false; fragmentions[precursor_ion_water_loss].cterminal = false; - fragmentions[precursor_ion_water_loss].name = "M*"; + fragmentions[precursor_ion_water_loss].name = "[M+zH]+ *"; fragmentions[precursor_ion_water_loss].massdifference = PRECURSOR_ION - H2O + nterminusshift + cterminusshift; fragmentions[precursor_ion_water_loss].parent = precursor_ion; // initialize precursor ion - NH3 fragmentions[precursor_ion_ammonia_loss].nterminal = false; fragmentions[precursor_ion_ammonia_loss].cterminal = false; - fragmentions[precursor_ion_ammonia_loss].name = "Mx"; + fragmentions[precursor_ion_ammonia_loss].name = "[M+zH]+ x"; fragmentions[precursor_ion_ammonia_loss].massdifference = PRECURSOR_ION - NH3 + nterminusshift + cterminusshift; fragmentions[precursor_ion_ammonia_loss].parent = precursor_ion; // initialize precursor ion - H2O - NH3 fragmentions[precursor_ion_water_and_ammonia_loss].nterminal = false; fragmentions[precursor_ion_water_and_ammonia_loss].cterminal = false; - fragmentions[precursor_ion_water_and_ammonia_loss].name = "M*x"; + fragmentions[precursor_ion_water_and_ammonia_loss].name = "[M+zH]+ *x"; fragmentions[precursor_ion_water_and_ammonia_loss].massdifference = PRECURSOR_ION - H2O - NH3 + nterminusshift + cterminusshift; fragmentions[precursor_ion_water_and_ammonia_loss].parent = precursor_ion; // initialize precursor ion - CO fragmentions[precursor_ion_co_loss].nterminal = false; fragmentions[precursor_ion_co_loss].cterminal = false; - fragmentions[precursor_ion_co_loss].name = "M-CO"; + fragmentions[precursor_ion_co_loss].name = "[M+zH]+ -CO"; fragmentions[precursor_ion_co_loss].massdifference = PRECURSOR_ION - CO + nterminusshift + cterminusshift; fragmentions[precursor_ion_co_loss].parent = precursor_ion; // initialize precursor ion - CO - H2O fragmentions[precursor_ion_co_loss_water_loss].nterminal = false; fragmentions[precursor_ion_co_loss_water_loss].cterminal = false; - fragmentions[precursor_ion_co_loss_water_loss].name = "M*-CO"; + fragmentions[precursor_ion_co_loss_water_loss].name = "[M+zH]+ *-CO"; fragmentions[precursor_ion_co_loss_water_loss].massdifference = PRECURSOR_ION - CO - H2O + nterminusshift + cterminusshift; fragmentions[precursor_ion_co_loss_water_loss].parent = precursor_ion_co_loss; // initialize precursor ion - CO - NH3 fragmentions[precursor_ion_co_loss_ammonia_loss].nterminal = false; fragmentions[precursor_ion_co_loss_ammonia_loss].cterminal = false; - fragmentions[precursor_ion_co_loss_ammonia_loss].name = "Mx-CO"; + fragmentions[precursor_ion_co_loss_ammonia_loss].name = "[M+zH]+ x-CO"; fragmentions[precursor_ion_co_loss_ammonia_loss].massdifference = PRECURSOR_ION - CO - NH3 + nterminusshift + cterminusshift; fragmentions[precursor_ion_co_loss_ammonia_loss].parent = precursor_ion_co_loss; // initialize precursor ion - CO - H2O - NH3 fragmentions[precursor_ion_co_loss_water_and_ammonia_loss].nterminal = false; fragmentions[precursor_ion_co_loss_water_and_ammonia_loss].cterminal = false; - fragmentions[precursor_ion_co_loss_water_and_ammonia_loss].name = "M*x-CO"; + fragmentions[precursor_ion_co_loss_water_and_ammonia_loss].name = "[M+zH]+ *x-CO"; fragmentions[precursor_ion_co_loss_water_and_ammonia_loss].massdifference = PRECURSOR_ION - CO - H2O - NH3 + nterminusshift + cterminusshift; fragmentions[precursor_ion_co_loss_water_and_ammonia_loss].parent = precursor_ion_co_loss; // initialize cyclic precursor ion fragmentions[cyclic_precursor_ion].nterminal = false; fragmentions[cyclic_precursor_ion].cterminal = false; - fragmentions[cyclic_precursor_ion].name = "M"; + fragmentions[cyclic_precursor_ion].name = "[M+zH]+"; fragmentions[cyclic_precursor_ion].massdifference = PRECURSOR_ION_CYCLIC; fragmentions[cyclic_precursor_ion].parent = cyclic_precursor_ion; // initialize cyclic precursor ion - H2O fragmentions[cyclic_precursor_ion_water_loss].nterminal = false; fragmentions[cyclic_precursor_ion_water_loss].cterminal = false; - fragmentions[cyclic_precursor_ion_water_loss].name = "M*"; + fragmentions[cyclic_precursor_ion_water_loss].name = "[M+zH]+ *"; fragmentions[cyclic_precursor_ion_water_loss].massdifference = PRECURSOR_ION_CYCLIC - H2O; fragmentions[cyclic_precursor_ion_water_loss].parent = cyclic_precursor_ion; // initialize cyclic precursor ion - NH3 fragmentions[cyclic_precursor_ion_ammonia_loss].nterminal = false; fragmentions[cyclic_precursor_ion_ammonia_loss].cterminal = false; - fragmentions[cyclic_precursor_ion_ammonia_loss].name = "Mx"; + fragmentions[cyclic_precursor_ion_ammonia_loss].name = "[M+zH]+ x"; fragmentions[cyclic_precursor_ion_ammonia_loss].massdifference = PRECURSOR_ION_CYCLIC - NH3; fragmentions[cyclic_precursor_ion_ammonia_loss].parent = cyclic_precursor_ion; // initialize cyclic precursor ion - H2O - NH3 fragmentions[cyclic_precursor_ion_water_and_ammonia_loss].nterminal = false; fragmentions[cyclic_precursor_ion_water_and_ammonia_loss].cterminal = false; - fragmentions[cyclic_precursor_ion_water_and_ammonia_loss].name = "M*x"; + fragmentions[cyclic_precursor_ion_water_and_ammonia_loss].name = "[M+zH]+ *x"; fragmentions[cyclic_precursor_ion_water_and_ammonia_loss].massdifference = PRECURSOR_ION_CYCLIC - H2O - NH3; fragmentions[cyclic_precursor_ion_water_and_ammonia_loss].parent = cyclic_precursor_ion; // initialize cyclic precursor ion - CO fragmentions[cyclic_precursor_ion_co_loss].nterminal = false; fragmentions[cyclic_precursor_ion_co_loss].cterminal = false; - fragmentions[cyclic_precursor_ion_co_loss].name = "M-CO"; + fragmentions[cyclic_precursor_ion_co_loss].name = "[M+zH]+ -CO"; fragmentions[cyclic_precursor_ion_co_loss].massdifference = PRECURSOR_ION_CYCLIC - CO; fragmentions[cyclic_precursor_ion_co_loss].parent = cyclic_precursor_ion; // initialize cyclic precursor ion - CO - H2O fragmentions[cyclic_precursor_ion_co_loss_water_loss].nterminal = false; fragmentions[cyclic_precursor_ion_co_loss_water_loss].cterminal = false; - fragmentions[cyclic_precursor_ion_co_loss_water_loss].name = "M*-CO"; + fragmentions[cyclic_precursor_ion_co_loss_water_loss].name = "[M+zH]+ *-CO"; fragmentions[cyclic_precursor_ion_co_loss_water_loss].massdifference = PRECURSOR_ION_CYCLIC - CO - H2O; fragmentions[cyclic_precursor_ion_co_loss_water_loss].parent = cyclic_precursor_ion_co_loss; // initialize cyclic precursor ion - CO - NH3 fragmentions[cyclic_precursor_ion_co_loss_ammonia_loss].nterminal = false; fragmentions[cyclic_precursor_ion_co_loss_ammonia_loss].cterminal = false; - fragmentions[cyclic_precursor_ion_co_loss_ammonia_loss].name = "Mx-CO"; + fragmentions[cyclic_precursor_ion_co_loss_ammonia_loss].name = "[M+zH]+ x-CO"; fragmentions[cyclic_precursor_ion_co_loss_ammonia_loss].massdifference = PRECURSOR_ION_CYCLIC - CO - NH3; fragmentions[cyclic_precursor_ion_co_loss_ammonia_loss].parent = cyclic_precursor_ion_co_loss; // initialize cyclic precursor ion - CO - H2O - NH3 fragmentions[cyclic_precursor_ion_co_loss_water_and_ammonia_loss].nterminal = false; fragmentions[cyclic_precursor_ion_co_loss_water_and_ammonia_loss].cterminal = false; - fragmentions[cyclic_precursor_ion_co_loss_water_and_ammonia_loss].name = "M*x-CO"; + fragmentions[cyclic_precursor_ion_co_loss_water_and_ammonia_loss].name = "[M+zH]+ *x-CO"; fragmentions[cyclic_precursor_ion_co_loss_water_and_ammonia_loss].massdifference = PRECURSOR_ION_CYCLIC - CO - H2O - NH3; fragmentions[cyclic_precursor_ion_co_loss_water_and_ammonia_loss].parent = cyclic_precursor_ion_co_loss; diff --git a/CycloBranch/core/cFragmentIons.h b/CycloBranch/core/cFragmentIons.h index 446d47a..77597c7 100644 --- a/CycloBranch/core/cFragmentIons.h +++ b/CycloBranch/core/cFragmentIons.h @@ -90,16 +90,6 @@ class cPeriodicTableMap { }; -/** - \brief Compute mass from summary molecular formula. - \param summary reference to a string with summary molecular formula - \param error reference to an output boolean value; when the value is true, an error occurred - \param errormessage reference to an output string value; filled when an error occurred - \retval double mass corresponding to the formula -*/ -double getMassFromResidueSummary(string& summary, bool& error, string& errormessage); - - const double H2O = 2 * H + O; const double NH3 = 3 * H + N; const double CO = C + O; diff --git a/CycloBranch/core/cParameters.cpp b/CycloBranch/core/cParameters.cpp index 3898c81..46bb8d3 100644 --- a/CycloBranch/core/cParameters.cpp +++ b/CycloBranch/core/cParameters.cpp @@ -433,7 +433,7 @@ string cParameters::printToString() { s += "Searched Peptide Sequence: " + originalsearchedsequence + "\n"; s += "N-terminal Modification of Searched Peptide Sequence: " + searchedsequenceNtermmodif + "\n"; s += "C-terminal Modification of Searched Peptide Sequence: " + searchedsequenceCtermmodif + "\n"; - s += "T-Modification of Searched Peptide Sequence: " + searchedsequenceTmodif + "\n"; + s += "Branch Modification of Searched Peptide Sequence: " + searchedsequenceTmodif + "\n"; s += "\n"; diff --git a/CycloBranch/core/cPeak.cpp b/CycloBranch/core/cPeak.cpp index cf44ede..20fbc2b 100644 --- a/CycloBranch/core/cPeak.cpp +++ b/CycloBranch/core/cPeak.cpp @@ -20,7 +20,6 @@ void cPeak::clear() { scrambled = false; rotationid = -1; - matchedrotations.clear(); seriesid = -1; } @@ -31,16 +30,6 @@ bool cPeak::empty() { } -bool cPeak::hasMatchedRotation(int rotationid) { - for (int i = 0; i < (int)matchedrotations.size(); i++) { - if (rotationid == matchedrotations[i]) { - return true; - } - } - return false; -} - - void cPeak::store(ofstream& os) { int size; @@ -60,13 +49,6 @@ void cPeak::store(ofstream& os) { os.write((char *)&matchedid, sizeof(int)); os.write((char *)&charge, sizeof(int)); os.write((char *)&rotationid, sizeof(int)); - - size = (int)matchedrotations.size(); - os.write((char *)&size, sizeof(int)); - for (int i = 0; i < (int)matchedrotations.size(); i++) { - os.write((char *)&matchedrotations[i], sizeof(int)); - } - os.write((char *)&seriesid, sizeof(int)); os.write((char *)&isotope, sizeof(bool)); os.write((char *)&removeme, sizeof(bool)); @@ -93,13 +75,6 @@ void cPeak::load(ifstream& is) { is.read((char *)&matchedid, sizeof(int)); is.read((char *)&charge, sizeof(int)); is.read((char *)&rotationid, sizeof(int)); - - is.read((char *)&size, sizeof(int)); - matchedrotations.resize(size); - for (int i = 0; i < (int)matchedrotations.size(); i++) { - is.read((char *)&matchedrotations[i], sizeof(int)); - } - is.read((char *)&seriesid, sizeof(int)); is.read((char *)&isotope, sizeof(bool)); is.read((char *)&removeme, sizeof(bool)); diff --git a/CycloBranch/core/cPeak.h b/CycloBranch/core/cPeak.h index b3e7be4..478e33c 100644 --- a/CycloBranch/core/cPeak.h +++ b/CycloBranch/core/cPeak.h @@ -89,12 +89,6 @@ struct cPeak { int rotationid; - /** - \brief Vector of ids of rotations matched by an experimental peak. - */ - vector matchedrotations; - - /** \brief An order of a peak in a series (e.g., B_5 in a B series). */ @@ -138,14 +132,6 @@ struct cPeak { bool empty(); - /** - \brief Test whether the peak matches a rotation of a cyclic peptide. - \param rotationid id of a rotation of a cyclic peptide - \retval bool true when the peak matches the rotation - */ - bool hasMatchedRotation(int rotationid); - - /** \brief Store the structure into an output stream. \param os an output stream diff --git a/CycloBranch/core/cSummaryFormula.cpp b/CycloBranch/core/cSummaryFormula.cpp new file mode 100644 index 0000000..8cca1e4 --- /dev/null +++ b/CycloBranch/core/cSummaryFormula.cpp @@ -0,0 +1,264 @@ +#include "core/cSummaryFormula.h" + + +void cSummaryFormula::explodeSummary(map& atoms, string& summary) { + if ((int)summary.size() == 0) { + return; + } + + cPeriodicTableMap map; + string tmps; + tmps = summary[0]; + + int tmpc = 0; + bool minus = false; + for (int i = 1; i < (int)summary.size(); i++) { + + if ((summary[i] >= 'A') && (summary[i] <= 'Z')) { + if (map.count(tmps) > 0) { + if (tmpc == 0) { + if (atoms.count(tmps) == 0) { + atoms[tmps] = 1; + } + else { + atoms[tmps] += 1; + } + } + else { + if (atoms.count(tmps) == 0) { + atoms[tmps] = minus?-tmpc:tmpc; + } + else { + atoms[tmps] += minus?-tmpc:tmpc; + } + } + } + else { + return; + } + + tmps = summary[i]; + tmpc = 0; + minus = false; + } + + if ((summary[i] >= 'a') && (summary[i] <= 'z')) { + tmps += summary[i]; + } + + if ((summary[i] >= '0') && (summary[i] <= '9')) { + tmpc *= 10; + tmpc += summary[i] - '0'; + } + + if (summary[i] == '-') { + minus = true; + } + + } + + // the last element + if (map.count(tmps) > 0) { + if (tmpc == 0) { + if (atoms.count(tmps) == 0) { + atoms[tmps] = 1; + } + else { + atoms[tmps] += 1; + } + } + else { + if (atoms.count(tmps) == 0) { + atoms[tmps] = minus?-tmpc:tmpc; + } + else { + atoms[tmps] += minus?-tmpc:tmpc; + } + } + } +} + + +cSummaryFormula::cSummaryFormula() { + clear(); +} + + +cSummaryFormula::cSummaryFormula(string& formula) { + this->formula = formula; +} + + +void cSummaryFormula::clear() { + formula = ""; +} + + +void cSummaryFormula::setFormula(string& formula) { + this->formula = formula; +} + + +string& cSummaryFormula::getFormula() { + return formula; +} + + +void cSummaryFormula::addFormula(string& formula) { + if ((int)formula.size() == 0) { + return; + } + + map atoms; + atoms.clear(); + explodeSummary(atoms, this->formula); + explodeSummary(atoms, formula); + + this->formula = ""; + for (auto it = atoms.begin(); it != atoms.end(); ++it) { + if (it->second != 0) { + this->formula += it->first; + if (it->second != 1) { + this->formula += to_string(it->second); + } + } + } +} + + +bool cSummaryFormula::isValid(string& errormessage) { + if ((int)formula.size() == 0) { + return true; + } + + regex rx; + rx = "^([A-Z][a-z]*((-[0-9]+)|([0-9]*))*)+$"; + + try { + if (!regex_search(formula, rx)) { + errormessage = "Invalid summary: " + formula + ".\n\n"; + return false; + } + } + catch (std::regex_error& e) { + errormessage = "getMassFromResidueSummary: regex_search failed, error no. " + to_string((int)e.code()) + "\n"; + return false; + } + + errormessage = ""; + + cPeriodicTableMap map; + string tmps; + tmps = formula[0]; + + for (int i = 1; i < (int)formula.size(); i++) { + + if ((formula[i] >= 'A') && (formula[i] <= 'Z')) { + if (map.count(tmps) == 0) { + errormessage = "Undefined atom name: " + tmps + ".\n\n"; + return false; + } + + tmps = formula[i]; + } + + if ((formula[i] >= 'a') && (formula[i] <= 'z')) { + tmps += formula[i]; + } + + } + + // the last element + if (map.count(tmps) == 0) { + errormessage = "Undefined atom name: " + tmps + ".\n\n"; + return false; + } + + return true; +} + + +double cSummaryFormula::getMass() { + if ((int)formula.size() == 0) { + return 0; + } + + cPeriodicTableMap map; + double sum = 0; + + string tmps; + tmps = formula[0]; + + int tmpc = 0; + + bool minus = false; + + for (int i = 1; i < (int)formula.size(); i++) { + + if ((formula[i] >= 'A') && (formula[i] <= 'Z')) { + if (map.count(tmps) > 0) { + if (tmpc == 0) { + sum += map[tmps]; + } + else { + sum += minus?-tmpc*map[tmps]:tmpc*map[tmps]; + } + } + else { + return 0; + } + + tmps = formula[i]; + tmpc = 0; + minus = false; + } + + if ((formula[i] >= 'a') && (formula[i] <= 'z')) { + tmps += formula[i]; + } + + if ((formula[i] >= '0') && (formula[i] <= '9')) { + tmpc *= 10; + tmpc += formula[i] - '0'; + } + + if (formula[i] == '-') { + minus = true; + } + + } + + // the last element + if (map.count(tmps) > 0) { + if (tmpc == 0) { + sum += map[tmps]; + } + else { + sum += minus?-tmpc*map[tmps]:tmpc*map[tmps]; + } + } + else { + return 0; + } + + return sum; +} + + +void cSummaryFormula::store(ofstream& os) { + int size; + + size = (int)formula.size(); + os.write((char *)&size, sizeof(int)); + os.write(formula.c_str(), formula.size()); +} + + +void cSummaryFormula::load(ifstream& is) { + int size; + + is.read((char *)&size, sizeof(int)); + formula.resize(size); + is.read(&formula[0], formula.size()); +} + diff --git a/CycloBranch/core/cSummaryFormula.h b/CycloBranch/core/cSummaryFormula.h new file mode 100644 index 0000000..7ac8de4 --- /dev/null +++ b/CycloBranch/core/cSummaryFormula.h @@ -0,0 +1,101 @@ +/** + \file cSummaryFormula.h + \brief The representation of a summary formula. +*/ + + +#ifndef _CSUMMARYFORMULA_H +#define _CSUMMARYFORMULA_H + +#include +#include +#include "core/cFragmentIons.h" + + +using namespace std; + + +/** + \brief The representation of a summary formula. +*/ +class cSummaryFormula { + + string formula; + + void explodeSummary(map& atoms, string& summary); + +public: + + + /** + \brief The constructor. + */ + cSummaryFormula(); + + + /** + \brief The constructor. + \brief formula a chemical formula + */ + cSummaryFormula(string& formula); + + + /** + \brief Clear the structure. + */ + void clear(); + + + /** + \brief Set the formula. + \param formula a chemical formula + */ + void setFormula(string& formula); + + + /** + \brief Get the formula. + \retval string reference to the formula + */ + string& getFormula(); + + + /** + \brief Add a formula to the existing one. + \param formula a chemical formula + */ + void addFormula(string& formula); + + + /** + \brief Check the syntax of a chemical formula. + \param errormessage an error message if formula is invalid + \retval bool true when formula is valid + */ + bool isValid(string& errormessage); + + + /** + \brief Get mass of the formula. + \retval double mass of the formula + */ + double getMass(); + + + /** + \brief Store the structure into an output stream. + \param os an output stream + */ + void store(ofstream& os); + + + /** + \brief Load the structure from an input stream. + \param is an input stream + */ + void load(ifstream& is); + +}; + + +#endif \ No newline at end of file diff --git a/CycloBranch/core/cTheoreticalSpectrum.cpp b/CycloBranch/core/cTheoreticalSpectrum.cpp index ecefbdd..3280311 100644 --- a/CycloBranch/core/cTheoreticalSpectrum.cpp +++ b/CycloBranch/core/cTheoreticalSpectrum.cpp @@ -325,6 +325,8 @@ void cTheoreticalSpectrum::clear(bool clearpeaklist) { realpeptidename = ""; acronympeptidename = ""; acronyms.clear(); + backboneacronyms.clear(); + branchacronyms.clear(); path = ""; seriescompleted = 1; } @@ -493,10 +495,9 @@ int cTheoreticalSpectrum::compareBranched(cPeaksList& sortedpeaklist, cBricksDat for (set::iterator it = experimentalpeakmatches[i].begin(); it != experimentalpeakmatches[i].end(); ++it) { if (writedescription) { if (experimentalpeaks[i].description.compare("") != 0) { - experimentalpeaks[i].description += ", "; + experimentalpeaks[i].description += ","; } experimentalpeaks[i].description += theoreticalpeaks[*it].description.substr(0,theoreticalpeaks[*it].description.find(':')); - experimentalpeaks[i].matchedrotations.push_back(theoreticalpeaks[*it].rotationid); theoreticalpeaks[*it].matchdescription += ", measured mass " + to_string((long double)experimentalpeaks[i].mzratio) + " matched with " + to_string((long double)ppmError(experimentalpeaks[i].mzratio, theoreticalpeaks[*it].mzratio)) + " ppm error"; } @@ -510,7 +511,7 @@ int cTheoreticalSpectrum::compareBranched(cPeaksList& sortedpeaklist, cBricksDat visualcoverage.clear(); visualSeries tempseries; - coveragebyseries = "T-Permutations:
\n"; + coveragebyseries = "Linearized sequences:
\n"; for (int i = 0; i < (int)trotations.size(); i++) { coveragebyseries += to_string(i + 1) + " ~ " + bricksdatabasewithcombinations.getAcronymNameOfTPeptide(trotations[i].tcomposition, false) + "
\n"; } @@ -661,10 +662,9 @@ int cTheoreticalSpectrum::compareLinear(cPeaksList& sortedpeaklist, cBricksDatab for (set::iterator it = experimentalpeakmatches[i].begin(); it != experimentalpeakmatches[i].end(); ++it) { if (writedescription) { if (experimentalpeaks[i].description.compare("") != 0) { - experimentalpeaks[i].description += ", "; + experimentalpeaks[i].description += ","; } experimentalpeaks[i].description += theoreticalpeaks[*it].description.substr(0,theoreticalpeaks[*it].description.find(':')); - experimentalpeaks[i].matchedrotations.push_back(theoreticalpeaks[*it].rotationid); theoreticalpeaks[*it].matchdescription += ", measured mass " + to_string((long double)experimentalpeaks[i].mzratio) + " matched with " + to_string((long double)ppmError(experimentalpeaks[i].mzratio, theoreticalpeaks[*it].mzratio)) + " ppm error"; } @@ -954,10 +954,9 @@ int cTheoreticalSpectrum::compareCyclic(cPeaksList& sortedpeaklist, cBricksDatab for (set::iterator it = experimentalpeakmatches[i].begin(); it != experimentalpeakmatches[i].end(); ++it) { if (writedescription) { if (experimentalpeaks[i].description.compare("") != 0) { - experimentalpeaks[i].description += ", "; + experimentalpeaks[i].description += ","; } experimentalpeaks[i].description += theoreticalpeaks[*it].description.substr(0,theoreticalpeaks[*it].description.find(':')); - experimentalpeaks[i].matchedrotations.push_back(theoreticalpeaks[*it].rotationid); theoreticalpeaks[*it].matchdescription += ", measured mass " + to_string((long double)experimentalpeaks[i].mzratio) + " matched with " + to_string((long double)ppmError(experimentalpeaks[i].mzratio, theoreticalpeaks[*it].mzratio)) + " ppm error"; } @@ -1022,16 +1021,8 @@ int cTheoreticalSpectrum::compareCyclic(cPeaksList& sortedpeaklist, cBricksDatab visualSeries tempseries; visualcoverage.clear(); - coveragebyseries = "Rotations:
\n"; + coveragebyseries = "Linearized sequences from all ring break up points:
\n"; for (int i = 0; i < (int)rotations.size(); i++) { - /* - if (i == 0) { - coveragebyseries += ">>>
\n"; - } - if (i == r) { - coveragebyseries += "
\n<<<
\n"; - } - */ if (i == r) { coveragebyseries += "
\n"; } @@ -1056,7 +1047,7 @@ int cTheoreticalSpectrum::compareCyclic(cPeaksList& sortedpeaklist, cBricksDatab } } coveragebyseries += "
\n"; - visualcoverage.push_back(tempseries); // comment + visualcoverage.push_back(tempseries); } } @@ -1065,19 +1056,11 @@ int cTheoreticalSpectrum::compareCyclic(cPeaksList& sortedpeaklist, cBricksDatab vector mask; // peaks converted to letters vector tempvector; - visualSeries visualtempseries; for (int k = 0; k < r; k++) { mask.push_back(0); tempvector.push_back(0); - if (writedescription) { - visualtempseries.series.push_back(0); - } } - if (writedescription) { - //visualcoverage.clear(); // uncomment - } - for (int i = 0; i < (int)series.size(); i++) { for (int j = 0; j < (int)parameters->fragmentionsfortheoreticalspectra.size(); j++) { @@ -1102,18 +1085,9 @@ int cTheoreticalSpectrum::compareCyclic(cPeaksList& sortedpeaklist, cBricksDatab } } - if (writedescription) { - visualtempseries.name = to_string(splittingsites[i].first + 1) + "-" + to_string(splittingsites[i].second + 1) + "_"; - visualtempseries.name += parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[j]].name; - } - if (i < r) { for (int k = 0; k < r; k++) { mask[k] += tempvector[(k + r - i) % r]; - - if (writedescription) { - visualtempseries.series[k] = tempvector[(k + r - i) % r]; - } } } else { @@ -1121,17 +1095,9 @@ int cTheoreticalSpectrum::compareCyclic(cPeaksList& sortedpeaklist, cBricksDatab for (int k = 0; k < r; k++) { mask[k] += tempvector[(k + i) % r]; - - if (writedescription) { - visualtempseries.series[k] = tempvector[(k + i) % r]; - } } } - if (writedescription) { - //visualcoverage.push_back(visualtempseries); // uncomment - } - } } @@ -1152,17 +1118,25 @@ int cTheoreticalSpectrum::compareLasso(cPeaksList& sortedpeaklist, cBricksDataba vector splittingsites; int theoreticalpeaksrealsize = 0; vector stringcomposition; - - vector lassorotations; - candidate.getLassoRotations(lassorotations, true); - int r = (int)lassorotations.size() / 2; - validposition = -1; - reversevalidposition = -1; + // normalize the candidate + candidate.getLassoRotations(lassorotations, false); + for (int i = 0; i < (int)lassorotations.size(); i++) { + if (lassorotations[i].getBranchEnd() == getNumberOfBricks(candidate.getComposition()) - 1) { + vector v; + v.push_back(lassorotations[i].getComposition()); + candidate.setCandidate(v, candidate.getPath(), candidate.getStartModifID(), candidate.getEndModifID(), candidate.getMiddleModifID(), lassorotations[i].getBranchStart(), lassorotations[i].getBranchEnd()); + break; + } + } + + // get lasso rotations + candidate.getLassoRotations(lassorotations, true); + // get T-permutations of lasso rotations vector > trotationsoflassorotations; trotationsoflassorotations.resize(lassorotations.size()); for (int i = 0; i < (int)lassorotations.size(); i++) { @@ -1170,6 +1144,10 @@ int cTheoreticalSpectrum::compareLasso(cPeaksList& sortedpeaklist, cBricksDataba } + int r = (int)lassorotations.size() / 2; + validposition = -1; + reversevalidposition = -1; + try { bool stop = true; for (int i = 0; i < (int)lassorotations.size(); i++) { @@ -1385,10 +1363,9 @@ int cTheoreticalSpectrum::compareLasso(cPeaksList& sortedpeaklist, cBricksDataba for (set::iterator it = experimentalpeakmatches[i].begin(); it != experimentalpeakmatches[i].end(); ++it) { if (writedescription) { if (experimentalpeaks[i].description.compare("") != 0) { - experimentalpeaks[i].description += ", "; + experimentalpeaks[i].description += ","; } experimentalpeaks[i].description += theoreticalpeaks[*it].description.substr(0,theoreticalpeaks[*it].description.find(':')); - experimentalpeaks[i].matchedrotations.push_back(theoreticalpeaks[*it].rotationid); theoreticalpeaks[*it].matchdescription += ", measured mass " + to_string((long double)experimentalpeaks[i].mzratio) + " matched with " + to_string((long double)ppmError(experimentalpeaks[i].mzratio, theoreticalpeaks[*it].mzratio)) + " ppm error"; } @@ -1399,14 +1376,11 @@ int cTheoreticalSpectrum::compareLasso(cPeaksList& sortedpeaklist, cBricksDataba if (writedescription) { - coveragebyseries = "T-Permutations of lasso rotations:
\n"; + visualSeries tempseries; + visualcoverage.clear(); + + coveragebyseries = "Linearized sequences from all ring break up points:
\n"; for (int i = 0; i < (int)lassorotations.size(); i++) { - if (i == 0) { - coveragebyseries += ">>>
\n"; - } - if (i == r) { - coveragebyseries += "<<<
\n"; - } for (int j = 0; j < (int)trotationsoflassorotations[i].size(); j++) { coveragebyseries += to_string(splittingsites[i].first + 1) + "-" + to_string(splittingsites[i].second + 1) + "_"; coveragebyseries += to_string(j + 1) + " ~ "; @@ -1420,16 +1394,19 @@ int cTheoreticalSpectrum::compareLasso(cPeaksList& sortedpeaklist, cBricksDataba for (int i = 0; i < (int)lassorotations.size(); i++) { for (int j = 0; j < (int)series[i].size(); j++) { for (int k = 0; k < (int)parameters->fragmentionsfortheoreticalspectra.size(); k++) { - coveragebyseries += to_string(splittingsites[i].first + 1) + "-" + to_string(splittingsites[i].second + 1) + "_"; - coveragebyseries += to_string(j + 1) + "_"; - coveragebyseries += parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[k]].name + " "; + tempseries.name = to_string(splittingsites[i].first + 1) + "-" + to_string(splittingsites[i].second + 1) + "_"; + tempseries.name += to_string(j + 1) + "_" + parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[k]].name; + coveragebyseries += tempseries.name + " "; + tempseries.series.clear(); for (int m = 0; m < series[i][j][parameters->fragmentionsfortheoreticalspectra[k]].size() - 1; m++) { coveragebyseries += to_string(series[i][j][parameters->fragmentionsfortheoreticalspectra[k]][m]); + tempseries.series.push_back(series[i][j][parameters->fragmentionsfortheoreticalspectra[k]][m]); if (m < series[i][j][parameters->fragmentionsfortheoreticalspectra[k]].size() - 2) { coveragebyseries += " "; } } coveragebyseries += "
\n"; + visualcoverage.push_back(tempseries); } } } @@ -1562,10 +1539,9 @@ int cTheoreticalSpectrum::compareLinearPolysaccharide(cPeaksList& sortedpeaklist for (set::iterator it = experimentalpeakmatches[i].begin(); it != experimentalpeakmatches[i].end(); ++it) { if (writedescription) { if (experimentalpeaks[i].description.compare("") != 0) { - experimentalpeaks[i].description += ", "; + experimentalpeaks[i].description += ","; } experimentalpeaks[i].description += theoreticalpeaks[*it].description.substr(0,theoreticalpeaks[*it].description.find(':')); - experimentalpeaks[i].matchedrotations.push_back(theoreticalpeaks[*it].rotationid); theoreticalpeaks[*it].matchdescription += ", measured mass " + to_string((long double)experimentalpeaks[i].mzratio) + " matched with " + to_string((long double)ppmError(experimentalpeaks[i].mzratio, theoreticalpeaks[*it].mzratio)) + " ppm error"; } @@ -2121,11 +2097,53 @@ void cTheoreticalSpectrum::setAcronyms(cBricksDatabase& bricksdatabase) { } +void cTheoreticalSpectrum::setBackboneAcronyms(cBricksDatabase& bricksdatabase) { + vector bricks; + cBrick b; + b.clear(); + b.setComposition(candidate.getComposition(), false); + b.explodeToIntComposition(bricks); + + backboneacronyms.clear(); + for (int i = 0; i < (int)bricks.size(); i++) { + if ((candidate.getBranchStart() >= 0) && (candidate.getBranchEnd() >= 0) && ((i <= candidate.getBranchStart()) || (i > candidate.getBranchEnd()))) { + backboneacronyms.push_back(bricksdatabase[bricks[i] - 1].getAcronymsAsString()); + } + } +} + + +void cTheoreticalSpectrum::setBranchAcronyms(cBricksDatabase& bricksdatabase) { + vector bricks; + cBrick b; + b.clear(); + b.setComposition(candidate.getComposition(), false); + b.explodeToIntComposition(bricks); + + branchacronyms.clear(); + for (int i = 0; i < (int)bricks.size(); i++) { + if ((candidate.getBranchStart() >= 0) && (candidate.getBranchEnd() >= 0) && (i > candidate.getBranchStart()) && (i <= candidate.getBranchEnd())) { + branchacronyms.push_back(bricksdatabase[bricks[i] - 1].getAcronymsAsString()); + } + } +} + + vector& cTheoreticalSpectrum::getAcronyms() { return acronyms; } +vector& cTheoreticalSpectrum::getBackboneAcronyms() { + return backboneacronyms; +} + + +vector& cTheoreticalSpectrum::getBranchAcronyms() { + return branchacronyms; +} + + void cTheoreticalSpectrum::setPath(cDeNovoGraph& graph) { cDeNovoGraphNode* currentnode; cDeNovoGraphNode* targetnode; @@ -2246,6 +2264,22 @@ void cTheoreticalSpectrum::store(ofstream& os) { os.write(acronyms[i].c_str(), acronyms[i].size()); } + size = (int)backboneacronyms.size(); + os.write((char *)&size, sizeof(int)); + for (int i = 0; i < (int)backboneacronyms.size(); i++) { + size = (int)backboneacronyms[i].size(); + os.write((char *)&size, sizeof(int)); + os.write(backboneacronyms[i].c_str(), backboneacronyms[i].size()); + } + + size = (int)branchacronyms.size(); + os.write((char *)&size, sizeof(int)); + for (int i = 0; i < (int)branchacronyms.size(); i++) { + size = (int)branchacronyms[i].size(); + os.write((char *)&size, sizeof(int)); + os.write(branchacronyms[i].c_str(), branchacronyms[i].size()); + } + size = (int)path.size(); os.write((char *)&size, sizeof(int)); os.write(path.c_str(), path.size()); @@ -2314,6 +2348,22 @@ void cTheoreticalSpectrum::load(ifstream& is) { is.read(&acronyms[i][0], acronyms[i].size()); } + is.read((char *)&size, sizeof(int)); + backboneacronyms.resize(size); + for (int i = 0; i < (int)backboneacronyms.size(); i++) { + is.read((char *)&size, sizeof(int)); + backboneacronyms[i].resize(size); + is.read(&backboneacronyms[i][0], backboneacronyms[i].size()); + } + + is.read((char *)&size, sizeof(int)); + branchacronyms.resize(size); + for (int i = 0; i < (int)branchacronyms.size(); i++) { + is.read((char *)&size, sizeof(int)); + branchacronyms[i].resize(size); + is.read(&branchacronyms[i][0], branchacronyms[i].size()); + } + is.read((char *)&size, sizeof(int)); path.resize(size); is.read(&path[0], path.size()); diff --git a/CycloBranch/core/cTheoreticalSpectrum.h b/CycloBranch/core/cTheoreticalSpectrum.h index 5eb62c2..c6d791d 100644 --- a/CycloBranch/core/cTheoreticalSpectrum.h +++ b/CycloBranch/core/cTheoreticalSpectrum.h @@ -115,6 +115,8 @@ class cTheoreticalSpectrum { string realpeptidename; string acronympeptidename; vector acronyms; + vector backboneacronyms; + vector branchacronyms; string path; // remove false hits, i.e., b-H2O without existing b-ion @@ -450,6 +452,20 @@ class cTheoreticalSpectrum { void setAcronyms(cBricksDatabase& bricksdatabase); + /** + \brief Set a vector of acronyms corresponding to a backbone of a peptide sequence candidate. + \param bricksdatabase a database of building blocks + */ + void setBackboneAcronyms(cBricksDatabase& bricksdatabase); + + + /** + \brief Set a vector of acronyms corresponding to a branch of a peptide sequence candidate. + \param bricksdatabase a database of building blocks + */ + void setBranchAcronyms(cBricksDatabase& bricksdatabase); + + /** \brief Get a vector of acronyms corresponding to a peptide sequence candidate. \retval vector a vector of acronyms @@ -457,6 +473,20 @@ class cTheoreticalSpectrum { vector& getAcronyms(); + /** + \brief Get a vector of acronyms corresponding to a backbone of a peptide sequence candidate. + \retval vector a vector of acronyms + */ + vector& getBackboneAcronyms(); + + + /** + \brief Get a vector of acronyms corresponding to a branch of a peptide sequence candidate. + \retval vector a vector of acronyms + */ + vector& getBranchAcronyms(); + + /** \brief Set a path in the de novo graph corresponding to the spectrum. \param graph reference to the de novo graph diff --git a/CycloBranch/core/cTheoreticalSpectrumList.cpp b/CycloBranch/core/cTheoreticalSpectrumList.cpp index c55fc44..e439544 100644 --- a/CycloBranch/core/cTheoreticalSpectrumList.cpp +++ b/CycloBranch/core/cTheoreticalSpectrumList.cpp @@ -257,6 +257,10 @@ int cTheoreticalSpectrumList::parallelCompareAndStore(cCandidateSet& candidates, theoreticalspectra[i].setRealPeptideName(*bricksdb, parameters->peptidetype); theoreticalspectra[i].setAcronymPeptideNameWithHTMLReferences(*bricksdb, parameters->peptidetype); theoreticalspectra[i].setAcronyms(*bricksdb); + if ((parameters->peptidetype == branched) || (parameters->peptidetype == lasso)) { + theoreticalspectra[i].setBackboneAcronyms(*bricksdb); + theoreticalspectra[i].setBranchAcronyms(*bricksdb); + } if (parameters->mode == 0) { theoreticalspectra[i].setPath(*graph); } diff --git a/CycloBranch/gui/cAboutWidget.cpp b/CycloBranch/gui/cAboutWidget.cpp index c42b149..75401aa 100644 --- a/CycloBranch/gui/cAboutWidget.cpp +++ b/CycloBranch/gui/cAboutWidget.cpp @@ -18,7 +18,7 @@ cAboutWidget::cAboutWidget(QWidget* parent) { message->setReadOnly(true); message->setAcceptRichText(true); message->setOpenExternalLinks(true); - message->setHtml(appname + " " + appversion + "

Developers:

Jiri Novak
Laboratory of Molecular Structure Characterization
Institute of Microbiology
Academy of Sciences of the Czech Republic
Videnska 1083
142 20 Prague
Czech Republic
jiri.novak@biomed.cas.cz
http://ms.biomed.cas.cz/staff-novak_jiri.php
https://cas-cz.academia.edu/JiriNovak

(C) 2013-2014"); + message->setHtml(appname + " " + appversion + "

Developers:

Jiri Novak
Laboratory of Molecular Structure Characterization
Institute of Microbiology
Academy of Sciences of the Czech Republic
Videnska 1083
142 20 Prague
Czech Republic
jiri.novak@biomed.cas.cz
http://ms.biomed.cas.cz/cyclobranch/
http://ms.biomed.cas.cz/staff-novak_jiri.php
https://cas-cz.academia.edu/JiriNovak

(C) 2013-2014"); buttonbox = new QDialogButtonBox(QDialogButtonBox::Ok); //buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); diff --git a/CycloBranch/gui/cBranchedWidget.cpp b/CycloBranch/gui/cBranchedWidget.cpp index 549cd78..324f9d5 100644 --- a/CycloBranch/gui/cBranchedWidget.cpp +++ b/CycloBranch/gui/cBranchedWidget.cpp @@ -9,6 +9,7 @@ cBranchedWidget::cBranchedWidget() { parameters = 0; theoreticalspectrum = 0; + visibletrotationid = -1; } @@ -26,8 +27,8 @@ void cBranchedWidget::paintEvent(QPaintEvent *event) { vector backboneacronyms; vector branchacronyms; - theoreticalspectrum->getCandidate().getBackboneAcronyms(parameters->bricksdatabase, backboneacronyms); - theoreticalspectrum->getCandidate().getBranchAcronyms(parameters->bricksdatabase, branchacronyms); + backboneacronyms = theoreticalspectrum->getBackboneAcronyms(); + branchacronyms = theoreticalspectrum->getBranchAcronyms(); QPainter painter(this); const int topmargin = 20; @@ -35,8 +36,8 @@ void cBranchedWidget::paintEvent(QPaintEvent *event) { const int bottommargin = 80; const int rightmargin = 20; + int backbonesize = (int)backboneacronyms.size(); int branchsize = (int)branchacronyms.size(); - int backbonesize = (int)theoreticalspectrum->getAcronyms().size() - branchsize; vector tpermutations; theoreticalspectrum->getCandidate().getPermutationsOfBranches(tpermutations); @@ -86,6 +87,11 @@ void cBranchedWidget::paintEvent(QPaintEvent *event) { string name; int len = (int)theoreticalspectrum->getVisualCoverage()[0].series.size(); for (int i = 0; i < 6; i++) { + + if ((visibletrotationid != -1) && (visibletrotationid != i)) { + continue; + } + for (int j = 0; j < (int)parameters->fragmentionsfortheoreticalspectra.size(); j++) { position = 0; @@ -281,3 +287,9 @@ void cBranchedWidget::paintEvent(QPaintEvent *event) { } + +void cBranchedWidget::trotationChanged(int index) { + visibletrotationid = index - 1; + repaint(); +} + diff --git a/CycloBranch/gui/cBranchedWidget.h b/CycloBranch/gui/cBranchedWidget.h index 32b6d14..1f8b9f2 100644 --- a/CycloBranch/gui/cBranchedWidget.h +++ b/CycloBranch/gui/cBranchedWidget.h @@ -54,6 +54,12 @@ class cBranchedWidget : public QWidget cParameters* parameters; cTheoreticalSpectrum* theoreticalspectrum; + int visibletrotationid; + + +private slots: + + void trotationChanged(int index); }; diff --git a/CycloBranch/gui/cCyclicWidget.cpp b/CycloBranch/gui/cCyclicWidget.cpp index 73c3276..db7eede 100644 --- a/CycloBranch/gui/cCyclicWidget.cpp +++ b/CycloBranch/gui/cCyclicWidget.cpp @@ -6,207 +6,61 @@ #include -cCyclicWidget::cCyclicWidget() { - parameters = 0; - theoreticalspectrum = 0; - visiblerotationid = -1; -} - - -void cCyclicWidget::initialize(cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum) { - this->parameters = parameters; - this->theoreticalspectrum = theoreticalspectrum; -} - - -/* -void cCyclicWidget::paintEvent(QPaintEvent *event) { - string s; - - // count number of lines to draw - bool skip; - int linenumber = 0; - for (int i = 0; i < (int)theoreticalspectrum->getVisualCoverage().size(); i++) { - - skip = true; - for (int j = 0; j < (int)theoreticalspectrum->getVisualCoverage()[i].series.size(); j++) { - if (theoreticalspectrum->getVisualCoverage()[i].series[j] > 0) { - skip = false; - break; - } - } - - if (skip) { - continue; - } - - linenumber++; - } - - if ((theoreticalspectrum->getAcronyms().size() == 0) || (linenumber == 0)) { - return; - } - - QPainter painter(this); - const int topmargin = 80; - const int leftmargin = 60; - const int bottommargin = 50; - const int rightmargin = 50; - const int maskmargin = 30; - const int verticalstep = (height() - topmargin - bottommargin)/linenumber; - const int horizontalstep = (width() - leftmargin - rightmargin)/(int)theoreticalspectrum->getAcronyms().size(); - - QFont myFont("Courier", 9); - - painter.setPen(QPen(Qt::red, 2, Qt::SolidLine)); - painter.setFont(myFont); - - // draw candidate - int r = (int)theoreticalspectrum->getAcronyms().size(); - int hint = (int)theoreticalspectrum->getVisualCoverage().size()/(2*r); - for (int i = 0; i < r; i++) { - painter.drawLine(leftmargin + horizontalstep*i, topmargin - 30, leftmargin + horizontalstep*i, topmargin - 10); - painter.drawText(leftmargin + horizontalstep*i, topmargin - 30, horizontalstep, 20, Qt::AlignCenter, theoreticalspectrum->getAcronyms()[i].c_str()); - - s = theoreticalspectrum->getVisualCoverage()[i*hint].name.substr(0, theoreticalspectrum->getVisualCoverage()[i*hint].name.rfind('_')); - painter.drawText(leftmargin + horizontalstep*i - horizontalstep/2, topmargin - 80, horizontalstep, 30, Qt::AlignCenter, s.c_str()); - if (i == 0) { - painter.drawText(leftmargin + horizontalstep*r - horizontalstep/2, topmargin - 80, horizontalstep, 30, Qt::AlignCenter, s.c_str()); - } - - if (i == 0) { - s = theoreticalspectrum->getVisualCoverage()[r*hint].name.substr(0, theoreticalspectrum->getVisualCoverage()[r*hint].name.rfind('_')); - } - else { - s = theoreticalspectrum->getVisualCoverage()[(2*r - i)*hint].name.substr(0, theoreticalspectrum->getVisualCoverage()[(2*r - i)*hint].name.rfind('_')); - } - painter.drawText(leftmargin + horizontalstep*i - horizontalstep/2, topmargin - 60, horizontalstep, 30, Qt::AlignCenter, s.c_str()); - if (i == 0) { - painter.drawText(leftmargin + horizontalstep*r - horizontalstep/2, topmargin - 60, horizontalstep, 30, Qt::AlignCenter, s.c_str()); - } - } - painter.drawLine(leftmargin + horizontalstep*r, topmargin - 30, leftmargin + horizontalstep*r, topmargin - 10); - - painter.drawText(0, topmargin - 80, 20, 30, Qt::AlignCenter, ">>>"); - painter.drawText(0, topmargin - 60, 20, 30, Qt::AlignCenter, "<<<"); - - // draw lines - linenumber = 0; - for (int i = 0; i < (int)theoreticalspectrum->getVisualCoverage().size(); i++) { - - skip = true; - for (int j = 0; j < (int)theoreticalspectrum->getVisualCoverage()[i].series.size(); j++) { - if (theoreticalspectrum->getVisualCoverage()[i].series[j] > 0) { - skip = false; - break; - } - } - - if (skip) { - continue; - } - - painter.setPen(QPen(Qt::gray, 2, Qt::SolidLine)); - for (int j = 0; j < (int)theoreticalspectrum->getVisualCoverage()[i].series.size(); j++) { - if (theoreticalspectrum->getVisualCoverage()[i].series[j] > 0) { - painter.setBrush(QBrush(Qt::blue, Qt::SolidPattern)); - } - else { - painter.setBrush(QBrush(Qt::red, Qt::NoBrush)); - } - painter.drawRect(leftmargin + horizontalstep*j, topmargin + verticalstep*linenumber, horizontalstep, verticalstep); - } - - painter.setPen(QPen(Qt::red, 2, Qt::SolidLine)); - painter.setBrush(QBrush(Qt::red, Qt::NoBrush)); - - painter.drawText(0, topmargin + verticalstep*linenumber + verticalstep/2 - 9, 80, 20, Qt::AlignLeft, theoreticalspectrum->getVisualCoverage()[i].name.c_str()); - - linenumber++; - - } - -} -*/ - - -void cCyclicWidget::paintEvent(QPaintEvent *event) { - - if (theoreticalspectrum->getVisualCoverage().size() == 0) { - return; - } - - QPainter painter(this); - const int topmargin = 20;//max(20,(height() - 80)/2); - const int leftmargin = 20; - const int bottommargin = 80; - const int rightmargin = 20; - - int size = (int)theoreticalspectrum->getAcronyms().size(); - const double pi = 3.141592653589793; - double angle = 2*pi/(double)size; - int centerx = width()/2; - int centery = height()/2; - int radius = min(width() - leftmargin - rightmargin, height() - topmargin - bottommargin)/2; +void paintCircle(QPainter& painter, QColor& brushcolor, vector& acronymsofblocks, int centerx, int centery, int radius, double angle, int horizontalstep, int linesize, int cornerlinesize) { double cumulativeangle; - const int horizontalstep = (width() - leftmargin - rightmargin)/std::max(size, 1); - - QFont myFont("Courier", 9); - painter.setFont(myFont); - painter.setPen(QPen(Qt::black, 2, Qt::SolidLine)); painter.drawEllipse(QPointF(centerx,centery), radius, radius); int xsize = horizontalstep*2/3; - for (int i = 0; i < size; i++) { - cumulativeangle = angle*(double)i; + string blockid; + for (int i = 0; i < (int)acronymsofblocks.size(); i++) { + cumulativeangle = angle*(double)(i + 1); + blockid = to_string(i + 1); if (cumulativeangle < pi/2) { - painter.setBrush(QBrush(palette().color(QPalette::Background), Qt::SolidPattern)); + painter.setBrush(QBrush(brushcolor, Qt::SolidPattern)); painter.drawRect(centerx + sin(cumulativeangle)*radius - xsize/2, centery - sin(pi/2 - cumulativeangle)*radius - 10, xsize, 20); - painter.setBrush(QBrush(palette().color(QPalette::Background), Qt::NoBrush)); + painter.setBrush(QBrush(brushcolor, Qt::NoBrush)); painter.setPen(QPen(Qt::blue, 2, Qt::SolidLine)); - painter.drawText(centerx + sin(cumulativeangle)*radius - xsize/2, centery - sin(pi/2 - cumulativeangle)*radius - 10, xsize, 20, Qt::AlignCenter, theoreticalspectrum->getAcronyms()[i].c_str()); - painter.drawText(centerx + sin(cumulativeangle)*radius - xsize/2, centery - sin(pi/2 - cumulativeangle)*radius - 30, xsize, 20, Qt::AlignLeft, to_string(i + 1).c_str()); + painter.drawText(centerx + sin(cumulativeangle)*radius - xsize/2, centery - sin(pi/2 - cumulativeangle)*radius - 10, xsize, 20, Qt::AlignCenter, acronymsofblocks[i].c_str()); + painter.drawText(centerx + sin(cumulativeangle)*radius - xsize/2, centery - sin(pi/2 - cumulativeangle)*radius - 30, xsize, 20, Qt::AlignLeft, blockid.c_str()); painter.setPen(QPen(Qt::black, 2, Qt::SolidLine)); painter.drawRect(centerx + sin(cumulativeangle)*radius - xsize/2, centery - sin(pi/2 - cumulativeangle)*radius - 10, xsize, 20); } else if ((cumulativeangle >= pi/2) && (cumulativeangle <= pi)) { - painter.setBrush(QBrush(palette().color(QPalette::Background), Qt::SolidPattern)); + painter.setBrush(QBrush(brushcolor, Qt::SolidPattern)); painter.drawRect(centerx + sin(pi - cumulativeangle)*radius - xsize/2, centery + sin(cumulativeangle - pi/2)*radius - 10, xsize, 20); - painter.setBrush(QBrush(palette().color(QPalette::Background), Qt::NoBrush)); + painter.setBrush(QBrush(brushcolor, Qt::NoBrush)); painter.setPen(QPen(Qt::blue, 2, Qt::SolidLine)); - painter.drawText(centerx + sin(pi - cumulativeangle)*radius - xsize/2, centery + sin(cumulativeangle - pi/2)*radius - 10, xsize, 20, Qt::AlignCenter, theoreticalspectrum->getAcronyms()[i].c_str()); - painter.drawText(centerx + sin(pi - cumulativeangle)*radius - xsize/2, centery + sin(cumulativeangle - pi/2)*radius - 30, xsize, 20, Qt::AlignLeft, to_string(i + 1).c_str()); + painter.drawText(centerx + sin(pi - cumulativeangle)*radius - xsize/2, centery + sin(cumulativeangle - pi/2)*radius - 10, xsize, 20, Qt::AlignCenter, acronymsofblocks[i].c_str()); + painter.drawText(centerx + sin(pi - cumulativeangle)*radius - xsize/2, centery + sin(cumulativeangle - pi/2)*radius - 30, xsize, 20, Qt::AlignLeft, blockid.c_str()); painter.setPen(QPen(Qt::black, 2, Qt::SolidLine)); painter.drawRect(centerx + sin(pi - cumulativeangle)*radius - xsize/2, centery + sin(cumulativeangle - pi/2)*radius - 10, xsize, 20); } else if ((cumulativeangle >= pi) && (cumulativeangle <= 3*pi/2)) { - painter.setBrush(QBrush(palette().color(QPalette::Background), Qt::SolidPattern)); + painter.setBrush(QBrush(brushcolor, Qt::SolidPattern)); painter.drawRect(centerx - sin(cumulativeangle - pi)*radius - xsize/2, centery + sin(3*pi/2 - cumulativeangle)*radius - 10, xsize, 20); - painter.setBrush(QBrush(palette().color(QPalette::Background), Qt::NoBrush)); + painter.setBrush(QBrush(brushcolor, Qt::NoBrush)); painter.setPen(QPen(Qt::blue, 2, Qt::SolidLine)); - painter.drawText(centerx - sin(cumulativeangle - pi)*radius - xsize/2, centery + sin(3*pi/2 - cumulativeangle)*radius - 10, xsize, 20, Qt::AlignCenter, theoreticalspectrum->getAcronyms()[i].c_str()); - painter.drawText(centerx - sin(cumulativeangle - pi)*radius - xsize/2, centery + sin(3*pi/2 - cumulativeangle)*radius - 30, xsize, 20, Qt::AlignLeft, to_string(i + 1).c_str()); + painter.drawText(centerx - sin(cumulativeangle - pi)*radius - xsize/2, centery + sin(3*pi/2 - cumulativeangle)*radius - 10, xsize, 20, Qt::AlignCenter, acronymsofblocks[i].c_str()); + painter.drawText(centerx - sin(cumulativeangle - pi)*radius - xsize/2, centery + sin(3*pi/2 - cumulativeangle)*radius - 30, xsize, 20, Qt::AlignLeft, blockid.c_str()); painter.setPen(QPen(Qt::black, 2, Qt::SolidLine)); painter.drawRect(centerx - sin(cumulativeangle - pi)*radius - xsize/2, centery + sin(3*pi/2 - cumulativeangle)*radius - 10, xsize, 20); } else { - painter.setBrush(QBrush(palette().color(QPalette::Background), Qt::SolidPattern)); + painter.setBrush(QBrush(brushcolor, Qt::SolidPattern)); painter.drawRect(centerx - sin(2*pi - cumulativeangle)*radius - xsize/2, centery - sin(cumulativeangle - 3*pi/2)*radius - 10, xsize, 20); - painter.setBrush(QBrush(palette().color(QPalette::Background), Qt::NoBrush)); + painter.setBrush(QBrush(brushcolor, Qt::NoBrush)); painter.setPen(QPen(Qt::blue, 2, Qt::SolidLine)); - painter.drawText(centerx - sin(2*pi - cumulativeangle)*radius - xsize/2, centery - sin(cumulativeangle - 3*pi/2)*radius - 10, xsize, 20, Qt::AlignCenter, theoreticalspectrum->getAcronyms()[i].c_str()); - painter.drawText(centerx - sin(2*pi - cumulativeangle)*radius - xsize/2, centery - sin(cumulativeangle - 3*pi/2)*radius - 30, xsize, 20, Qt::AlignLeft, to_string(i + 1).c_str()); + painter.drawText(centerx - sin(2*pi - cumulativeangle)*radius - xsize/2, centery - sin(cumulativeangle - 3*pi/2)*radius - 10, xsize, 20, Qt::AlignCenter, acronymsofblocks[i].c_str()); + painter.drawText(centerx - sin(2*pi - cumulativeangle)*radius - xsize/2, centery - sin(cumulativeangle - 3*pi/2)*radius - 30, xsize, 20, Qt::AlignLeft, blockid.c_str()); painter.setPen(QPen(Qt::black, 2, Qt::SolidLine)); painter.drawRect(centerx - sin(2*pi - cumulativeangle)*radius - xsize/2, centery - sin(cumulativeangle - 3*pi/2)*radius - 10, xsize, 20); } } painter.setPen(QPen(Qt::black, 2, Qt::DashLine)); - int linesize = 20; - int cornerlinesize = horizontalstep/8; - for (int i = 0; i < size; i++) { + for (int i = 0; i < (int)acronymsofblocks.size(); i++) { cumulativeangle = angle*(double)i + angle/(double)2; if (cumulativeangle < pi/2) { QPoint p1(centerx + sin(cumulativeangle)*(radius - linesize), centery - sin(pi/2 - cumulativeangle)*(radius - linesize)); @@ -245,22 +99,23 @@ void cCyclicWidget::paintEvent(QPaintEvent *event) { painter.drawLine(p1, p4); } } - - unordered_set labels; - labels.clear(); +} + +void generateCyclicLabelsToRight(bool nterminal, int rotationid, int rotationstart, int fragmentstart, int fragmentend, int numberofringblocks, unordered_set& labels, cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum, int centerx, int centery, int radius, double angle, int linesize, int cornerlinesize, int visiblerotationid, int branchstart, int branchend) { + double cumulativeangle; string name; - int shiftedposition = 0; - int len = (int)theoreticalspectrum->getVisualCoverage()[0].series.size(); - for (int i = 0; i < 2*size; i++) { - if ((visiblerotationid == -1) || (visiblerotationid == i)) { - for (int j = 0; j < (int)parameters->fragmentionsfortheoreticalspectra.size(); j++) { - for (int k = 0; k < len; k++) { - if (theoreticalspectrum->getVisualCoverage()[i*parameters->fragmentionsfortheoreticalspectra.size() + j].series[k] > 0) { - name = theoreticalspectrum->getVisualCoverage()[i*parameters->fragmentionsfortheoreticalspectra.size() + j].name.substr(0, theoreticalspectrum->getVisualCoverage()[i*parameters->fragmentionsfortheoreticalspectra.size() + j].name.find('_') + 1); - name += parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[j]].name[0] + to_string(k + 1) + parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[j]].name.substr(1); - if (i < size) { - cumulativeangle = angle*(double)((i + k) % size) + angle/(double)2; + int m; + if ((visiblerotationid == -1) || ((parameters->peptidetype == cyclic) && (visiblerotationid == rotationid)) || ((parameters->peptidetype == lasso) && (visiblerotationid == rotationid/6))) { + for (int i = 0; i < (int)parameters->fragmentionsfortheoreticalspectra.size(); i++) { + if ((nterminal && parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].nterminal) || (!nterminal && parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].cterminal)) { + m = 0; + for (int j = fragmentstart; j < fragmentend; j++) { + if ((branchstart == -1) || (branchend == -1) || ((branchstart >= 0) && (j < branchstart)) || ((branchend >= 0) && (j >= branchend))) { + if (theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].series[j] > 0) { + name = theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].name.substr(0, theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].name.rfind('_') + 1); + name += parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].name[0] + to_string(j + 1) + parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].name.substr(1); + cumulativeangle = angle*(double)((rotationstart + m + 1) % numberofringblocks) + angle/(double)2; if (cumulativeangle < pi/2) { QPoint p3(centerx + sin(cumulativeangle)*(radius + linesize) - sin(pi/2 - cumulativeangle)*cornerlinesize, centery - sin(pi/2 - cumulativeangle)*(radius + linesize) - sin(cumulativeangle)*cornerlinesize); insertLabel(labels, p3.x() + 10, p3.y() - 10, name, false); @@ -278,8 +133,29 @@ void cCyclicWidget::paintEvent(QPaintEvent *event) { insertLabel(labels, p3.x() - 10, p3.y() - 10, name, true); } } - else { - cumulativeangle = angle*(double)((2*size - i - 1 + size - k - 1) % size) + angle/(double)2; + m++; + } + } + } + } + } +} + + +void generateCyclicLabelsToLeft(bool nterminal, int rotationid, int rotationstart, int fragmentstart, int fragmentend, int numberofringblocks, unordered_set& labels, cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum, int centerx, int centery, int radius, double angle, int linesize, int cornerlinesize, int visiblerotationid, int branchstart, int branchend) { + double cumulativeangle; + string name; + int m; + if ((visiblerotationid == -1) || ((parameters->peptidetype == cyclic) && (visiblerotationid == rotationid)) || ((parameters->peptidetype == lasso) && (visiblerotationid == rotationid/6))) { + for (int i = 0; i < (int)parameters->fragmentionsfortheoreticalspectra.size(); i++) { + if ((nterminal && parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].nterminal) || (!nterminal && parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].cterminal)) { + m = 0; + for (int j = fragmentstart; j < fragmentend; j++) { + if ((branchstart == -1) || (branchend == -1) || ((branchstart >= 0) && (j < branchstart)) || ((branchend >= 0) && (j >= branchend))) { + if (theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].series[j] > 0) { + name = theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].name.substr(0, theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].name.rfind('_') + 1); + name += parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].name[0] + to_string(j + 1) + parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].name.substr(1); + cumulativeangle = angle*(double)((2*numberofringblocks - rotationstart + numberofringblocks - m - 1) % numberofringblocks) + angle/(double)2; if (cumulativeangle < pi/2) { QPoint p4(centerx + sin(cumulativeangle)*(radius - linesize) + sin(pi/2 - cumulativeangle)*cornerlinesize, centery - sin(pi/2 - cumulativeangle)*(radius - linesize) + sin(cumulativeangle)*cornerlinesize); insertLabel(labels, p4.x() - 5, p4.y() - 5, name, true); @@ -296,12 +172,66 @@ void cCyclicWidget::paintEvent(QPaintEvent *event) { QPoint p4(centerx - sin(2*pi - cumulativeangle)*(radius - linesize) + sin(cumulativeangle - 3*pi/2)*cornerlinesize, centery - sin(cumulativeangle - 3*pi/2)*(radius - linesize) - sin(2*pi - cumulativeangle)*cornerlinesize); insertLabel(labels, p4.x() + 10, p4.y() - 10, name, false); } - } + } + m++; } } } } } +} + + +cCyclicWidget::cCyclicWidget() { + parameters = 0; + theoreticalspectrum = 0; + visiblerotationid = -1; +} + + +void cCyclicWidget::initialize(cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum) { + this->parameters = parameters; + this->theoreticalspectrum = theoreticalspectrum; +} + + +void cCyclicWidget::paintEvent(QPaintEvent *event) { + + if (theoreticalspectrum->getVisualCoverage().size() == 0) { + return; + } + + QPainter painter(this); + const int topmargin = 20;//max(20,(height() - 80)/2); + const int leftmargin = 20; + const int bottommargin = 80; + const int rightmargin = 20; + + int size = (int)theoreticalspectrum->getAcronyms().size(); + double angle = 2*pi/(double)size; + int centerx = width()/2; + int centery = height()/2; + int radius = min(width() - leftmargin - rightmargin, height() - topmargin - bottommargin)/2; + + const int horizontalstep = (width() - leftmargin - rightmargin)/std::max(size, 1); + + QFont myFont("Courier", 9); + painter.setFont(myFont); + + int linesize = 20; + int cornerlinesize = horizontalstep/8; + paintCircle(painter, (QColor &)(palette().color(QPalette::Background)), theoreticalspectrum->getAcronyms(), centerx, centery, radius, angle, horizontalstep, linesize, cornerlinesize); + + unordered_set labels; + labels.clear(); + + int half = (int)theoreticalspectrum->getVisualCoverage().size()/(int)parameters->fragmentionsfortheoreticalspectra.size()/2; + for (int i = 0; i < half; i++) { + generateCyclicLabelsToRight(true, i, i, 0, size - 1, size, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, -1, -1); + } + for (int i = half; i < 2*half; i++) { + generateCyclicLabelsToLeft(true, i, i, 0, size - 1, size, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, -1, -1); + } painter.setPen(QPen(Qt::red, 2, Qt::SolidLine)); for (auto it = labels.begin(); it != labels.end(); ++it) { diff --git a/CycloBranch/gui/cCyclicWidget.h b/CycloBranch/gui/cCyclicWidget.h index dff0e87..03cac46 100644 --- a/CycloBranch/gui/cCyclicWidget.h +++ b/CycloBranch/gui/cCyclicWidget.h @@ -19,6 +19,73 @@ class QPaintEvent; +const double pi = 3.141592653589793; + + +/** + \brief Paint the circle of a cyclic or a lasso peptide. + \param painter a reference to current QPainter + \param brushcolor a background color for rectangles with the acronyms of building blocks + \param acronymsofblocks acronyms of building blocks + \param centerx x coordinate of a center of the ring + \param centery y coordinate of a center of the ring + \param radius radius of the ring + \param angle an angle between two building blocks + \param horizontalstep determine width of rectangles with the acronyms of building blocks + \param linesize length of separators between building blocks + \param cornerlinesize length of endings of separators between building blocks +*/ +void paintCircle(QPainter& painter, QColor& brushcolor, vector& acronymsofblocks, int centerx, int centery, int radius, double angle, int horizontalstep, int linesize, int cornerlinesize); + + +/** + \brief Generate labels of fragment ions of a cyclic peptide (direction right). + \param nterminal if true only nterminal fragment ions are drawn, if false only cterminal fragment ions are drawn + \param rotationid id of a sequence rotation + \param rotationstart starting point on a ring to draw a series + \param fragmentstart first fragment to draw + \param fragmentend last fragment to draw + \param numberofringblocks number of building blocks on the ring + \param labels labels of fragment ions + \param parameters a pointer to parameters of the application + \param theoreticalspectrum a theoretical spectrum + \param centerx x coordinate of a center of the ring + \param centery y coordinate of a center of the ring + \param radius radius of the ring + \param angle an angle between two building blocks + \param linesize length of separators between building blocks + \param cornerlinesize length of endings of separators between building blocks + \param visiblerotationid id of a rotation whose fragment ions are visualized + \param branchstart starting position of a branch + \param branchend end position of a branch +*/ +void generateCyclicLabelsToRight(bool nterminal, int rotationid, int rotationstart, int fragmentstart, int fragmentend, int numberofringblocks, unordered_set& labels, cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum, int centerx, int centery, int radius, double angle, int linesize, int cornerlinesize, int visiblerotationid, int branchstart, int branchend); + + +/** + \brief Generate labels of fragment ions of a cyclic peptide (direction left). + \param nterminal if true only nterminal fragment ions are drawn, if false only cterminal fragment ions are drawn + \param rotationid id of a sequence rotation + \param rotationstart starting point on a ring to draw a series + \param fragmentstart first fragment to draw + \param fragmentend last fragment to draw + \param numberofringblocks number of building blocks on the ring + \param labels labels of fragment ions + \param parameters a pointer to parameters of the application + \param theoreticalspectrum a theoretical spectrum + \param centerx x coordinate of a center of the ring + \param centery y coordinate of a center of the ring + \param radius radius of the ring + \param angle an angle between two building blocks + \param linesize length of separators between building blocks + \param cornerlinesize length of endings of separators between building blocks + \param visiblerotationid id of a rotation whose fragment ions are visualized + \param branchstart starting position of a branch + \param branchend end position of a branch +*/ +void generateCyclicLabelsToLeft(bool nterminal, int rotationid, int rotationstart, int fragmentstart, int fragmentend, int numberofringblocks, unordered_set& labels, cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum, int centerx, int centery, int radius, double angle, int linesize, int cornerlinesize, int visiblerotationid, int branchstart, int branchend); + + /** \brief Visualization of a cyclic peptide. */ diff --git a/CycloBranch/gui/cGraphicalSpectrumWidget.cpp b/CycloBranch/gui/cGraphicalSpectrumWidget.cpp index a76bbb8..9bb7252 100644 --- a/CycloBranch/gui/cGraphicalSpectrumWidget.cpp +++ b/CycloBranch/gui/cGraphicalSpectrumWidget.cpp @@ -10,6 +10,8 @@ cGraphicalSpectrumWidget::cGraphicalSpectrumWidget(QWidget* parent) { this->parent = parent; + parameters = 0; + theoreticalspectrum = 0; origwidth = 0; origheight = 0; scale = 1; @@ -17,6 +19,8 @@ cGraphicalSpectrumWidget::cGraphicalSpectrumWidget(QWidget* parent) { hidematched = false; factor = 0.2; coloredrotationid = -1; + coloredrotationstring = ""; + coloredtrotationid = -1; pressedx = -1; pressedy = -1; currentx = 0; @@ -32,7 +36,8 @@ cGraphicalSpectrumWidget::~cGraphicalSpectrumWidget() { } -void cGraphicalSpectrumWidget::setTheoreticalSpectrum(cTheoreticalSpectrum* theoreticalspectrum) { +void cGraphicalSpectrumWidget::initialize(cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum) { + this->parameters = parameters; this->theoreticalspectrum = theoreticalspectrum; minmzratio = 0; maxmzratio = theoreticalspectrum->getExperimentalSpectrum().getMaximumMZRatio(); @@ -65,7 +70,7 @@ void cGraphicalSpectrumWidget::paintEvent(QPaintEvent *event) { int x; double y; - char tmpbuf[20]; + char tmpbuf[30]; string s; int w = origwidth; @@ -114,7 +119,60 @@ void cGraphicalSpectrumWidget::paintEvent(QPaintEvent *event) { y = theoreticalspectrum->getExperimentalSpectrum()[i].intensity/maxintensity * (h - topmargin - bottommargin); - if ((theoreticalspectrum->getExperimentalSpectrum()[i].matched > 0) && ((coloredrotationid == -1) || ((coloredrotationid != -1) && (theoreticalspectrum->getExperimentalSpectrum()[i].hasMatchedRotation(coloredrotationid))))) { + string coloredtrotationstring; + if (coloredtrotationid != -1) { + if (parameters->peptidetype == branched) { + coloredtrotationstring = " " + to_string(coloredtrotationid + 1) + "_"; + } + if (parameters->peptidetype == lasso) { + coloredtrotationstring = "_" + to_string(coloredtrotationid + 1) + "_"; + } + } + + vector hits; + hits.clear(); + s = theoreticalspectrum->getExperimentalSpectrum()[i].description; + int position = (int)s.find(','); + while (position != string::npos) { + hits.push_back(s.substr(0, position)); + s = s.substr(position + 1); + + if ((parameters->peptidetype == cyclic) && (coloredrotationid != -1) && (hits.back().find(coloredrotationstring) == string::npos)) { + hits.pop_back(); + } + + if ((parameters->peptidetype == branched) && (coloredtrotationid != -1) && (hits.back().find(coloredtrotationstring) == string::npos)) { + hits.pop_back(); + } + + if ((parameters->peptidetype == lasso) && (((coloredrotationid != -1) && (hits.back().find(coloredrotationstring) == string::npos)) || ((coloredtrotationid != -1) && (hits.back().find(coloredtrotationstring) == string::npos)))) { + hits.pop_back(); + } + + position = (int)s.find(','); + } + + if (s.size() > 0) { + hits.push_back(s); + + if ((parameters->peptidetype == cyclic) && (coloredrotationid != -1) && (hits.back().find(coloredrotationstring) == string::npos)) { + hits.pop_back(); + } + + if ((parameters->peptidetype == branched) && (coloredtrotationid != -1) && (hits.back().find(coloredtrotationstring) == string::npos)) { + hits.pop_back(); + } + + if ((parameters->peptidetype == lasso) && (((coloredrotationid != -1) && (hits.back().find(coloredrotationstring) == string::npos)) || ((coloredtrotationid != -1) && (hits.back().find(coloredtrotationstring) == string::npos)))) { + hits.pop_back(); + } + } + + sprintf_s(tmpbuf,"%.3f\0",theoreticalspectrum->getExperimentalSpectrum()[i].mzratio); + s = tmpbuf; + hits.push_back(s); + + if (hits.size() > 1) { painter.setPen(QPen(Qt::red, 2, Qt::SolidLine)); } else { @@ -123,13 +181,10 @@ void cGraphicalSpectrumWidget::paintEvent(QPaintEvent *event) { painter.drawLine(QPoint(x, h - bottommargin - 2), QPoint(x, h - bottommargin - std::max((int)y, 3))); - sprintf_s(tmpbuf,"%.3f\0",theoreticalspectrum->getExperimentalSpectrum()[i].mzratio); - s = tmpbuf; - if (theoreticalspectrum->getExperimentalSpectrum()[i].description.length() > 0) { - s += " (" + theoreticalspectrum->getExperimentalSpectrum()[i].description + ")"; + for (int i = 0; i < (int)hits.size(); i++) { + painter.drawText(x - 2, h - bottommargin - std::max((int)y, 3) - 15*((int)hits.size() - i), width(), 20, Qt::AlignLeft, hits[i].c_str()); } - //painter.drawText(QPoint((int)x + margin, h - margin - (int)y), tmpbuf); - drawVerticalText(&painter, QString(s.c_str()), x + 3, h - bottommargin - (int)y - 5); + } } @@ -342,3 +397,15 @@ void cGraphicalSpectrumWidget::rotationChanged(int index) { repaint(); } + +void cGraphicalSpectrumWidget::trotationChanged(int index) { + coloredtrotationid = index - 1; + repaint(); +} + + +void cGraphicalSpectrumWidget::rotationChanged(QString text) { + coloredrotationstring = " " + text.toStdString() + "_"; + repaint(); +} + diff --git a/CycloBranch/gui/cGraphicalSpectrumWidget.h b/CycloBranch/gui/cGraphicalSpectrumWidget.h index 0e58efc..7933811 100644 --- a/CycloBranch/gui/cGraphicalSpectrumWidget.h +++ b/CycloBranch/gui/cGraphicalSpectrumWidget.h @@ -45,10 +45,11 @@ class cGraphicalSpectrumWidget : public QWidget /** - \brief Set the theoretical spectrum. - \param theoreticalspectrum pointer to a theoretical spectrum + \brief Initialize the widget. + \param parameters a pointer to parameters + \param theoreticalspectrum a pointer to a theoretical spectrum */ - void setTheoreticalSpectrum(cTheoreticalSpectrum* theoreticalspectrum); + void initialize(cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum); protected: @@ -100,6 +101,7 @@ class cGraphicalSpectrumWidget : public QWidget void drawVerticalText(QPainter* painter, QString text, int x, int y); QWidget* parent; + cParameters* parameters; cTheoreticalSpectrum* theoreticalspectrum; qreal scale; @@ -107,6 +109,8 @@ class cGraphicalSpectrumWidget : public QWidget int origwidth, origheight; int coloredrotationid; + string coloredrotationstring; + int coloredtrotationid; bool hideunmatched; bool hidematched; @@ -152,6 +156,10 @@ private slots: void rotationChanged(int index); + void trotationChanged(int index); + + void rotationChanged(QString text); + }; #endif \ No newline at end of file diff --git a/CycloBranch/gui/cLassoWidget.cpp b/CycloBranch/gui/cLassoWidget.cpp new file mode 100644 index 0000000..20874c1 --- /dev/null +++ b/CycloBranch/gui/cLassoWidget.cpp @@ -0,0 +1,258 @@ +#include "gui/cLassoWidget.h" + +#include +#include +#include +#include + + +void generateBranchLabelsDown(bool nterminal, int rotationid, unordered_set& labels, cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum, int centerx, int topmargin, int horizontalstep, int verticalstep, int visiblerotationid, int branchstart) { + string name; + int j; + if ((visiblerotationid == -1) || (visiblerotationid == rotationid/6)) { + for (int i = 0; i < (int)parameters->fragmentionsfortheoreticalspectra.size(); i++) { + if ((nterminal && parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].nterminal) || (!nterminal && parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].cterminal)) { + j = 0; + while (j < branchstart) { + if (theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].series[j] > 0) { + name = theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].name.substr(0, theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].name.rfind('_') + 1); + name += parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].name[0] + to_string(j + 1) + parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].name.substr(1); + insertLabel(labels, centerx + 25, topmargin + verticalstep*j + verticalstep/2 - verticalstep/8, name, false); + } + j++; + } + } + } + } +} + + +void generateBranchLabelsUp(bool nterminal, int rotationid, unordered_set& labels, cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum, int centerx, int topmargin, int horizontalstep, int verticalstep, int visiblerotationid, int branchend) { + string name; + int j; + int count; + if ((visiblerotationid == -1) || (visiblerotationid == rotationid/6)) { + for (int i = 0; i < (int)parameters->fragmentionsfortheoreticalspectra.size(); i++) { + if ((nterminal && parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].nterminal) || (!nterminal && parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].cterminal)) { + j = 0; + count = (int)theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].series.size() - branchend; + while (j < count) { + if (theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].series[j + branchend] > 0) { + name = theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].name.substr(0, theoreticalspectrum->getVisualCoverage()[rotationid*parameters->fragmentionsfortheoreticalspectra.size() + i].name.rfind('_') + 1); + name += parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].name[0] + to_string(j + branchend + 1) + parameters->fragmentdefinitions[parameters->fragmentionsfortheoreticalspectra[i]].name.substr(1); + insertLabel(labels, centerx - 25, topmargin + verticalstep*(count - j - 1) + verticalstep/2, name, true); + } + j++; + } + } + } + } +} + + +cLassoWidget::cLassoWidget() { + parameters = 0; + theoreticalspectrum = 0; + visiblerotationid = -1; + visibletrotationid = -1; +} + + +void cLassoWidget::initialize(cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum) { + this->parameters = parameters; + this->theoreticalspectrum = theoreticalspectrum; +} + + +void cLassoWidget::paintEvent(QPaintEvent *event) { + + if (theoreticalspectrum->getVisualCoverage().size() == 0) { + return; + } + + vector backboneacronyms; + vector branchacronyms; + backboneacronyms = theoreticalspectrum->getBackboneAcronyms(); + branchacronyms = theoreticalspectrum->getBranchAcronyms(); + + QPainter painter(this); + const int topmargin = 20; + const int leftmargin = 20; + const int bottommargin = 80; + const int rightmargin = 20; + + int backbonesize = (int)backboneacronyms.size(); + int branchsize = (int)branchacronyms.size(); + double angle = 2*pi/(double)backbonesize; + int centerx = width()/2; + int centery = height()*3/4; + int radius = (height()/2 - bottommargin)/2; + + const int horizontalstep = (width() - leftmargin - rightmargin)/std::max(backbonesize, 1); + const int verticalstep = (centery - radius - topmargin - 10)/std::max(branchsize, 1); + + QFont myFont("Courier", 9); + painter.setFont(myFont); + + int linesize = 20; + int cornerlinesize = horizontalstep/8; + paintCircle(painter, (QColor &)(palette().color(QPalette::Background)), backboneacronyms, centerx, centery, radius, angle, horizontalstep, linesize, cornerlinesize); + + + // paint the branch + for (int i = 0; i < branchsize; i++) { + painter.setPen(QPen(Qt::blue, 2, Qt::SolidLine)); + painter.drawText(centerx - horizontalstep/3, topmargin + verticalstep*i, horizontalstep*2/3, 20, Qt::AlignCenter, branchacronyms[branchsize - i - 1].c_str()); + painter.drawText(centerx - horizontalstep/3, topmargin + verticalstep*i - 20, horizontalstep*2/3, 20, Qt::AlignLeft, to_string(backbonesize + branchsize - i).c_str()); + + painter.setPen(QPen(Qt::black, 2, Qt::SolidLine)); + painter.drawRect(centerx - horizontalstep/3, topmargin + verticalstep*i, horizontalstep*2/3, 20); + + painter.setPen(QPen(Qt::black, 2, Qt::SolidLine)); + painter.drawLine(centerx, topmargin + verticalstep*i + 20, centerx, topmargin + verticalstep*i + verticalstep); + painter.setPen(QPen(Qt::black, 2, Qt::DashLine)); + painter.drawLine(centerx - 20, topmargin + verticalstep*i + (verticalstep + 10)/2, centerx + 20, topmargin + verticalstep*i + (verticalstep + 10)/2); + painter.drawLine(centerx - 20, topmargin + verticalstep*i + (verticalstep + 10)/2, centerx - 20, topmargin + verticalstep*i + (verticalstep + 10)/2 + verticalstep/8); + painter.drawLine(centerx + 20, topmargin + verticalstep*i + (verticalstep + 10)/2 - verticalstep/8, centerx + 20, topmargin + verticalstep*i + (verticalstep + 10)/2); + + if (i == branchsize - 1) { + painter.setPen(QPen(Qt::black, 2, Qt::SolidLine)); + painter.drawLine(centerx, topmargin + verticalstep*i + verticalstep, centerx, centery - radius - 10); + } + } + + + // get lasso rotations + vector lassorotations; + theoreticalspectrum->getCandidate().getLassoRotations(lassorotations, true); + + // get T-permutations of lasso rotations + vector > trotationsoflassorotations; + trotationsoflassorotations.resize(lassorotations.size()); + for (int i = 0; i < (int)lassorotations.size(); i++) { + lassorotations[i].getPermutationsOfBranches(trotationsoflassorotations[i]); + } + + unordered_set labels; + labels.clear(); + + int rotationid; + int half = (int)theoreticalspectrum->getVisualCoverage().size()/(int)parameters->fragmentionsfortheoreticalspectra.size()/2; + for (int i = 0; i < half; i++) { + + if ((visibletrotationid != -1) && (visibletrotationid != i % 6)) { + continue; + } + + if (i/6 == 0) { + rotationid = half/6; + } + else { + rotationid = 2*half/6 - i/6; + } + + switch (i % 6) + { + case 0: + generateCyclicLabelsToRight(true, i, i/6, 0, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][0].middlebranchstart, trotationsoflassorotations[i/6][0].middlebranchend); + break; + case 1: + generateBranchLabelsDown(true, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][1].middlebranchstart); + generateCyclicLabelsToRight(true, i, -1, trotationsoflassorotations[i/6][1].middlebranchend, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][1].middlebranchstart, trotationsoflassorotations[i/6][1].middlebranchend); + break; + case 2: + generateCyclicLabelsToRight(true, rotationid*6 + 2, i/6, 0, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[rotationid][2].middlebranchstart, trotationsoflassorotations[rotationid][2].middlebranchend); + break; + case 3: + generateCyclicLabelsToRight(true, i, i/6, 0, trotationsoflassorotations[i/6][3].middlebranchstart, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][3].middlebranchstart, trotationsoflassorotations[i/6][3].middlebranchend); + generateBranchLabelsUp(true, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][3].middlebranchend); + generateBranchLabelsDown(false, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][4].middlebranchstart); + generateCyclicLabelsToLeft(false, i, 0, trotationsoflassorotations[i/6][4].middlebranchend, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][4].middlebranchstart, trotationsoflassorotations[i/6][4].middlebranchend); + break; + case 4: + generateBranchLabelsDown(true, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][4].middlebranchstart); + generateCyclicLabelsToLeft(true, i, 0, trotationsoflassorotations[i/6][4].middlebranchend, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][4].middlebranchstart, trotationsoflassorotations[i/6][4].middlebranchend); + break; + case 5: + generateCyclicLabelsToRight(true, rotationid*6 + 5, i/6, 0, trotationsoflassorotations[rotationid][5].middlebranchstart, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[rotationid][5].middlebranchstart, trotationsoflassorotations[rotationid][5].middlebranchend); + generateBranchLabelsUp(true, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][5].middlebranchend); + generateBranchLabelsDown(false, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][1].middlebranchstart); + generateCyclicLabelsToRight(false, i, -1, trotationsoflassorotations[i/6][1].middlebranchend, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][1].middlebranchstart, trotationsoflassorotations[i/6][1].middlebranchend); + break; + default: + break; + } + + } + + for (int i = half; i < 2*half; i++) { + + if ((visibletrotationid != -1) && (visibletrotationid != i % 6)) { + continue; + } + + if (i/6 == half/6) { + rotationid = 0; + } + else { + rotationid = 2*half/6 - i/6; + } + + switch (i % 6) + { + case 0: + generateCyclicLabelsToLeft(true, i, i/6, 0, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][0].middlebranchstart, trotationsoflassorotations[i/6][0].middlebranchend); + break; + case 1: + generateBranchLabelsDown(true, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][1].middlebranchstart); + generateCyclicLabelsToLeft(true, i, 0, trotationsoflassorotations[i/6][1].middlebranchend, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][1].middlebranchstart, trotationsoflassorotations[i/6][1].middlebranchend); + break; + case 2: + generateCyclicLabelsToLeft(true, rotationid*6 + 2, i/6, 0, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[rotationid][2].middlebranchstart, trotationsoflassorotations[rotationid][2].middlebranchend); + break; + case 3: + generateCyclicLabelsToLeft(true, i, i/6, 0, trotationsoflassorotations[i/6][3].middlebranchstart, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][3].middlebranchstart, trotationsoflassorotations[i/6][3].middlebranchend); + generateBranchLabelsUp(true, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][3].middlebranchend); + generateBranchLabelsDown(false, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][4].middlebranchstart); + generateCyclicLabelsToRight(false, i, -1, trotationsoflassorotations[i/6][4].middlebranchend, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][4].middlebranchstart, trotationsoflassorotations[i/6][4].middlebranchend); + break; + case 4: + generateBranchLabelsDown(true, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][4].middlebranchstart); + generateCyclicLabelsToRight(true, i, -1, trotationsoflassorotations[i/6][4].middlebranchend, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][4].middlebranchstart, trotationsoflassorotations[i/6][4].middlebranchend); + break; + case 5: + generateCyclicLabelsToLeft(true, rotationid*6 + 5, i/6, 0, trotationsoflassorotations[rotationid][5].middlebranchstart, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[rotationid][5].middlebranchstart, trotationsoflassorotations[rotationid][5].middlebranchend); + generateBranchLabelsUp(true, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][5].middlebranchend); + generateBranchLabelsDown(false, i, labels, parameters, theoreticalspectrum, centerx, topmargin, horizontalstep, verticalstep, visiblerotationid, trotationsoflassorotations[i/6][1].middlebranchstart); + generateCyclicLabelsToLeft(false, i, 0, trotationsoflassorotations[i/6][1].middlebranchend, backbonesize + branchsize - 1, backbonesize, labels, parameters, theoreticalspectrum, centerx, centery, radius, angle, linesize, cornerlinesize, visiblerotationid, trotationsoflassorotations[i/6][1].middlebranchstart, trotationsoflassorotations[i/6][1].middlebranchend); + break; + default: + break; + } + + } + + painter.setPen(QPen(Qt::red, 2, Qt::SolidLine)); + for (auto it = labels.begin(); it != labels.end(); ++it) { + if (it->alignright) { + painter.drawText(it->x - (int)it->label.size()*7, it->y, (int)it->label.size()*7, 20, Qt::AlignLeft, it->label.c_str()); + } + else { + painter.drawText(it->x, it->y, width(), 20, Qt::AlignLeft, it->label.c_str()); + } + } + +} + + +void cLassoWidget::rotationChanged(int index) { + visiblerotationid = index - 1; + repaint(); +} + + +void cLassoWidget::trotationChanged(int index) { + visibletrotationid = index - 1; + repaint(); +} + diff --git a/CycloBranch/gui/cLassoWidget.h b/CycloBranch/gui/cLassoWidget.h new file mode 100644 index 0000000..ee21684 --- /dev/null +++ b/CycloBranch/gui/cLassoWidget.h @@ -0,0 +1,107 @@ +/** + \file cLassoWidget.h + \brief Visualization of a lasso peptide. +*/ + + +#ifndef _CLASSOWIDGET_H +#define _CLASSOWIDGET_H + +#include +#include +#include + +#include "core/cTheoreticalSpectrum.h" +#include "gui/cLinearWidget.h" +#include "gui/cCyclicWidget.h" + + +// forward declaration +class QPaintEvent; + + +/** + \brief Generate labels of fragment ions on a branch of a lasso peptide (direction down). + \param nterminal if true only nterminal fragment ions are drawn, if false only cterminal fragment ions are drawn + \param rotationid id of a sequence rotation + \param labels labels of fragment ions + \param parameters a pointer to parameters of the application + \param theoreticalspectrum a theoretical spectrum + \param centerx x coordinate of a center of the ring + \param topmargin top margin in pixels + \param horizontalstep horizontal step (determine width of blocks) + \param verticalstep vertical step (determine height of blocks) + \param visiblerotationid id of a rotation whose fragment ions are visualized + \param branchstart starting position of a branch +*/ +void generateBranchLabelsDown(bool nterminal, int rotationid, unordered_set& labels, cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum, int centerx, int topmargin, int horizontalstep, int verticalstep, int visiblerotationid, int branchstart); + + +/** + \brief Generate labels of fragment ions on a branch of a lasso peptide (direction up). + \param nterminal if true only nterminal fragment ions are drawn, if false only cterminal fragment ions are drawn + \param rotationid id of a sequence rotation + \param labels labels of fragment ions + \param parameters a pointer to parameters of the application + \param theoreticalspectrum a theoretical spectrum + \param centerx x coordinate of a center of the ring + \param topmargin top margin in pixels + \param horizontalstep horizontal step (determine width of blocks) + \param verticalstep vertical step (determine height of blocks) + \param visiblerotationid id of a rotation whose fragment ions are visualized + \param branchend end position of a branch +*/ +void generateBranchLabelsUp(bool nterminal, int rotationid, unordered_set& labels, cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum, int centerx, int topmargin, int horizontalstep, int verticalstep, int visiblerotationid, int branchend); + + +/** + \brief Visualization of a lasso peptide. +*/ +class cLassoWidget : public QWidget +{ + Q_OBJECT + +public: + + + /** + \brief The constructor. + */ + cLassoWidget(); + + + /** + \brief Initialize the widget. + \param parameters a pointer to parameters + \param theoreticalspectrum a pointer to a theoretical spectrum + */ + void initialize(cParameters* parameters, cTheoreticalSpectrum* theoreticalspectrum); + + +protected: + + + /** + \brief Handle the paint event. + \param event pointer to QPaintEvent + */ + void paintEvent(QPaintEvent *event); + + +private: + + cParameters* parameters; + cTheoreticalSpectrum* theoreticalspectrum; + int visiblerotationid; + int visibletrotationid; + + +private slots: + + void rotationChanged(int index); + + void trotationChanged(int index); + +}; + +#endif \ No newline at end of file diff --git a/CycloBranch/gui/cMainThread.cpp b/CycloBranch/gui/cMainThread.cpp index e490428..fe106a9 100644 --- a/CycloBranch/gui/cMainThread.cpp +++ b/CycloBranch/gui/cMainThread.cpp @@ -2,7 +2,7 @@ QString appname = "CycloBranch"; -QString appversion = "v. 1.0.696 (64-bit)"; +QString appversion = "v. 1.0.739 (64-bit)"; cMainThread::cMainThread(cParameters& parameters, bool enablelogwindow, bool enablestdout) { @@ -145,11 +145,15 @@ void cMainThread::run() { return; } - bool error = false; string errormessage = ""; + cSummaryFormula formula; for (int i = 0; i < (int)parameters.searchedmodifications.size(); i++) { - parameters.searchedmodifications[i].massdifference = getMassFromResidueSummary(parameters.searchedmodifications[i].summary, error, errormessage); - if (error) { + formula.clear(); + formula.setFormula(parameters.searchedmodifications[i].summary); + if (formula.isValid(errormessage)) { + parameters.searchedmodifications[i].massdifference = formula.getMass(); + } + else { *os << errormessage << endl; emit safeExit(); return; @@ -295,7 +299,7 @@ void cMainThread::run() { } if (middlemodifid == -1) { - *os << endl << "Error: Unknown T-modification is used." << endl; + *os << endl << "Error: Unknown branch modification is used." << endl; emitEndSignals(); endNow(); return; diff --git a/CycloBranch/gui/cMainWindow.cpp b/CycloBranch/gui/cMainWindow.cpp index c6e68eb..674b712 100644 --- a/CycloBranch/gui/cMainWindow.cpp +++ b/CycloBranch/gui/cMainWindow.cpp @@ -125,7 +125,7 @@ cMainWindow::cMainWindow() { setWindowTitle(appname); - resultsbasecolumncount = 7; + resultsbasecolumncount = 8; resultsspecificcolumncount = 0; resultsDetails.clear(); @@ -243,42 +243,45 @@ void cMainWindow::sendTheoreticalSpectrum(cTheoreticalSpectrum theoreticalspectr results->setItem(row, 2, new QTableWidgetItem(stripHTML(theoreticalspectrum.getAcronymPeptideNameWithHTMLReferences()).c_str())); results->setItem(row, 3, new QTableWidgetItem()); - results->item(row, 3)->setData(Qt::DisplayRole, getNumberOfBricks(theoreticalspectrum.getCandidate().getComposition())); + results->item(row, 3)->setData(Qt::DisplayRole, theoreticalspectrum.getCandidate().getSummaryFormula(parameters).c_str()); + + results->setItem(row, 4, new QTableWidgetItem()); + results->item(row, 4)->setData(Qt::DisplayRole, getNumberOfBricks(theoreticalspectrum.getCandidate().getComposition())); switch (parameters.peptidetype) { case linear: - results->setItem(row, 4, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getStartModifID()].name.c_str())); - results->setItem(row, 5, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getEndModifID()].name.c_str())); + results->setItem(row, 5, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getStartModifID()].name.c_str())); + results->setItem(row, 6, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getEndModifID()].name.c_str())); break; case branched: - results->setItem(row, 4, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getStartModifID()].name.c_str())); - results->setItem(row, 5, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getMiddleModifID()].name.c_str())); - results->setItem(row, 6, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getEndModifID()].name.c_str())); + results->setItem(row, 5, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getStartModifID()].name.c_str())); + results->setItem(row, 6, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getMiddleModifID()].name.c_str())); + results->setItem(row, 7, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getEndModifID()].name.c_str())); break; case cyclic: - results->setItem(row, 4, new QTableWidgetItem()); - results->item(row, 4)->setData(Qt::DisplayRole, theoreticalspectrum.getNumberOfMatchedBricks()); + results->setItem(row, 5, new QTableWidgetItem()); + results->item(row, 5)->setData(Qt::DisplayRole, theoreticalspectrum.getNumberOfMatchedBricks()); break; case lasso: - results->setItem(row, 4, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getMiddleModifID()].name.c_str())); + results->setItem(row, 5, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getMiddleModifID()].name.c_str())); break; case linearpolysaccharide: - results->setItem(row, 4, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getStartModifID()].name.c_str())); - results->setItem(row, 5, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getEndModifID()].name.c_str())); + results->setItem(row, 5, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getStartModifID()].name.c_str())); + results->setItem(row, 6, new QTableWidgetItem(parameters.searchedmodifications[theoreticalspectrum.getCandidate().getEndModifID()].name.c_str())); break; default: break; } - results->setItem(row, 4 + resultsspecificcolumncount, new QTableWidgetItem()); - results->item(row, 4 + resultsspecificcolumncount)->setData(Qt::DisplayRole, theoreticalspectrum.getNumberOfMatchedPeaks()); - results->setItem(row, 5 + resultsspecificcolumncount, new QTableWidgetItem()); - results->item(row, 5 + resultsspecificcolumncount)->setData(Qt::DisplayRole, theoreticalspectrum.getRatioOfMatchedPeaks()*100); + results->item(row, 5 + resultsspecificcolumncount)->setData(Qt::DisplayRole, theoreticalspectrum.getNumberOfMatchedPeaks()); results->setItem(row, 6 + resultsspecificcolumncount, new QTableWidgetItem()); - results->item(row, 6 + resultsspecificcolumncount)->setData(Qt::DisplayRole, theoreticalspectrum.getWeightedIntensityScore()); + results->item(row, 6 + resultsspecificcolumncount)->setData(Qt::DisplayRole, theoreticalspectrum.getRatioOfMatchedPeaks()*100); + + results->setItem(row, 7 + resultsspecificcolumncount, new QTableWidgetItem()); + results->item(row, 7 + resultsspecificcolumncount)->setData(Qt::DisplayRole, theoreticalspectrum.getWeightedIntensityScore()); for (int i = 0; i < (int)parameters.fragmentionsfortheoreticalspectra.size(); i++) { results->setItem(row, resultsbasecolumncount + resultsspecificcolumncount + i, new QTableWidgetItem()); @@ -334,36 +337,37 @@ void cMainWindow::prepareColumns() { results->setHorizontalHeaderItem(0, new QTableWidgetItem("*")); results->setHorizontalHeaderItem(1, new QTableWidgetItem("Result ID")); results->setHorizontalHeaderItem(2, new QTableWidgetItem("Peptide Sequence")); - results->setHorizontalHeaderItem(3, new QTableWidgetItem("Number of Bricks")); + results->setHorizontalHeaderItem(3, new QTableWidgetItem("Neutral Formula")); + results->setHorizontalHeaderItem(4, new QTableWidgetItem("Number of Bricks")); switch (parameters.peptidetype) { case linear: - results->setHorizontalHeaderItem(4, new QTableWidgetItem("N-terminal Modification")); - results->setHorizontalHeaderItem(5, new QTableWidgetItem("C-terminal Modification")); + results->setHorizontalHeaderItem(5, new QTableWidgetItem("N-terminal Modification")); + results->setHorizontalHeaderItem(6, new QTableWidgetItem("C-terminal Modification")); break; case branched: - results->setHorizontalHeaderItem(4, new QTableWidgetItem("N-terminal Modification")); - results->setHorizontalHeaderItem(5, new QTableWidgetItem("T-Modification")); - results->setHorizontalHeaderItem(6, new QTableWidgetItem("C-terminal Modification")); + results->setHorizontalHeaderItem(5, new QTableWidgetItem("N-terminal Modification")); + results->setHorizontalHeaderItem(6, new QTableWidgetItem("Branch Modification")); + results->setHorizontalHeaderItem(7, new QTableWidgetItem("C-terminal Modification")); break; case cyclic: - results->setHorizontalHeaderItem(4, new QTableWidgetItem("Matched Bricks")); + results->setHorizontalHeaderItem(5, new QTableWidgetItem("Matched Bricks")); break; case lasso: - results->setHorizontalHeaderItem(4, new QTableWidgetItem("T-Modification")); + results->setHorizontalHeaderItem(5, new QTableWidgetItem("Branch Modification")); break; case linearpolysaccharide: - results->setHorizontalHeaderItem(4, new QTableWidgetItem("N-terminal Modification")); - results->setHorizontalHeaderItem(5, new QTableWidgetItem("C-terminal Modification")); + results->setHorizontalHeaderItem(5, new QTableWidgetItem("N-terminal Modification")); + results->setHorizontalHeaderItem(6, new QTableWidgetItem("C-terminal Modification")); break; default: break; } - results->setHorizontalHeaderItem(4 + resultsspecificcolumncount, new QTableWidgetItem("Matched Peaks")); - results->setHorizontalHeaderItem(5 + resultsspecificcolumncount, new QTableWidgetItem("Ratio of Matched Peaks [%]")); - results->setHorizontalHeaderItem(6 + resultsspecificcolumncount, new QTableWidgetItem("Sum of Relative Intensities")); + results->setHorizontalHeaderItem(5 + resultsspecificcolumncount, new QTableWidgetItem("Matched Peaks")); + results->setHorizontalHeaderItem(6 + resultsspecificcolumncount, new QTableWidgetItem("Ratio of Matched Peaks [%]")); + results->setHorizontalHeaderItem(7 + resultsspecificcolumncount, new QTableWidgetItem("Sum of Relative Intensities")); for (int i = 0; i < (int)parameters.fragmentionsfortheoreticalspectra.size(); i++) { results->setHorizontalHeaderItem(resultsbasecolumncount + resultsspecificcolumncount + i, new QTableWidgetItem(parameters.fragmentdefinitions[(fragmentIonType)parameters.fragmentionsfortheoreticalspectra[i]].name.c_str())); diff --git a/CycloBranch/gui/cParametersWidget.cpp b/CycloBranch/gui/cParametersWidget.cpp index 06c8b41..f5b17b8 100644 --- a/CycloBranch/gui/cParametersWidget.cpp +++ b/CycloBranch/gui/cParametersWidget.cpp @@ -289,7 +289,7 @@ cParametersWidget::cParametersWidget() { searchedsequenceTmodif = new QLineEdit(); searchedsequenceTmodif->setToolTip("A name of an N-terminal or C-terminal modification as defined in the window \"N-terminal and C-terminal Modifications\" which belongs to a branch of a searched peptide (branched and lasso peptides only)."); - searchedsequenceformlayout->addRow(tr("T-Modification: "), searchedsequenceTmodif); + searchedsequenceformlayout->addRow(tr("Branch Modification: "), searchedsequenceTmodif); searchedsequencegroupbox = new QGroupBox("Searched Peptide Sequence"); searchedsequencegroupbox->setLayout(searchedsequenceformlayout); diff --git a/CycloBranch/gui/cParametersWidget.h b/CycloBranch/gui/cParametersWidget.h index 4318ca3..c2ece92 100644 --- a/CycloBranch/gui/cParametersWidget.h +++ b/CycloBranch/gui/cParametersWidget.h @@ -14,9 +14,8 @@ #include #include -#include "core/cFragmentIons.h" +#include "core/cSummaryFormula.h" #include "core/cParameters.h" - #include "gui/cFragmentIonsListWidget.h" diff --git a/CycloBranch/gui/cSpectrumDetailWidget.cpp b/CycloBranch/gui/cSpectrumDetailWidget.cpp index 5b298d7..bd8881b 100644 --- a/CycloBranch/gui/cSpectrumDetailWidget.cpp +++ b/CycloBranch/gui/cSpectrumDetailWidget.cpp @@ -16,6 +16,7 @@ cSpectrumDetailWidget::cSpectrumDetailWidget() { rotation = 0; + trotation = 0; parameters = 0; preparedToShow = false; @@ -25,6 +26,7 @@ cSpectrumDetailWidget::cSpectrumDetailWidget() { cSpectrumDetailWidget::cSpectrumDetailWidget(const cSpectrumDetailWidget& sd) { rotation = 0; + trotation = 0; parameters = sd.parameters; preparedToShow = false; @@ -109,6 +111,10 @@ cSpectrumDetailWidget::~cSpectrumDetailWidget() { delete rotation; } + if (trotation) { + delete trotation; + } + delete formlayout; delete formwidget; @@ -125,6 +131,7 @@ cSpectrumDetailWidget::~cSpectrumDetailWidget() { delete branchedwidget; break; case lasso: + delete lassowidget; break; case linearpolysaccharide: break; @@ -173,6 +180,7 @@ void cSpectrumDetailWidget::prepareToShow(peptideType peptidetype) { branchedwidget = new cBranchedWidget(); break; case lasso: + lassowidget = new cLassoWidget(); break; case linearpolysaccharide: break; @@ -261,22 +269,68 @@ void cSpectrumDetailWidget::prepareToShow(peptideType peptidetype) { rotation->addItem(tr("all")); string s; - for (int i = 0; i < 2*r; i++) { - s = theoreticalspectrum->getVisualCoverage()[i*hint].name.substr(0, theoreticalspectrum->getVisualCoverage()[i*hint].name.rfind('_')); - /* - if (i < r) { - s += " >>>"; - } - else { - s += " <<<"; + if (theoreticalspectrum->getVisualCoverage().size() > 0) { + for (int i = 0; i < 2*r; i++) { + s = theoreticalspectrum->getVisualCoverage()[i*hint].name.substr(0, theoreticalspectrum->getVisualCoverage()[i*hint].name.rfind('_')); + rotation->addItem(tr(s.c_str())); } - */ - rotation->addItem(tr(s.c_str())); } connect(rotation, SIGNAL(currentIndexChanged(int)), graphicalspectrum, SLOT(rotationChanged(int))); + connect(rotation, SIGNAL(currentIndexChanged(QString)), graphicalspectrum, SLOT(rotationChanged(QString))); connect(rotation, SIGNAL(currentIndexChanged(int)), cyclicwidget, SLOT(rotationChanged(int))); - formlayout->addRow(tr("Show matched series: "), rotation); + formlayout->addRow(tr("Ring break up point: "), rotation); + } + + // branched + if (parameters && (parameters->peptidetype == branched)) { + trotation = new QComboBox(); + trotation->addItem(tr("all")); + trotation->addItem(tr("1 (left-to-right)")); + trotation->addItem(tr("2 (top-to-right)")); + trotation->addItem(tr("3 (right-to-left)")); + trotation->addItem(tr("4 (left-to-top)")); + trotation->addItem(tr("5 (top-to-left)")); + trotation->addItem(tr("6 (right-to-top)")); + + connect(trotation, SIGNAL(currentIndexChanged(int)), graphicalspectrum, SLOT(trotationChanged(int))); + connect(trotation, SIGNAL(currentIndexChanged(int)), branchedwidget, SLOT(trotationChanged(int))); + formlayout->addRow(tr("Linearized sequence: "), trotation); + } + + // lasso + if (parameters && theoreticalspectrum && (parameters->peptidetype == lasso)) { + int r = (int)theoreticalspectrum->getAcronyms().size() - (int)theoreticalspectrum->getCandidate().getBranchSize(); + int hint = (int)theoreticalspectrum->getVisualCoverage().size()/(2*r); + + rotation = new QComboBox(); + rotation->addItem(tr("all")); + + string s; + if (theoreticalspectrum->getVisualCoverage().size() > 0) { + for (int i = 0; i < 2*r; i++) { + s = theoreticalspectrum->getVisualCoverage()[i*hint].name.substr(0, theoreticalspectrum->getVisualCoverage()[i*hint].name.find('_')); + rotation->addItem(tr(s.c_str())); + } + } + + connect(rotation, SIGNAL(currentIndexChanged(int)), graphicalspectrum, SLOT(rotationChanged(int))); + connect(rotation, SIGNAL(currentIndexChanged(QString)), graphicalspectrum, SLOT(rotationChanged(QString))); + connect(rotation, SIGNAL(currentIndexChanged(int)), lassowidget, SLOT(rotationChanged(int))); + formlayout->addRow(tr("Ring break up point: "), rotation); + + trotation = new QComboBox(); + trotation->addItem(tr("all")); + trotation->addItem(tr("1 (left-to-right)")); + trotation->addItem(tr("2 (top-to-right)")); + trotation->addItem(tr("3 (right-to-left)")); + trotation->addItem(tr("4 (left-to-top)")); + trotation->addItem(tr("5 (top-to-left)")); + trotation->addItem(tr("6 (right-to-top)")); + + connect(trotation, SIGNAL(currentIndexChanged(int)), graphicalspectrum, SLOT(trotationChanged(int))); + connect(trotation, SIGNAL(currentIndexChanged(int)), lassowidget, SLOT(trotationChanged(int))); + formlayout->addRow(tr("Linearized sequence: "), trotation); } formwidget = new QWidget(); @@ -314,6 +368,13 @@ void cSpectrumDetailWidget::prepareToShow(peptideType peptidetype) { vsplitter2->setStretchFactor(2, 5); break; case lasso: + vsplitter2->addWidget(formwidget); + vsplitter2->addWidget(lassowidget); + vsplitter2->addWidget(textedit); + vsplitter2->setStretchFactor(0, 2); + vsplitter2->setStretchFactor(1, 3); + vsplitter2->setStretchFactor(2, 5); + break; case linearpolysaccharide: vsplitter2->addWidget(formwidget); vsplitter2->addWidget(textedit); @@ -335,7 +396,7 @@ void cSpectrumDetailWidget::prepareToShow(peptideType peptidetype) { resize(1280, 700); - if (theoreticalspectrum) { + if (parameters && theoreticalspectrum) { switch (peptidetype) { @@ -349,6 +410,7 @@ void cSpectrumDetailWidget::prepareToShow(peptideType peptidetype) { branchedwidget->initialize(parameters, theoreticalspectrum); break; case lasso: + lassowidget->initialize(parameters, theoreticalspectrum); break; case linearpolysaccharide: break; @@ -356,7 +418,7 @@ void cSpectrumDetailWidget::prepareToShow(peptideType peptidetype) { break; } - graphicalspectrum->setTheoreticalSpectrum(theoreticalspectrum); + graphicalspectrum->initialize(parameters, theoreticalspectrum); textedit->setHtml(theoreticalspectrum->getCoverageBySeries().c_str()); textbrowser->setHtml(getDetailsAsHTMLString().c_str()); diff --git a/CycloBranch/gui/cSpectrumDetailWidget.h b/CycloBranch/gui/cSpectrumDetailWidget.h index 61349dd..01c528f 100644 --- a/CycloBranch/gui/cSpectrumDetailWidget.h +++ b/CycloBranch/gui/cSpectrumDetailWidget.h @@ -12,6 +12,7 @@ #include "gui/cLinearWidget.h" #include "gui/cCyclicWidget.h" #include "gui/cBranchedWidget.h" +#include "gui/cLassoWidget.h" #include "gui/cGraphicalSpectrumWidget.h" @@ -114,12 +115,14 @@ class cSpectrumDetailWidget : public QWidget QCheckBox* hideunmatched; QCheckBox* hidematched; QComboBox* rotation; + QComboBox* trotation; QTextEdit* textedit; QTextBrowser* textbrowser; cLinearWidget* linearwidget; cCyclicWidget* cyclicwidget; cBranchedWidget* branchedwidget; + cLassoWidget* lassowidget; QScrollArea* graphicalspectrumscroll; cGraphicalSpectrumWidget* graphicalspectrum;