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 "FilterAnnotationsByQualifierWorker.h"
23
24 #include <U2Core/AnnotationTableObject.h>
25 #include <U2Core/TaskSignalMapper.h>
26
27 #include <U2Designer/DelegateEditors.h>
28
29 #include <U2Gui/DialogUtils.h>
30
31 #include <U2Lang/ActorPrototypeRegistry.h>
32 #include <U2Lang/BaseActorCategories.h>
33 #include <U2Lang/BasePorts.h>
34 #include <U2Lang/BaseSlots.h>
35 #include <U2Lang/BaseTypes.h>
36 #include <U2Lang/ConfigurationEditor.h>
37 #include <U2Lang/CoreLibConstants.h>
38 #include <U2Lang/WorkflowEnv.h>
39
40 namespace U2 {
41 namespace LocalWorkflow {
42
43 const QString FilterAnnotationsByQualifierWorkerFactory::ACTOR_ID("filter-annotations-by-qualifier");
44
45 const static QString QUALIFER_NAME_ATTR("qualifier-name");
46 const static QString QUALIFER_VALUE_ATTR("qualifier-value");
47 const static QString WHICH_FILTER_ATTR("accept-or-filter");
48
composeRichDoc()49 QString FilterAnnotationsByQualifierPrompter::composeRichDoc() {
50 QString unsetStr = "<font color='red'>" + tr("unset") + "</font>";
51 QString annName = getProducers(BasePorts::IN_ANNOTATIONS_PORT_ID(), BaseSlots::ANNOTATION_TABLE_SLOT().getId());
52 annName = annName.isEmpty() ? unsetStr : annName;
53 return tr("Filter annotations from <u>%1</u> by given qualifier name and value.").arg(annName);
54 }
55
init()56 void FilterAnnotationsByQualifierWorker::init() {
57 input = ports.value(BasePorts::IN_ANNOTATIONS_PORT_ID());
58 output = ports.value(BasePorts::OUT_ANNOTATIONS_PORT_ID());
59 }
60
tick()61 Task *FilterAnnotationsByQualifierWorker::tick() {
62 if (input->hasMessage()) {
63 Message inputMessage = getMessageAndSetupScriptValues(input);
64 if (inputMessage.isEmpty()) {
65 output->transit();
66 return nullptr;
67 }
68
69 QVariantMap qm = inputMessage.getData().toMap();
70 const QVariant annsVar = qm[BaseSlots::ANNOTATION_TABLE_SLOT().getId()];
71 inputAnns = StorageUtils::getAnnotationTable(context->getDataStorage(), annsVar);
72
73 bool accept = actor->getParameter(WHICH_FILTER_ATTR)->getAttributeValue<bool>(context);
74 QString qualName = actor->getParameter(QUALIFER_NAME_ATTR)->getAttributeValue<QString>(context);
75 QString qualValue = actor->getParameter(QUALIFER_VALUE_ATTR)->getAttributeValue<QString>(context);
76
77 Task *t = new FilterAnnotationsByQualifierTask(inputAnns, qualName, qualValue, accept);
78 connect(new TaskSignalMapper(t), SIGNAL(si_taskFinished(Task *)), SLOT(sl_taskFinished(Task *)));
79 return t;
80 } else if (input->isEnded()) {
81 setDone();
82 output->setEnded();
83 }
84 return nullptr;
85 }
86
sl_taskFinished(Task * t)87 void FilterAnnotationsByQualifierWorker::sl_taskFinished(Task *t) {
88 if (t->isCanceled() || t->hasError()) {
89 return;
90 }
91 const SharedDbiDataHandler tableId = context->getDataStorage()->putAnnotationTable(inputAnns);
92 output->put(Message(BaseTypes::ANNOTATION_TABLE_TYPE(),
93 qVariantFromValue<SharedDbiDataHandler>(tableId)));
94 }
95
cleanup()96 void FilterAnnotationsByQualifierWorker::cleanup() {
97 }
98
init()99 void FilterAnnotationsByQualifierWorkerFactory::init() {
100 QList<PortDescriptor *> portDescs;
101 QList<Attribute *> attribs;
102
103 // accept sequence and annotated regions as input
104 QMap<Descriptor, DataTypePtr> inputMap;
105 inputMap[BaseSlots::ANNOTATION_TABLE_SLOT()] = BaseTypes::ANNOTATION_TABLE_TYPE();
106
107 { // Create input port descriptors
108 Descriptor inDesc(BasePorts::IN_ANNOTATIONS_PORT_ID(), FilterAnnotationsByQualifierWorker::tr("Input annotations"), FilterAnnotationsByQualifierWorker::tr("Annotations to be filtered by name."));
109 Descriptor outDesc(BasePorts::OUT_ANNOTATIONS_PORT_ID(), FilterAnnotationsByQualifierWorker::tr("Result annotations"), FilterAnnotationsByQualifierWorker::tr("Resulted annotations, filtered by name."));
110
111 portDescs << new PortDescriptor(inDesc, DataTypePtr(new MapDataType("filter.anns", inputMap)), /*input*/ true);
112 portDescs << new PortDescriptor(outDesc, DataTypePtr(new MapDataType("filter.anns", inputMap)), /*input*/ false, /*multi*/ true);
113 }
114
115 { // Create attributes descriptors
116 Descriptor qualifierNameDesc(QUALIFER_NAME_ATTR,
117 FilterAnnotationsByQualifierWorker::tr("Qualifier name"),
118 FilterAnnotationsByQualifierWorker::tr("Name of the qualifier to use for filtering."));
119 Descriptor qualifierValDesc(QUALIFER_VALUE_ATTR,
120 FilterAnnotationsByQualifierWorker::tr("Qualifier value"),
121 FilterAnnotationsByQualifierWorker::tr("Text value of the qualifier to apply as filtering criteria"));
122 Descriptor whichFilterDesc(WHICH_FILTER_ATTR,
123 FilterAnnotationsByQualifierWorker::tr("Accept or filter"),
124 FilterAnnotationsByQualifierWorker::tr("Selects the name filter: accept specified names or accept all except specified."));
125
126 attribs << new Attribute(qualifierNameDesc, BaseTypes::STRING_TYPE(), /*required*/ true);
127 attribs << new Attribute(qualifierValDesc, BaseTypes::STRING_TYPE(), /*required*/ true);
128 attribs << new Attribute(whichFilterDesc, BaseTypes::BOOL_TYPE(), /*required*/ false, QVariant(true));
129 }
130
131 Descriptor desc(FilterAnnotationsByQualifierWorkerFactory::ACTOR_ID,
132 FilterAnnotationsByQualifierWorker::tr("Filter Annotations by Qualifier"),
133 FilterAnnotationsByQualifierWorker::tr("Filters annotations by Qualifier."));
134 ActorPrototype *proto = new IntegralBusActorPrototype(desc, portDescs, attribs);
135
136 proto->setPrompter(new FilterAnnotationsByQualifierPrompter());
137
138 WorkflowEnv::getProtoRegistry()->registerProto(BaseActorCategories::CATEGORY_BASIC(), proto);
139 DomainFactory *localDomain = WorkflowEnv::getDomainRegistry()->getById(LocalDomainFactory::ID);
140 localDomain->registerEntry(new FilterAnnotationsByQualifierWorkerFactory());
141 }
142
run()143 void FilterAnnotationsByQualifierTask::run() {
144 // TODO: add reg exp option and tests!
145
146 QMutableListIterator<SharedAnnotationData> i(anns);
147
148 while (i.hasNext()) {
149 SharedAnnotationData &ad = i.next();
150 QVector<U2Qualifier> quals;
151 ad->findQualifiers(qualName, quals);
152
153 bool matchFound = false;
154 foreach (const U2Qualifier &qual, quals) {
155 if (qual.value == qualFilterVal) {
156 matchFound = true;
157 break;
158 }
159 }
160
161 if (accept) {
162 if (!matchFound) {
163 i.remove();
164 }
165 } else {
166 if (matchFound) {
167 i.remove();
168 }
169 }
170 }
171 }
172
173 } // namespace LocalWorkflow
174 } // namespace U2
175