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 "CodonOccurTask.h"
23 
24 #include <U2Core/Annotation.h>
25 #include <U2Core/DNAAlphabet.h>
26 #include <U2Core/U2DbiUtils.h>
27 #include <U2Core/U2Region.h>
28 
29 namespace U2 {
30 
CodonOccurTask(DNATranslation * complementTranslation,const U2EntityRef & seqRef)31 CodonOccurTask::CodonOccurTask(DNATranslation *complementTranslation, const U2EntityRef &seqRef)
32     : BackgroundTask<QMap<QByteArray, qint64>>(tr("Count codons"), TaskFlag_NoRun) {
33     SequenceDbiWalkerConfig config;
34     config.seqRef = seqRef;
35     config.complTrans = complementTranslation;
36     config.strandToWalk = StrandOption_Both;
37     config.chunkSize = 10 * 1000 * 1000;  // Use maximum 6*10mb RAM.
38     // Run only 1 subtask at a time: the code in onRegion() is not thread-safe: updates global QHash state.
39     config.nThreads = 1;
40     addSubTask(new SequenceDbiWalkerTask(config, this, tr("Count all codons in sequence")));
41 }
42 
CodonOccurTask(DNATranslation * complementTranslation,const U2EntityRef & seqRef,const QVector<U2Region> & regions)43 CodonOccurTask::CodonOccurTask(DNATranslation *complementTranslation, const U2EntityRef &seqRef, const QVector<U2Region> &regions)
44     : BackgroundTask<QMap<QByteArray, qint64>>(tr("Count codons"), TaskFlag_NoRun) {
45     SequenceDbiWalkerConfig config;
46     config.seqRef = seqRef;
47     config.complTrans = complementTranslation;
48     config.strandToWalk = StrandOption_Both;
49     config.chunkSize = 10 * 1000 * 1000;  // Use maximum 6*10mb RAM.
50     config.translateOnlyFirstFrame = true;
51     // Run only 1 subtask at a time: the code in onRegion() is not thread-safe: updates global QHash state.
52     config.nThreads = 1;
53     for (const U2Region &region : qAsConst(regions)) {
54         config.range = region;
55         addSubTask(new SequenceDbiWalkerTask(config, this, tr("Count codons in sequence region")));
56     }
57 }
58 
CodonOccurTask(DNATranslation * complementTranslation,const U2EntityRef & seqRef,const QList<Annotation * > & annotations)59 CodonOccurTask::CodonOccurTask(DNATranslation *complementTranslation, const U2EntityRef &seqRef, const QList<Annotation *> &annotations)
60     : BackgroundTask<QMap<QByteArray, qint64>>(tr("Count codons"), TaskFlag_NoRun) {
61     SequenceDbiWalkerConfig config;
62     config.seqRef = seqRef;
63     config.complTrans = complementTranslation;
64     config.chunkSize = 10 * 1000 * 1000;  // Use maximum 6*10mb RAM.
65     config.translateOnlyFirstFrame = true;
66     // Run only 1 subtask at a time: the code in onRegion() is not thread-safe: updates global QHash state.
67     config.nThreads = 1;
68     for (const Annotation *annotation : qAsConst(annotations)) {
69         U2Location location = annotation->getLocation();
70         config.strandToWalk = location->strand.isDirect() ? StrandOption_DirectOnly : StrandOption_ComplementOnly;
71         for (const U2Region &region : qAsConst(location->regions)) {
72             config.range = region;
73             addSubTask(new SequenceDbiWalkerTask(config, this, tr("Count codons in annotated region")));
74         }
75     }
76 }
77 
onRegion(SequenceDbiWalkerSubtask * task,TaskStateInfo &)78 void CodonOccurTask::onRegion(SequenceDbiWalkerSubtask *task, TaskStateInfo &) {
79     const QByteArray &sequence = task->getRegionSequence();
80     const char *sequenceData = sequence.constData();
81     bool isFirstFrameOnly = task->getSequenceDbiWalkerTask()->getConfig().translateOnlyFirstFrame;
82     int step = isFirstFrameOnly ? 3 : 1;
83     for (int i = 0, n = sequence.length() - 2; i < n; i += step) {
84         QByteArray codon(sequenceData + i, 3);
85         countPerCodon[codon] = countPerCodon.value(codon, 0) + 1;
86     }
87 }
88 
report()89 Task::ReportResult CodonOccurTask::report() {
90     // Copy computation result to the main thread data.
91     result = countPerCodon;
92     return ReportResult_Finished;
93 }
94 
95 }  // namespace U2
96