From 7ddf916639af301cee368e413ee97e639ba45122 Mon Sep 17 00:00:00 2001 From: Julianus Pfeuffer Date: Thu, 12 Aug 2021 17:39:44 +0200 Subject: [PATCH 1/6] More fixes and cleanups and TODOs --- .../include/OpenMS/VISUAL/DataSelectionTabs.h | 2 +- .../OpenMS/VISUAL/SequenceVisualizer.h | 2 +- .../include/OpenMS/VISUAL/SpectraTreeTab.h | 7 ++- .../VISUAL/APPLICATIONS/TOPPViewBase.cpp | 3 +- .../source/VISUAL/DataSelectionTabs.cpp | 16 +++++-- .../source/VISUAL/ICONS/sequence_viz.html | 3 +- src/openms_gui/source/VISUAL/Plot1DCanvas.cpp | 5 +- .../source/VISUAL/SequenceVisualizer.cpp | 8 ++-- .../source/VISUAL/SpectraIDViewTab.cpp | 48 +++++++++++-------- .../source/VISUAL/SpectraTreeTab.cpp | 22 +++++++-- .../VISUAL/TVIdentificationViewController.cpp | 9 +++- .../source/VISUAL/TVSpectraViewController.cpp | 1 + 12 files changed, 85 insertions(+), 41 deletions(-) diff --git a/src/openms_gui/include/OpenMS/VISUAL/DataSelectionTabs.h b/src/openms_gui/include/OpenMS/VISUAL/DataSelectionTabs.h index fcbec247cc9..76956bf3adc 100644 --- a/src/openms_gui/include/OpenMS/VISUAL/DataSelectionTabs.h +++ b/src/openms_gui/include/OpenMS/VISUAL/DataSelectionTabs.h @@ -93,7 +93,7 @@ namespace OpenMS /// Tabs which have data to show are automatically enabled. Others are disabled. /// If the currently visible tab would have to data to show, we pick the highest (rightmost) tab /// which has data and show that instead - void update(); + void callUpdateEntries(); /// invoked when user changes the active tab to @p tab_index void currentTabChanged(int tab_index); diff --git a/src/openms_gui/include/OpenMS/VISUAL/SequenceVisualizer.h b/src/openms_gui/include/OpenMS/VISUAL/SequenceVisualizer.h index 4d9d3b7b2b3..c9dcacaf8cd 100644 --- a/src/openms_gui/include/OpenMS/VISUAL/SequenceVisualizer.h +++ b/src/openms_gui/include/OpenMS/VISUAL/SequenceVisualizer.h @@ -28,7 +28,7 @@ namespace OpenMS public slots: - void setProteinPeptideDataToJsonObj(QString accession_num, QString pro_seq, QJsonArray peptides_data, QJsonArray pep_mod_data); + void setProteinPeptideDataToJsonObj(const QString& accession_num, const QString& pro_seq, const QJsonArray& peptides_data, const QJsonArray& pep_mod_data); private: Ui::SequenceVisualizer* ui; diff --git a/src/openms_gui/include/OpenMS/VISUAL/SpectraTreeTab.h b/src/openms_gui/include/OpenMS/VISUAL/SpectraTreeTab.h index e26e30c4b52..5fe4e14cadc 100644 --- a/src/openms_gui/include/OpenMS/VISUAL/SpectraTreeTab.h +++ b/src/openms_gui/include/OpenMS/VISUAL/SpectraTreeTab.h @@ -80,6 +80,9 @@ namespace OpenMS /// @param current_type Either DT_PEAK or DT_CHROMATOGRAM, depending on what is currently shown bool getSelectedScan(MSExperiment& exp, LayerData::DataType& current_type) const; + /// received focus e.g. through tabswitching + void updateIndexFromCurrentLayer(); + signals: void spectrumSelected(int); void chromsSelected(std::vector indices); @@ -92,13 +95,15 @@ namespace OpenMS QLineEdit* spectra_search_box_ = nullptr; QComboBox* spectra_combo_box_ = nullptr; TreeView* spectra_treewidget_ = nullptr; + LayerData* layer_ = nullptr; /// cache to store mapping of chromatogram precursors to chromatogram indices std::map, Precursor::MZLess> > map_precursor_to_chrom_idx_cache_; /// remember the last PeakMap that we used to fill the spectra list (and avoid rebuilding it) const PeakMap* last_peakmap_ = nullptr; private slots: - /// fill the search-combo-box with current column header names + + /// fill the search-combo-box with current column header names void populateSearchBox_(); /// searches for rows containing a search text (from spectra_search_box_); called when text search box is used void spectrumSearchText_(); diff --git a/src/openms_gui/source/VISUAL/APPLICATIONS/TOPPViewBase.cpp b/src/openms_gui/source/VISUAL/APPLICATIONS/TOPPViewBase.cpp index 2909ab0b8f4..c3f0796ffe2 100644 --- a/src/openms_gui/source/VISUAL/APPLICATIONS/TOPPViewBase.cpp +++ b/src/openms_gui/source/VISUAL/APPLICATIONS/TOPPViewBase.cpp @@ -2022,7 +2022,8 @@ namespace OpenMS { return; } - selection_view_->currentTabChanged(1); //switch to ID view + selection_view_->setCurrentIndex(DataSelectionTabs::IDENT_IDX); //switch to ID view + selection_view_->currentTabChanged(DataSelectionTabs::IDENT_IDX); } void TOPPViewBase::annotateWithOSW() diff --git a/src/openms_gui/source/VISUAL/DataSelectionTabs.cpp b/src/openms_gui/source/VISUAL/DataSelectionTabs.cpp index 9d001938f2a..4e357c425fe 100644 --- a/src/openms_gui/source/VISUAL/DataSelectionTabs.cpp +++ b/src/openms_gui/source/VISUAL/DataSelectionTabs.cpp @@ -113,7 +113,7 @@ namespace OpenMS // called externally // and internally by signals - void DataSelectionTabs::update() + void DataSelectionTabs::callUpdateEntries() { // prevent infinite loop when calling 'setTabEnabled' -> currentTabChanged() -> update() this->blockSignals(true); @@ -151,7 +151,6 @@ namespace OpenMS Size current_index = currentIndex(); // update the currently visible tab (might be disabled if no data is shown) tab_ptrs_[current_index]->updateEntries(layer_ptr); - this->update(); // not sure if necessary. Should update itself if changes occurred. } void DataSelectionTabs::currentTabChanged(int tab_index) @@ -167,9 +166,13 @@ namespace OpenMS case IDENT_IDX: spectraview_controller_->deactivateBehavior(); diatab_controller_->deactivateBehavior(); - if (tv_->getActive2DWidget()) // currently 2D window is open + std::cout << "trying to switch to Ident tab" << std::endl; + if (tv_->getActive2DWidget()) // currently, 2D window is open { + std::cout << "2D was open" << std::endl; idview_controller_->showSpectrumAsNew1D(0); + } else { + std::cout << "2D was NOT open" << std::endl; } idview_controller_->activateBehavior(); break; @@ -182,7 +185,12 @@ namespace OpenMS std::cerr << "Error: tab_index " << tab_index << " is invalid\n"; throw Exception::NotImplemented(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION); } - update(); + callUpdateEntries(); //TODO actually this is overkill. Why would you load the entire table again + // when you only switched tabs? The TabView should get notified when the layer data changes, so it only + // updates when necessary... + // The only thing that maybe needs to happen when switching tabs is to sync the index across the tables in the different tabs. + // which is the only reason why we need to actually use callUpdateEntries here. + // At least we reduced it to only updateEntries during tab switch, not EVERY update() [e.g. when resizing, refocussing...] } void DataSelectionTabs::showSpectrumAsNew1D(int index) diff --git a/src/openms_gui/source/VISUAL/ICONS/sequence_viz.html b/src/openms_gui/source/VISUAL/ICONS/sequence_viz.html index 18310c1cb9a..cd9f7670c5a 100644 --- a/src/openms_gui/source/VISUAL/ICONS/sequence_viz.html +++ b/src/openms_gui/source/VISUAL/ICONS/sequence_viz.html @@ -117,6 +117,7 @@ length="${protlen}" displaystart="1" displayend="${protlen}" + numberofticks="0" use-ctrl-to-zoom="true" highlight-event="onmouseover" /> @@ -132,7 +133,7 @@ let modProtTrack = ` = spec.size()) { // somehow the peak is invalid. This happens from time to time and should be tracked down elsewhere - // but its hard to reproduce (changing spectra in 1D view using arrow keys while hovering over the spectrum with the mouse?). + // but it's hard to reproduce (changing spectra in 1D view using arrow keys while hovering over the spectrum with the mouse?). return; } const ExperimentType::PeakType& sel = spec[peak.peak]; @@ -2096,6 +2096,7 @@ namespace OpenMS // be an in-memory representation in the peak data structure. Using // setCurrentSpectrumIndex will select the appropriate spectrum and load it // into memory. + std::cout << "Current nr. spec: " << getCurrentLayer().getPeakData()->size() << std::endl; if (index < getCurrentLayer().getPeakData()->size()) { getCurrentLayer().setCurrentSpectrumIndex(index); diff --git a/src/openms_gui/source/VISUAL/SequenceVisualizer.cpp b/src/openms_gui/source/VISUAL/SequenceVisualizer.cpp index 6e0572e4738..e2ef81b4fe5 100644 --- a/src/openms_gui/source/VISUAL/SequenceVisualizer.cpp +++ b/src/openms_gui/source/VISUAL/SequenceVisualizer.cpp @@ -31,10 +31,10 @@ namespace OpenMS delete ui; } - void SequenceVisualizer::setProteinPeptideDataToJsonObj(QString accession_num, - QString pro_seq, - QJsonArray pep_data, - QJsonArray pep_mod_data) + void SequenceVisualizer::setProteinPeptideDataToJsonObj(const QString& accession_num, + const QString& pro_seq, + const QJsonArray& pep_data, + const QJsonArray& pep_mod_data) { m_json_data_obj["accession_num"] = accession_num; m_json_data_obj["protein_sequence_data"] = pro_seq; diff --git a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp index 0489ea86f88..d098e834645 100644 --- a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp +++ b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp @@ -315,20 +315,18 @@ namespace OpenMS { const vector& pep_hits = pep.getHits(); const PeptideHit& hit = pep_hits[0]; - const String& pep_seq = hit.getSequence().toString(); + const AASequence& aaseq = hit.getSequence(); // contains the keys - mod_data, pep_start and seq and corresponding values QJsonObject peptides_mod_obj; // contains key-value of modName and vector of indices QJsonObject mod_data; - - auto seq = AASequence().fromString(pep_seq); - for (int i = 0; i < seq.size(); ++i) + for (int i = 0; i < aaseq.size(); ++i) { - if (seq[i].isModified()) + if (aaseq[i].isModified()) { - const String& mod_name = seq[i].getModificationName(); + const String& mod_name = aaseq[i].getModificationName(); if (!mod_data.contains(mod_name.toQString())) { @@ -345,25 +343,30 @@ namespace OpenMS peptides_mod_obj["mod_data"] = mod_data; - //store start and end positions- - for (int j = 0; j < pep_hits.size(); ++j) + const auto qstrseq = aaseq.toString().toQString(); + //store start and end positions + //TODO maybe we could store the index of the hit that belongs to that specific protein in the map as well + // or we generally should only look at the first hit + for (const auto & pep_hit : pep_hits) { - const vector& evidences = pep_hits[j].getPeptideEvidences(); + const vector& evidences = pep_hit.getPeptideEvidences(); - for (int k = 0; k < evidences.size(); ++k) + for (const auto & evidence : evidences) { - const String& id_accession = evidences[k].getProteinAccession(); + const String& id_accession = evidence.getProteinAccession(); QJsonObject data; - int pep_start = evidences[k].getStart(); - int pep_end = evidences[k].getEnd(); - if (id_accession.toQString()== current_accession) + int pep_start = evidence.getStart(); + int pep_end = evidence.getEnd(); + if (id_accession.toQString() == current_accession) { data["start"] = pep_start; data["end"] = pep_end; - data["seq"] = pep_seq.toQString(); + data["seq"] = qstrseq; + //TODO why does the modification need to store the peptide sequence? + // the modifications in theory only need one index and this is their location peptides_mod_obj["pep_start"] = pep_start; - peptides_mod_obj["seq"] = pep_seq.toQString(); + peptides_mod_obj["seq"] = qstrseq; peptides_data.push_back(data); } @@ -377,11 +380,11 @@ namespace OpenMS const vector& protein_hits = prot_id[current_identification_index].getHits(); QString pro_sequence; - for (int i = 0; i < protein_hits.size(); ++i) + for (const auto & protein_hit : protein_hits) { - const String& protein_accession = protein_hits[i].getAccession(); - const String& protein_sequence = protein_hits[i].getSequence(); + const String& protein_accession = protein_hit.getAccession(); + const String& protein_sequence = protein_hit.getSequence(); if (protein_accession.toQString() == current_accession) { @@ -390,7 +393,8 @@ namespace OpenMS } } - SequenceVisualizer* widget = new SequenceVisualizer(); + auto* widget = new SequenceVisualizer(); // no parent since we want a new window + widget->resize(1500,500); // make a bit bigger widget->setProteinPeptideDataToJsonObj(accession_num, pro_sequence, peptides_data, peptides_mod_data); widget->show(); } @@ -923,13 +927,15 @@ namespace OpenMS selected_item->setSelected(true); table_widget_->setCurrentItem(selected_item); table_widget_->scrollToItem(selected_item); + currentCellChanged_(selected_row,0,0,0); //simulate cell change to trigger repaint and reannotation of spectrum 1D view } table_widget_->blockSignals(false); table_widget_->setUpdatesEnabled(true); + // call this updateProteinEntries_(-1) function after the table_widget data is filled, // otherwise table_widget_->item(row, clm) returns nullptr; - updateProteinEntries_(-1);// we need this extra function since it's an internal slot + updateProteinEntries_(selected_row); } diff --git a/src/openms_gui/source/VISUAL/SpectraTreeTab.cpp b/src/openms_gui/source/VISUAL/SpectraTreeTab.cpp index 6dedb1845fb..a15f87982c4 100644 --- a/src/openms_gui/source/VISUAL/SpectraTreeTab.cpp +++ b/src/openms_gui/source/VISUAL/SpectraTreeTab.cpp @@ -87,7 +87,7 @@ namespace OpenMS }; // keep in SYNC with enum HeaderNames const QStringList HEADER_NAMES = QStringList() - << " type" << "index" << "m/z" << "Description" << "rt start" << "rt end" << "charge" << "chromatogram type";; + << " type" << "index" << "m/z" << "Description" << "rt start" << "rt end" << "charge" << "chromatogram type"; } struct IndexExtrator @@ -182,12 +182,20 @@ namespace OpenMS } } + void SpectraTreeTab::updateIndexFromCurrentLayer() + { + std::cout << "Spectra tab view activated to go to position " << layer_->getCurrentSpectrumIndex() << std::endl; + spectra_treewidget_->setTreePosition(layer_->getCurrentSpectrumIndex()); + } + void SpectraTreeTab::itemSelectionChange_(QTreeWidgetItem* current, QTreeWidgetItem* previous) { /* test for previous == 0 is important - without it, the wrong spectrum will be selected after finishing the execution of a TOPP tool on the whole data */ - if (current == nullptr || previous == nullptr) + // WUT???? + std::cout << "itemselection in specra tabview changed:" << std::endl; + if (current == nullptr) { return; } @@ -195,6 +203,7 @@ namespace OpenMS IndexExtrator ie(current); if (!ie.hasChromIndices()) { + std::cout << "Spectrum selected from Spec View Table: " << ie.spectrum_index << std::endl; emit spectrumSelected(ie.spectrum_index); } else @@ -208,7 +217,7 @@ namespace OpenMS spectrumSearchText_(); // update selection first (we might be in a new layer) QList selected = spectra_treewidget_->selectedItems(); // show the first selected item - if (selected.size() > 0) itemSelectionChange_(selected.first(), selected.first()); + if (!selected.empty()) itemSelectionChange_(selected.first(), selected.first()); } void SpectraTreeTab::itemDoubleClicked_(QTreeWidgetItem* current) @@ -296,11 +305,13 @@ namespace OpenMS void SpectraTreeTab::updateEntries(LayerData* layer) { + std::cout << "Updating spectrum table view entries" << std::endl; if (layer == nullptr) { clear(); return; } + layer_ = layer; if (!spectra_treewidget_->isVisible() || spectra_treewidget_->signalsBlocked()) { @@ -309,7 +320,9 @@ namespace OpenMS LayerData& cl = *layer; spectra_treewidget_->blockSignals(true); - RAIICleanup clean([&](){ spectra_treewidget_->blockSignals(false); }); + RAIICleanup clean([&](){ + std::cout << "signals in spectra table unblocked" << std::endl; + spectra_treewidget_->blockSignals(false); }); QTreeWidgetItem* toplevel_item = nullptr; QTreeWidgetItem* selected_item = nullptr; @@ -423,6 +436,7 @@ namespace OpenMS { // now, select and scroll down to item selected_item->setSelected(true); + spectra_treewidget_->setCurrentItem(selected_item); spectra_treewidget_->scrollToItem(selected_item); } if (cl.getPeakData()->size() > 1) diff --git a/src/openms_gui/source/VISUAL/TVIdentificationViewController.cpp b/src/openms_gui/source/VISUAL/TVIdentificationViewController.cpp index 2caf3a24e8a..9aa7da6cf62 100644 --- a/src/openms_gui/source/VISUAL/TVIdentificationViewController.cpp +++ b/src/openms_gui/source/VISUAL/TVIdentificationViewController.cpp @@ -85,6 +85,7 @@ namespace OpenMS if (layer.type == LayerData::DT_PEAK) { + std::cout << "PeakType" << std::endl; // open new 1D widget with the current default parameters Plot1DWidget* w = new Plot1DWidget(tv_->getSpectrumParameters(1), (QWidget*)tv_->getWorkspace()); @@ -97,6 +98,7 @@ namespace OpenMS w->canvas()->activateSpectrum(spectrum_index); + std::cout << "Spectrum activated" << std::endl; // set relative (%) view of visible area w->canvas()->setIntensityMode(PlotCanvas::IM_SNAP); @@ -1288,7 +1290,11 @@ namespace OpenMS void TVIdentificationViewController::activateBehavior() { Plot1DWidget* w = tv_->getActive1DWidget(); - if (w == nullptr) return; + if (w == nullptr) + { + std::cout << "No active 1D widget" << std::endl; + return; + } PlotCanvas* current_canvas = w->canvas(); LayerData& current_layer = current_canvas->getCurrentLayer(); @@ -1311,6 +1317,7 @@ namespace OpenMS break; } } + } // override diff --git a/src/openms_gui/source/VISUAL/TVSpectraViewController.cpp b/src/openms_gui/source/VISUAL/TVSpectraViewController.cpp index 3b12850a266..a0b1bd47315 100644 --- a/src/openms_gui/source/VISUAL/TVSpectraViewController.cpp +++ b/src/openms_gui/source/VISUAL/TVSpectraViewController.cpp @@ -188,6 +188,7 @@ namespace OpenMS // new spectrum. if (!layer.chromatogram_flag_set()) { + std::cout << "Activating spectrum1D from TVspectraViewController:" << index << std::endl; widget_1d->canvas()->activateSpectrum(index); } else From 3128c8fb9edf74334803d7de1c0262d662ae702a Mon Sep 17 00:00:00 2001 From: Julianus Pfeuffer Date: Thu, 12 Aug 2021 17:47:58 +0200 Subject: [PATCH 2/6] Remove unnecessary sequence lookup --- .../source/VISUAL/SpectraIDViewTab.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp index d098e834645..8afdcd14cb3 100644 --- a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp +++ b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp @@ -378,24 +378,10 @@ namespace OpenMS //protein const vector& prot_id = (*layer_->getPeakData()).getProteinIdentifications(); const vector& protein_hits = prot_id[current_identification_index].getHits(); - QString pro_sequence; - - for (const auto & protein_hit : protein_hits) - { - - const String& protein_accession = protein_hit.getAccession(); - const String& protein_sequence = protein_hit.getSequence(); - - if (protein_accession.toQString() == current_accession) - { - pro_sequence = protein_sequence.toQString(); - break; - } - } auto* widget = new SequenceVisualizer(); // no parent since we want a new window widget->resize(1500,500); // make a bit bigger - widget->setProteinPeptideDataToJsonObj(accession_num, pro_sequence, peptides_data, peptides_mod_data); + widget->setProteinPeptideDataToJsonObj(accession_num, sequence, peptides_data, peptides_mod_data); widget->show(); } } From f44b105f8225e08827654cbf1d8a8f5e628e3711 Mon Sep 17 00:00:00 2001 From: Julianus Pfeuffer Date: Thu, 12 Aug 2021 18:24:31 +0200 Subject: [PATCH 3/6] more cleanup --- .../OpenMS/VISUAL/SequenceVisualizer.h | 45 +++++++++++++++--- .../include/OpenMS/VISUAL/SpectraIDViewTab.h | 4 +- .../source/VISUAL/SequenceVisualizer.cpp | 47 +++++++++++++++---- .../source/VISUAL/SpectraIDViewTab.cpp | 6 ++- 4 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/openms_gui/include/OpenMS/VISUAL/SequenceVisualizer.h b/src/openms_gui/include/OpenMS/VISUAL/SequenceVisualizer.h index c9dcacaf8cd..5ab78bfa938 100644 --- a/src/openms_gui/include/OpenMS/VISUAL/SequenceVisualizer.h +++ b/src/openms_gui/include/OpenMS/VISUAL/SequenceVisualizer.h @@ -1,3 +1,38 @@ +// -------------------------------------------------------------------------- +// OpenMS -- Open-Source Mass Spectrometry +// -------------------------------------------------------------------------- +// Copyright The OpenMS Team -- Eberhard Karls University Tuebingen, +// ETH Zurich, and Freie Universitaet Berlin 2002-2021. +// +// This software is released under a three-clause BSD license: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of any author or any participating institution +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// For a full list of authors, refer to the file AUTHORS. +// -------------------------------------------------------------------------- +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING +// INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// -------------------------------------------------------------------------- +// $Maintainer: Julianus Pfeuffer $ +// $Authors: Dhanmoni Nath, Julianus Pfeuffer $ +// -------------------------------------------------------------------------- + +#ifdef QT_WEBENGINEWIDGETS_LIB #pragma once // OpenMS_GUI config @@ -6,9 +41,6 @@ #include #include -#include -#include - namespace Ui { class SequenceVisualizer; @@ -23,8 +55,8 @@ namespace OpenMS Q_PROPERTY(QJsonObject json_data_obj MEMBER m_json_data_obj) public: - SequenceVisualizer(QWidget* parent = nullptr); - ~SequenceVisualizer(); + explicit SequenceVisualizer(QWidget* parent = nullptr); + ~SequenceVisualizer() override; public slots: @@ -34,4 +66,5 @@ namespace OpenMS Ui::SequenceVisualizer* ui; QJsonObject m_json_data_obj; }; -}// namespace OpenMS \ No newline at end of file +}// namespace OpenMS +#endif \ No newline at end of file diff --git a/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h b/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h index 42b0bd4139d..86b98449f74 100644 --- a/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h +++ b/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h @@ -100,9 +100,9 @@ namespace OpenMS /// partially fill the bottom-most row void fillRow_(const MSSpectrum& spectrum, const int spec_index, const QColor background_color); // extract the required part of the accession - QString extractNumFromAccession_(QString listItem); + QString extractNumFromAccession_(conts QString& listItem); //open browser to navigate to uniport site with accession - void openUniProtSiteWithAccession_(QString accession); + void openUniProtSiteWithAccession_(const QString& accession); LayerData* layer_ = nullptr; QCheckBox* hide_no_identification_ = nullptr; diff --git a/src/openms_gui/source/VISUAL/SequenceVisualizer.cpp b/src/openms_gui/source/VISUAL/SequenceVisualizer.cpp index e2ef81b4fe5..c878f9c9aa5 100644 --- a/src/openms_gui/source/VISUAL/SequenceVisualizer.cpp +++ b/src/openms_gui/source/VISUAL/SequenceVisualizer.cpp @@ -1,12 +1,42 @@ +// -------------------------------------------------------------------------- +// OpenMS -- Open-Source Mass Spectrometry +// -------------------------------------------------------------------------- +// Copyright The OpenMS Team -- Eberhard Karls University Tuebingen, +// ETH Zurich, and Freie Universitaet Berlin 2002-2021. +// +// This software is released under a three-clause BSD license: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of any author or any participating institution +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// For a full list of authors, refer to the file AUTHORS. +// -------------------------------------------------------------------------- +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING +// INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// -------------------------------------------------------------------------- +// $Maintainer: Julianus Pfeuffer $ +// $Authors: Dhanmoni Nath, Julianus Pfeuffer $ +// -------------------------------------------------------------------------- + +#ifdef QT_WEBENGINEWIDGETS_LIB #include #include -#include -#include #include -#include -#include -#include #include #include @@ -18,8 +48,8 @@ namespace OpenMS QWidget(parent), ui(new Ui::SequenceVisualizer) { ui->setupUi(this); - QWebEngineView* view = new QWebEngineView(parent); - QWebChannel* channel = new QWebChannel(this); + auto* view = new QWebEngineView(parent); + auto* channel = new QWebChannel(this); view->page()->setWebChannel(channel); channel->registerObject(QString("SequenceVisualizer"), this); view->load(QUrl("qrc:/new/sequence_viz.html")); @@ -41,4 +71,5 @@ namespace OpenMS m_json_data_obj["peptides_data"] = pep_data; m_json_data_obj["peptides_mod_data"] = pep_mod_data; } -}// namespace OpenMS \ No newline at end of file +}// namespace OpenMS +#endif \ No newline at end of file diff --git a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp index 8afdcd14cb3..86e150b5616 100644 --- a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp +++ b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp @@ -221,7 +221,7 @@ namespace OpenMS } //extract required part of accession and open browser - QString SpectraIDViewTab::extractNumFromAccession_(QString full_accession) + QString SpectraIDViewTab::extractNumFromAccession_(const QString& full_accession) { //regex for matching accession QRegExp reg_pre_accession("(tr|sp)"); @@ -255,7 +255,7 @@ namespace OpenMS } } - void SpectraIDViewTab::openUniProtSiteWithAccession_(QString accession) + void SpectraIDViewTab::openUniProtSiteWithAccession_(const QString& accession) { QString accession_num = extractNumFromAccession_(accession); if (!accession_num.isEmpty()) { @@ -291,6 +291,7 @@ namespace OpenMS } //Open window + #ifdef QT_WEBENGINEWIDGETS_LIB if (column == ProteinClmn::SEQUENCE) { // store the current sequence clicked @@ -385,6 +386,7 @@ namespace OpenMS widget->show(); } } + #endif } void SpectraIDViewTab::currentSpectraSelectionChanged_() From 26114c6714225d9aa3f850dc3b7d19c2bb56e893 Mon Sep 17 00:00:00 2001 From: Julianus Pfeuffer Date: Thu, 12 Aug 2021 18:34:41 +0200 Subject: [PATCH 4/6] more cleanup --- .../include/OpenMS/VISUAL/SpectraIDViewTab.h | 4 ++-- .../source/VISUAL/SpectraIDViewTab.cpp | 19 ++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h b/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h index 86b98449f74..28cbb8a79d4 100644 --- a/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h +++ b/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h @@ -98,9 +98,9 @@ namespace OpenMS private: /// partially fill the bottom-most row - void fillRow_(const MSSpectrum& spectrum, const int spec_index, const QColor background_color); + void fillRow_(const MSSpectrum& spectrum, const int spec_index, const QColor& background_color); // extract the required part of the accession - QString extractNumFromAccession_(conts QString& listItem); + QString extractNumFromAccession_(const QString& listItem); //open browser to navigate to uniport site with accession void openUniProtSiteWithAccession_(const QString& accession); diff --git a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp index 86e150b5616..f05aa486186 100644 --- a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp +++ b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp @@ -195,21 +195,18 @@ namespace OpenMS { const vector& peptide_ids = spec.getPeptideIdentifications(); - for (int i = 0; i < peptide_ids.size(); ++i) + for (const auto& pepid : peptide_ids) { - const vector& pep_hits = peptide_ids[i].getHits(); - const PeptideHit& hit = pep_hits[i]; - const String& pep_seq = hit.getSequence().toString(); - + const vector& pep_hits = pepid.getHits(); //add id_accession as the key of the map and push the peptideID to the vector value- - for (int j = 0; j < pep_hits.size(); ++j) + for (const auto & pep_hit : pep_hits) { - const vector& evidences = pep_hits[j].getPeptideEvidences(); + const vector& evidences = pep_hit.getPeptideEvidences(); - for (int k = 0; k < evidences.size(); ++k) + for (const auto & evidence : evidences) { - const String& id_accession = evidences[k].getProteinAccession(); - protein_to_peptide_id_map[id_accession].push_back(peptide_ids[0]); + const String& id_accession = evidence.getProteinAccession(); + protein_to_peptide_id_map[id_accession].push_back(&pepid); } } } @@ -1021,7 +1018,7 @@ namespace OpenMS } } - void SpectraIDViewTab::fillRow_(const MSSpectrum& spectrum, const int spec_index, const QColor background_color) + void SpectraIDViewTab::fillRow_(const MSSpectrum& spectrum, const int spec_index, const QColor& background_color) { const vector& precursors = spectrum.getPrecursors(); From 6999ce98ae937e4d4a758577a24b3e4c4ece9980 Mon Sep 17 00:00:00 2001 From: Julianus Pfeuffer Date: Thu, 12 Aug 2021 18:41:37 +0200 Subject: [PATCH 5/6] some fixes in the traversal orders. --- .../include/OpenMS/VISUAL/SpectraIDViewTab.h | 5 +- .../source/VISUAL/SpectraIDViewTab.cpp | 59 +++++++++---------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h b/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h index 28cbb8a79d4..b36bd73e22a 100644 --- a/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h +++ b/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h @@ -110,11 +110,8 @@ namespace OpenMS TableView* table_widget_ = nullptr; TableView* protein_table_widget_ = nullptr; QTableWidget* fragment_window_ = nullptr; - QWidget* protein_window_ = nullptr; - QWidget* accession_window_ = nullptr; - bool is_ms1_shown_ = false; bool is_first_time_loading = true; - std::unordered_map> protein_to_peptide_id_map; + std::unordered_map> protein_to_peptide_id_map; private slots: /// Saves the (potentially filtered) IDs as an idXML or mzIdentML file void saveIDs_(); diff --git a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp index f05aa486186..4e037cfd51c 100644 --- a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp +++ b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp @@ -309,45 +309,18 @@ namespace OpenMS QJsonArray peptides_mod_data; //use data from the protein_to_peptide_id_map map and store the start/end position to the QJsonArray - for (auto pep : protein_to_peptide_id_map[current_accession]) + for (auto pep_id_ptr : protein_to_peptide_id_map[current_accession]) { - const vector& pep_hits = pep.getHits(); - const PeptideHit& hit = pep_hits[0]; - const AASequence& aaseq = hit.getSequence(); + const vector& pep_hits = pep_id_ptr->getHits(); - // contains the keys - mod_data, pep_start and seq and corresponding values - QJsonObject peptides_mod_obj; - // contains key-value of modName and vector of indices - QJsonObject mod_data; - - for (int i = 0; i < aaseq.size(); ++i) - { - if (aaseq[i].isModified()) - { - const String& mod_name = aaseq[i].getModificationName(); - - if (!mod_data.contains(mod_name.toQString())) - { - mod_data[mod_name.toQString()] = QJsonArray{i}; - } - else - { - QJsonArray values = mod_data.value(mod_name.toQString()).toArray(); - values.push_back(i); - mod_data[mod_name.toQString()] = values; - } - } - } - - peptides_mod_obj["mod_data"] = mod_data; - - const auto qstrseq = aaseq.toString().toQString(); //store start and end positions //TODO maybe we could store the index of the hit that belongs to that specific protein in the map as well // or we generally should only look at the first hit for (const auto & pep_hit : pep_hits) { const vector& evidences = pep_hit.getPeptideEvidences(); + const AASequence& aaseq = pep_hit.getSequence(); + const auto qstrseq = aaseq.toString().toQString(); for (const auto & evidence : evidences) { @@ -357,6 +330,30 @@ namespace OpenMS int pep_end = evidence.getEnd(); if (id_accession.toQString() == current_accession) { + // contains the keys - mod_data, pep_start and seq and corresponding values + QJsonObject peptides_mod_obj; + // contains key-value of modName and vector of indices + QJsonObject mod_data; + + for (int i = 0; i < aaseq.size(); ++i) + { + if (aaseq[i].isModified()) + { + const String& mod_name = aaseq[i].getModificationName(); + + if (!mod_data.contains(mod_name.toQString())) + { + mod_data[mod_name.toQString()] = QJsonArray{i}; + } + else + { + QJsonArray values = mod_data.value(mod_name.toQString()).toArray(); + values.push_back(i); + mod_data[mod_name.toQString()] = values; + } + } + } + peptides_mod_obj["mod_data"] = mod_data; data["start"] = pep_start; data["end"] = pep_end; data["seq"] = qstrseq; From a0660192c73f1970d6164bb6c5502ddfb9e7a5ff Mon Sep 17 00:00:00 2001 From: Julianus Pfeuffer Date: Thu, 12 Aug 2021 19:28:34 +0200 Subject: [PATCH 6/6] trying to fix protein sequence problem. left todos --- .../include/OpenMS/VISUAL/SpectraIDViewTab.h | 4 ++-- src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h b/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h index b36bd73e22a..7e83cde47b5 100644 --- a/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h +++ b/src/openms_gui/include/OpenMS/VISUAL/SpectraIDViewTab.h @@ -100,7 +100,7 @@ namespace OpenMS /// partially fill the bottom-most row void fillRow_(const MSSpectrum& spectrum, const int spec_index, const QColor& background_color); // extract the required part of the accession - QString extractNumFromAccession_(const QString& listItem); + static static QString extractNumFromAccession_(const QString& listItem); //open browser to navigate to uniport site with accession void openUniProtSiteWithAccession_(const QString& accession); @@ -111,7 +111,7 @@ namespace OpenMS TableView* protein_table_widget_ = nullptr; QTableWidget* fragment_window_ = nullptr; bool is_first_time_loading = true; - std::unordered_map> protein_to_peptide_id_map; + std::unordered_map> protein_to_peptide_id_map; private slots: /// Saves the (potentially filtered) IDs as an idXML or mzIdentML file void saveIDs_(); diff --git a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp index 4e037cfd51c..8a06d68066e 100644 --- a/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp +++ b/src/openms_gui/source/VISUAL/SpectraIDViewTab.cpp @@ -292,9 +292,12 @@ namespace OpenMS if (column == ProteinClmn::SEQUENCE) { // store the current sequence clicked - QString sequence = table_widget_->item(row, Clmn::SEQUENCE)->data(Qt::DisplayRole).toString(); + //TODO this will always set the protein sequence to "show" since that is what we put in the column + // a) store a pointer to the ProteinHit in the protein_to_peptide_id_map (value = pair) + // b) store a hidden column with the full sequence in the protein_table_widget. + QString protein_sequence = protein_table_widget_->item(row, ProteinClmn::SEQUENCE)->data(Qt::DisplayRole).toString(); // return whole accession as string, eg: tr|P02769|ALBU_BOVIN - QString current_accession = table_widget_->item(row, Clmn::ACCESSIONS)->data(Qt::DisplayRole).toString(); + QString current_accession = protein_table_widget_->item(row, ProteinClmn::ACCESSION)->data(Qt::DisplayRole).toString(); QString accession_num = extractNumFromAccession_(current_accession); auto item_pepid = table_widget_->item(row, Clmn::ID_NR); @@ -364,10 +367,10 @@ namespace OpenMS peptides_mod_obj["seq"] = qstrseq; peptides_data.push_back(data); + peptides_mod_data.push_back(peptides_mod_obj); } } } - peptides_mod_data.push_back(peptides_mod_obj); } //protein @@ -376,7 +379,7 @@ namespace OpenMS auto* widget = new SequenceVisualizer(); // no parent since we want a new window widget->resize(1500,500); // make a bit bigger - widget->setProteinPeptideDataToJsonObj(accession_num, sequence, peptides_data, peptides_mod_data); + widget->setProteinPeptideDataToJsonObj(accession_num, protein_sequence, peptides_data, peptides_mod_data); widget->show(); } }