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 "GenomeAlignerIndexWorker.h"
23
24 #include <U2Core/Log.h>
25
26 #include <U2Designer/DelegateEditors.h>
27
28 #include <U2Gui/DialogUtils.h>
29
30 #include <U2Lang/ActorPrototypeRegistry.h>
31 #include <U2Lang/BaseActorCategories.h>
32 #include <U2Lang/BaseAttributes.h>
33 #include <U2Lang/BasePorts.h>
34 #include <U2Lang/BaseSlots.h>
35 #include <U2Lang/BaseTypes.h>
36 #include <U2Lang/CoreLibConstants.h>
37 #include <U2Lang/IntegralBusModel.h>
38 #include <U2Lang/WorkflowEnv.h>
39
40 #include "GenomeAlignerPlugin.h"
41
42 namespace U2 {
43 namespace LocalWorkflow {
44
45 static const QString INDEX_PORT_ID("in-gen-al-index");
46 static const QString INDEX_OUT_PORT_ID("out-gen-al-index");
47 static const QString INDEX_SLOT("index-slot");
48
49 static const QString REFSEQ_URL_ATTR("url-reference");
50 static const QString INDEX_URL_ATTR("url-index");
51 static const QString REF_SIZE_ATTR("ref-size");
52
53 const QString GenomeAlignerBuildWorkerFactory::ACTOR_ID("gen-al-build-index");
54 const QString GenomeAlignerIndexReaderWorkerFactory::ACTOR_ID("gen-al-read-index");
55
56 /************************************************************************/
57 /* Genome aligner index build */
58 /************************************************************************/
init()59 void GenomeAlignerBuildWorkerFactory::init() {
60 QList<PortDescriptor *> p;
61 QList<Attribute *> a;
62 Descriptor oud(INDEX_OUT_PORT_ID, QString("Genome aligner index"), QString("Result genome aligner index of reference sequence."));
63
64 QMap<Descriptor, DataTypePtr> outM;
65 outM[INDEX_SLOT] = GenomeAlignerPlugin::GENOME_ALIGNER_INDEX_TYPE();
66 p << new PortDescriptor(oud, DataTypePtr(new MapDataType("gen.al.build.index.out", outM)), false /*input*/, true /*multi*/);
67
68 Descriptor refseq(REFSEQ_URL_ATTR, GenomeAlignerBuildWorker::tr("Reference"), GenomeAlignerBuildWorker::tr("Reference sequence url. The short reads will be aligned to this reference genome."));
69 Descriptor desc(ACTOR_ID, GenomeAlignerBuildWorker::tr("Genome aligner index builder"), GenomeAlignerBuildWorker::tr("GenomeAlignerBuild builds an index from a set of DNA sequences. GenomeAlignerBuild outputs a set of 3 files with suffixes .idx, .ref, .sarr. These files together constitute the index: they are all that is needed to align reads to that reference."));
70 Descriptor index(INDEX_URL_ATTR, GenomeAlignerBuildWorker::tr("Index"), GenomeAlignerBuildWorker::tr("Output index url."));
71 Descriptor refSize(REF_SIZE_ATTR, GenomeAlignerBuildWorker::tr("Reference fragmentation"), GenomeAlignerBuildWorker::tr("Reference fragmentation size"));
72
73 a << new Attribute(refseq, BaseTypes::STRING_TYPE(), true /*required*/, QString());
74 a << new Attribute(index, BaseTypes::STRING_TYPE(), true /*required*/, QString());
75 a << new Attribute(refSize, BaseTypes::NUM_TYPE(), true /*required*/, 10);
76
77 ActorPrototype *proto = new IntegralBusActorPrototype(desc, p, a);
78
79 QMap<QString, PropertyDelegate *> delegates;
80
81 delegates[REFSEQ_URL_ATTR] = new URLDelegate(DialogUtils::prepareDocumentsFileFilter(true), QString(), true);
82 delegates[INDEX_URL_ATTR] = new URLDelegate(DialogUtils::prepareDocumentsFileFilter(true), QString(), false);
83
84 proto->setEditor(new DelegateEditor(delegates));
85 proto->setPrompter(new GenomeAlignerBuildPrompter());
86 proto->setIconPath(":core/images/align.png");
87 WorkflowEnv::getProtoRegistry()->registerProto(BaseActorCategories::CATEGORY_ASSEMBLY(), proto);
88
89 DomainFactory *localDomain = WorkflowEnv::getDomainRegistry()->getById(LocalDomainFactory::ID);
90 localDomain->registerEntry(new GenomeAlignerBuildWorkerFactory());
91 }
92
init()93 void GenomeAlignerBuildWorker::init() {
94 output = ports.value(INDEX_OUT_PORT_ID);
95 refSeqUrl = actor->getParameter(REFSEQ_URL_ATTR)->getAttributeValue<QString>(context);
96 indexUrl = actor->getParameter(INDEX_URL_ATTR)->getAttributeValue<QString>(context);
97
98 settings.prebuiltIndex = false;
99 }
100
isReady() const101 bool GenomeAlignerBuildWorker::isReady() const {
102 return !isDone();
103 }
104
tick()105 Task *GenomeAlignerBuildWorker::tick() {
106 if (refSeqUrl.isEmpty()) {
107 algoLog.trace(GenomeAlignerBuildWorker::tr("Reference sequence URL is empty"));
108 return nullptr;
109 }
110 if (indexUrl.isEmpty()) {
111 algoLog.trace(GenomeAlignerBuildWorker::tr("Result index URL is empty"));
112 return nullptr;
113 }
114
115 settings.refSeqUrl = refSeqUrl;
116 settings.indexFileName = indexUrl.getURLString();
117 Task *t = new GenomeAlignerTask(settings, true);
118 connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished()));
119 return t;
120 }
121
sl_taskFinished()122 void GenomeAlignerBuildWorker::sl_taskFinished() {
123 GenomeAlignerTask *t = qobject_cast<GenomeAlignerTask *>(sender());
124 if (t->getState() != Task::State_Finished) {
125 return;
126 }
127
128 done = true;
129
130 QVariant v = qVariantFromValue<QString>(t->getIndexPath());
131 output->put(Message(GenomeAlignerPlugin::GENOME_ALIGNER_INDEX_TYPE(), v));
132 output->setEnded();
133 algoLog.trace(tr("Genome aligner index building finished. Result name is %1").arg(t->getIndexPath()));
134 }
135
isDone() const136 bool GenomeAlignerBuildWorker::isDone() const {
137 return done;
138 }
139
cleanup()140 void GenomeAlignerBuildWorker::cleanup() {
141 }
142
composeRichDoc()143 QString GenomeAlignerBuildPrompter::composeRichDoc() {
144 QString refSeqUrl = getParameter(REFSEQ_URL_ATTR).toString();
145 QString refSeq = (refSeqUrl.isEmpty() ? "" : QString("<u>%1</u>").arg(GUrl(refSeqUrl).fileName()));
146
147 QString doc = tr("Build genome aligner index from %1 and send it url to output.").arg(refSeq);
148
149 return doc;
150 }
151
152 /************************************************************************/
153 /* Genome aligner index read */
154 /************************************************************************/
init()155 void GenomeAlignerIndexReaderWorkerFactory::init() {
156 QList<PortDescriptor *> p;
157 QList<Attribute *> a;
158 Descriptor oud(INDEX_OUT_PORT_ID, GenomeAlignerIndexReaderWorker::tr("Genome aligner index"), GenomeAlignerIndexReaderWorker::tr("Result of genome aligner index builder."));
159
160 QMap<Descriptor, DataTypePtr> outM;
161 outM[INDEX_SLOT] = GenomeAlignerPlugin::GENOME_ALIGNER_INDEX_TYPE();
162 p << new PortDescriptor(oud, DataTypePtr(new MapDataType("gen.al.index.reader.out", outM)), false /*input*/, true /*multi*/);
163
164 Descriptor desc(ACTOR_ID, GenomeAlignerIndexReaderWorker::tr("Genome aligner index reader"), GenomeAlignerIndexReaderWorker::tr("Read a set of several files with extensions .idx, .ref, .X.sarr. These files together constitute the index: they are all that is needed to align reads to that reference."));
165 Descriptor index(INDEX_URL_ATTR, GenomeAlignerIndexReaderWorker::tr("Index"), GenomeAlignerIndexReaderWorker::tr("Select an index file with the .idx extension"));
166
167 a << new Attribute(index, BaseTypes::STRING_TYPE(), true /*required*/, QString());
168
169 ActorPrototype *proto = new IntegralBusActorPrototype(desc, p, a);
170
171 QMap<QString, PropertyDelegate *> delegates;
172
173 delegates[INDEX_URL_ATTR] = new URLDelegate(DialogUtils::prepareDocumentsFileFilter(true), QString(), false, false, false);
174
175 proto->setEditor(new DelegateEditor(delegates));
176 proto->setPrompter(new GenomeAlignerIndexReaderPrompter());
177 proto->setIconPath(":core/images/align.png");
178 WorkflowEnv::getProtoRegistry()->registerProto(BaseActorCategories::CATEGORY_ASSEMBLY(), proto);
179
180 DomainFactory *localDomain = WorkflowEnv::getDomainRegistry()->getById(LocalDomainFactory::ID);
181 localDomain->registerEntry(new GenomeAlignerIndexReaderWorkerFactory());
182 }
183
init()184 void GenomeAlignerIndexReaderWorker::init() {
185 output = ports.value(INDEX_OUT_PORT_ID);
186 indexUrl = actor->getParameter(INDEX_URL_ATTR)->getAttributeValue<QString>(context);
187 }
188
isReady() const189 bool GenomeAlignerIndexReaderWorker::isReady() const {
190 return !isDone();
191 }
192
tick()193 Task *GenomeAlignerIndexReaderWorker::tick() {
194 if (indexUrl.isEmpty()) {
195 algoLog.trace(GenomeAlignerIndexReaderWorker::tr("Index URL is empty"));
196 return nullptr;
197 }
198 Task *t = new Task("Genome aligner index reader", TaskFlags_NR_FOSCOE);
199 connect(t, SIGNAL(si_stateChanged()), SLOT(sl_taskFinished()));
200 return t;
201 }
202
sl_taskFinished()203 void GenomeAlignerIndexReaderWorker::sl_taskFinished() {
204 QVariant v = qVariantFromValue<QString>(indexUrl.getURLString());
205 output->put(Message(GenomeAlignerPlugin::GENOME_ALIGNER_INDEX_TYPE(), v));
206 output->setEnded();
207 done = true;
208 algoLog.trace(tr("Reading genome aligner index finished. Result name is %1").arg(indexUrl.getURLString()));
209 }
210
isDone() const211 bool GenomeAlignerIndexReaderWorker::isDone() const {
212 return done;
213 }
214
cleanup()215 void GenomeAlignerIndexReaderWorker::cleanup() {
216 }
217
composeRichDoc()218 QString GenomeAlignerIndexReaderPrompter::composeRichDoc() {
219 QString indexUrl = getParameter(INDEX_URL_ATTR).toString();
220 QString index = (indexUrl.isEmpty() ? "" : QString("<u>%1</u>").arg(GUrl(indexUrl).fileName()));
221
222 QString doc = tr("Read genome aligner index from %1 and send it url to output.").arg(index);
223
224 return doc;
225 }
226 } // namespace LocalWorkflow
227 } // namespace U2
228