1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #include "SlidingWindowStep.h"
23 
24 #include <U2Core/U2SafePoints.h>
25 
26 #include "trimmomatic/util/LineEditHighlighter.h"
27 
28 namespace U2 {
29 namespace LocalWorkflow {
30 
31 const QString SlidingWindowStepFactory::ID = "SLIDINGWINDOW";
32 
SlidingWindowStep()33 SlidingWindowStep::SlidingWindowStep()
34     : TrimmomaticStep(SlidingWindowStepFactory::ID) {
35     name = "SLIDINGWINDOW";
36     description = tr("<html><head></head><body>"
37                      "<h4>SLIDINGWINDOW</h4>"
38                      "<p>This step performs a sliding window trimming, cutting once the average "
39                      "quality within the window falls below a threshold. By considering multiple "
40                      "bases, a single poor quality base will not cause the removal of high quality "
41                      "data later in the read.</p>"
42                      "<p>Input the following values:</p>"
43                      "<ul>"
44                      "<li><b>Window size</b>: the number of bases to average across.</li>"
45                      "<li><b>Quality threshold</b>: the average quality required.</li>"
46                      "</ul>"
47                      "</body></html>");
48 }
49 
createWidget() const50 TrimmomaticStepSettingsWidget *SlidingWindowStep::createWidget() const {
51     return new SlidingWindowSettingsWidget();
52 }
53 
serializeState(const QVariantMap & widgetState) const54 QString SlidingWindowStep::serializeState(const QVariantMap &widgetState) const {
55     QString serializedState;
56     if (widgetState.contains(SlidingWindowSettingsWidget::WINDOW_SIZE)) {
57         serializedState += QString::number(widgetState.value(SlidingWindowSettingsWidget::WINDOW_SIZE).toInt());
58     }
59     serializedState += ":";
60     if (widgetState.contains(SlidingWindowSettingsWidget::REQUIRED_QUALITY)) {
61         serializedState += QString::number(widgetState.value(SlidingWindowSettingsWidget::REQUIRED_QUALITY).toInt());
62     }
63     return serializedState;
64 }
65 
parseState(const QString & command) const66 QVariantMap SlidingWindowStep::parseState(const QString &command) const {
67     QVariantMap state;
68     QRegExp regExp(id + ":" + "(\\d*)" + ":" + "(\\d*)");
69 
70     const bool matched = regExp.exactMatch(command);
71     CHECK(matched, state);
72 
73     const QString windowSize = regExp.cap(1);
74     if (!windowSize.isEmpty()) {
75         state[SlidingWindowSettingsWidget::WINDOW_SIZE] = windowSize.toInt();
76     }
77 
78     const QString requiredQuality = regExp.cap(2);
79     if (!requiredQuality.isEmpty()) {
80         state[SlidingWindowSettingsWidget::REQUIRED_QUALITY] = requiredQuality.toInt();
81     }
82 
83     return state;
84 }
85 
86 const QString SlidingWindowSettingsWidget::WINDOW_SIZE = "windowSize";
87 const QString SlidingWindowSettingsWidget::REQUIRED_QUALITY = "requiredQuality";
88 
SlidingWindowSettingsWidget()89 SlidingWindowSettingsWidget::SlidingWindowSettingsWidget() {
90     setupUi(this);
91 
92     leWindowSize->setValidator(new QIntValidator(1, std::numeric_limits<int>::max(), this));
93     new LineEditHighlighter(leWindowSize);
94 
95     connect(leWindowSize, SIGNAL(textChanged(QString)), SIGNAL(si_valueChanged()));
96     connect(sbQualityThreshold, SIGNAL(valueChanged(int)), SIGNAL(si_valueChanged()));
97 }
98 
~SlidingWindowSettingsWidget()99 SlidingWindowSettingsWidget::~SlidingWindowSettingsWidget() {
100     emit si_widgetIsAboutToBeDestroyed(getState());
101 }
102 
validate() const103 bool SlidingWindowSettingsWidget::validate() const {
104     return !leWindowSize->text().isEmpty();
105 }
106 
getState() const107 QVariantMap SlidingWindowSettingsWidget::getState() const {
108     QVariantMap state;
109 
110     const QString windowSizeString = leWindowSize->text();
111     const bool isEmpty = windowSizeString.isEmpty();
112     bool valid = false;
113     const int windowSize = windowSizeString.toInt(&valid);
114 
115     if (!isEmpty && valid) {
116         state[WINDOW_SIZE] = windowSize;
117     }
118     state[REQUIRED_QUALITY] = sbQualityThreshold->value();
119 
120     return state;
121 }
122 
setState(const QVariantMap & state)123 void SlidingWindowSettingsWidget::setState(const QVariantMap &state) {
124     bool contains = state.contains(WINDOW_SIZE);
125     bool valid = false;
126     const int windowSize = state.value(WINDOW_SIZE).toInt(&valid);
127     if (contains && valid) {
128         leWindowSize->setText(QString::number(windowSize));
129     }
130 
131     contains = state.contains(REQUIRED_QUALITY);
132     const int requiredQuality = state.value(REQUIRED_QUALITY).toInt(&valid);
133     if (contains && valid) {
134         sbQualityThreshold->setValue(requiredQuality);
135     }
136 }
137 
SlidingWindowStepFactory()138 SlidingWindowStepFactory::SlidingWindowStepFactory()
139     : TrimmomaticStepFactory(ID) {
140 }
141 
createStep() const142 SlidingWindowStep *SlidingWindowStepFactory::createStep() const {
143     return new SlidingWindowStep();
144 }
145 
146 }    // namespace LocalWorkflow
147 }    // namespace U2
148