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 "MultipleChromatogramAlignmentImporter.h"
23
24 #include <U2Core/ChromatogramUtils.h>
25 #include <U2Core/DNAAlphabet.h>
26 #include <U2Core/GObjectTypes.h>
27 #include <U2Core/L10n.h>
28 #include <U2Core/McaDbiUtils.h>
29 #include <U2Core/MultipleAlignmentInfo.h>
30 #include <U2Core/MultipleChromatogramAlignmentObject.h>
31 #include <U2Core/MultipleChromatogramAlignmentRow.h>
32 #include <U2Core/U2AttributeDbi.h>
33 #include <U2Core/U2MsaDbi.h>
34 #include <U2Core/U2ObjectDbi.h>
35 #include <U2Core/U2ObjectRelationsDbi.h>
36 #include <U2Core/U2OpStatus.h>
37 #include <U2Core/U2SafePoints.h>
38 #include <U2Core/U2SequenceDbi.h>
39 #include <U2Core/U2SequenceUtils.h>
40
41 #include "datatype/msa/MultipleAlignmentRowInfo.h"
42
43 namespace U2 {
44
createAlignment(U2OpStatus & os,const U2DbiRef & dbiRef,const QString & folder,MultipleChromatogramAlignment & mca)45 MultipleChromatogramAlignmentObject *MultipleChromatogramAlignmentImporter::createAlignment(U2OpStatus &os,
46 const U2DbiRef &dbiRef,
47 const QString &folder,
48 MultipleChromatogramAlignment &mca) {
49 DbiConnection connection(dbiRef, true, os);
50 CHECK(!os.isCanceled(), nullptr);
51 SAFE_POINT_OP(os, nullptr);
52 SAFE_POINT_EXT(nullptr != connection.dbi, os.setError(L10N::nullPointerError("Destination database")), nullptr);
53
54 TmpDbiObjects objs(dbiRef, os);
55
56 // MCA object and info
57 U2Mca dbMca = importMcaObject(os, connection, folder, mca);
58 objs.objects << dbMca.id;
59 CHECK_OP(os, nullptr);
60
61 importMcaInfo(os, connection, dbMca.id, mca);
62 CHECK_OP(os, nullptr);
63
64 // MCA rows
65 QList<McaRowDatabaseData> mcaRowsDatabaseData = importRowChildObjects(os, connection, folder, mca);
66 CHECK_OP(os, nullptr);
67
68 QList<U2McaRow> rows = importRows(os, connection, dbMca, mcaRowsDatabaseData);
69 CHECK_OP(os, nullptr);
70 SAFE_POINT_EXT(rows.size() == mca->getNumRows(), os.setError(QObject::tr("Unexpected error on MCA rows import")), nullptr);
71
72 for (int i = 0, n = mca->getNumRows(); i < n; ++i) {
73 mca->getMcaRow(i)->setRowDbInfo(rows.at(i));
74 }
75
76 return new MultipleChromatogramAlignmentObject(mca->getName(), U2EntityRef(dbiRef, dbMca.id), QVariantMap(), mca);
77 }
78
importMcaObject(U2OpStatus & os,const DbiConnection & connection,const QString & folder,const MultipleChromatogramAlignment & mca)79 U2Mca MultipleChromatogramAlignmentImporter::importMcaObject(U2OpStatus &os, const DbiConnection &connection, const QString &folder, const MultipleChromatogramAlignment &mca) {
80 U2Mca dbMca;
81 const DNAAlphabet *alphabet = mca->getAlphabet();
82 SAFE_POINT_EXT(nullptr != alphabet, os.setError("The alignment alphabet is NULL during importing"), U2Mca());
83
84 dbMca.alphabet.id = alphabet->getId();
85 dbMca.length = mca->getLength();
86 dbMca.visualName = mca->getName();
87 if (dbMca.visualName.isEmpty()) {
88 QDate date = QDate::currentDate();
89 QString generatedName = "MCA" + date.toString();
90 coreLog.trace(QString("A multiple alignment name was empty. Generated a new name %1").arg(generatedName));
91 dbMca.visualName = generatedName;
92 }
93
94 U2MsaDbi *msaDbi = connection.dbi->getMsaDbi();
95 SAFE_POINT_EXT(nullptr != msaDbi, os.setError("NULL MSA Dbi during importing an alignment"), U2Mca());
96
97 dbMca.id = msaDbi->createMcaObject(folder, dbMca.visualName, dbMca.alphabet, dbMca.length, os);
98 CHECK_OP(os, U2Mca());
99
100 return dbMca;
101 }
102
importMcaInfo(U2OpStatus & os,const DbiConnection & connection,const U2DataId & mcaId,const MultipleChromatogramAlignment & mca)103 void MultipleChromatogramAlignmentImporter::importMcaInfo(U2OpStatus &os, const DbiConnection &connection, const U2DataId &mcaId, const MultipleChromatogramAlignment &mca) {
104 const QVariantMap info = mca->getInfo();
105
106 U2AttributeDbi *attributeDbi = connection.dbi->getAttributeDbi();
107 SAFE_POINT_EXT(nullptr != attributeDbi, os.setError("NULL Attribute Dbi during importing an alignment"), );
108
109 foreach (const QString key, info.keys()) {
110 if (key != MultipleAlignmentInfo::NAME) { // name is stored in the object
111 const QString value = info.value(key).toString();
112 U2StringAttribute attribute(mcaId, key, value);
113 attributeDbi->createStringAttribute(attribute, os);
114 CHECK_OP(os, );
115 }
116 }
117 }
118
importRowChildObjects(U2OpStatus & os,const DbiConnection & connection,const QString & folder,const MultipleChromatogramAlignment & mca)119 QList<McaRowDatabaseData> MultipleChromatogramAlignmentImporter::importRowChildObjects(U2OpStatus &os,
120 const DbiConnection &connection,
121 const QString &folder,
122 const MultipleChromatogramAlignment &mca) {
123 QList<McaRowDatabaseData> mcaRowsDatabaseData;
124 UdrDbi *udrDbi = connection.dbi->getUdrDbi();
125 SAFE_POINT_EXT(nullptr != udrDbi, os.setError("NULL UDR Dbi during importing an alignment"), mcaRowsDatabaseData);
126 U2SequenceDbi *sequenceDbi = connection.dbi->getSequenceDbi();
127 SAFE_POINT_EXT(nullptr != sequenceDbi, os.setError("NULL Sequence Dbi during importing an alignment"), mcaRowsDatabaseData);
128
129 const DNAAlphabet *alphabet = mca->getAlphabet();
130 SAFE_POINT_EXT(nullptr != alphabet, os.setError("MCA alphabet is NULL"), mcaRowsDatabaseData);
131 const U2AlphabetId alphabetId = alphabet->getId();
132
133 foreach (const MultipleChromatogramAlignmentRow &row, mca->getMcaRows()) {
134 McaRowDatabaseData mcaRowDatabaseData;
135
136 mcaRowDatabaseData.chromatogram = importChromatogram(os, connection, folder, row->getChromatogram());
137 CHECK_OP(os, mcaRowsDatabaseData);
138
139 mcaRowDatabaseData.sequence = importSequence(os, connection, folder, row->getSequence(), alphabetId);
140 CHECK_OP(os, mcaRowsDatabaseData);
141
142 createRelation(os, connection, mcaRowDatabaseData.sequence, mcaRowDatabaseData.chromatogram.id);
143
144 mcaRowDatabaseData.additionalInfo = row->getAdditionalInfo();
145 importRowAdditionalInfo(os, connection, mcaRowDatabaseData.chromatogram, mcaRowDatabaseData.additionalInfo);
146 CHECK_OP(os, mcaRowsDatabaseData);
147
148 mcaRowDatabaseData.gapModel = row->getGapModel();
149 mcaRowDatabaseData.rowLength = row->getRowLengthWithoutTrailing();
150
151 mcaRowsDatabaseData << mcaRowDatabaseData;
152 }
153
154 return mcaRowsDatabaseData;
155 }
156
importRows(U2OpStatus & os,const DbiConnection & connection,U2Mca & dbMca,const QList<McaRowDatabaseData> & mcaRowsDatabaseData)157 QList<U2McaRow> MultipleChromatogramAlignmentImporter::importRows(U2OpStatus &os,
158 const DbiConnection &connection,
159 U2Mca &dbMca,
160 const QList<McaRowDatabaseData> &mcaRowsDatabaseData) {
161 QList<U2McaRow> rows;
162
163 foreach (const McaRowDatabaseData &mcaRowDatabaseData, mcaRowsDatabaseData) {
164 U2McaRow row;
165 row.chromatogramId = mcaRowDatabaseData.chromatogram.id;
166 row.sequenceId = mcaRowDatabaseData.sequence.id;
167 row.gaps = mcaRowDatabaseData.gapModel;
168 row.gstart = 0;
169 row.gend = mcaRowDatabaseData.sequence.length;
170 row.length = mcaRowDatabaseData.rowLength;
171
172 rows << row;
173 }
174
175 McaDbiUtils::addRows(os, U2EntityRef(connection.dbi->getDbiRef(), dbMca.id), rows);
176 CHECK_OP(os, QList<U2McaRow>());
177 return rows;
178 }
179
importChromatogram(U2OpStatus & os,const DbiConnection & connection,const QString & folder,const DNAChromatogram & chromatogram)180 U2Chromatogram MultipleChromatogramAlignmentImporter::importChromatogram(U2OpStatus &os,
181 const DbiConnection &connection,
182 const QString &folder,
183 const DNAChromatogram &chromatogram) {
184 const U2EntityRef chromatogramRef = ChromatogramUtils::import(os, connection.dbi->getDbiRef(), folder, chromatogram);
185 CHECK_OP(os, U2Chromatogram());
186 connection.dbi->getObjectDbi()->setObjectRank(chromatogramRef.entityId, U2DbiObjectRank_Child, os);
187 CHECK_OP(os, U2Chromatogram());
188 return ChromatogramUtils::getChromatogramDbInfo(os, chromatogramRef);
189 }
190
importSequence(U2OpStatus & os,const DbiConnection & connection,const QString & folder,const DNASequence & sequence,const U2AlphabetId & alphabetId)191 U2Sequence MultipleChromatogramAlignmentImporter::importSequence(U2OpStatus &os,
192 const DbiConnection &connection,
193 const QString &folder,
194 const DNASequence &sequence,
195 const U2AlphabetId &alphabetId) {
196 const U2EntityRef sequenceRef = U2SequenceUtils::import(os, connection.dbi->getDbiRef(), folder, sequence, alphabetId);
197 CHECK_OP(os, U2Sequence());
198 connection.dbi->getObjectDbi()->setObjectRank(sequenceRef.entityId, U2DbiObjectRank_Child, os);
199 CHECK_OP(os, U2Sequence());
200 return connection.dbi->getSequenceDbi()->getSequenceObject(sequenceRef.entityId, os);
201 }
202
importRowAdditionalInfo(U2OpStatus & os,const DbiConnection & connection,const U2Chromatogram & chromatogram,const QVariantMap & additionalInfo)203 void MultipleChromatogramAlignmentImporter::importRowAdditionalInfo(U2OpStatus &os, const DbiConnection &connection, const U2Chromatogram &chromatogram, const QVariantMap &additionalInfo) {
204 U2IntegerAttribute reversedAttribute;
205 reversedAttribute.objectId = chromatogram.id;
206 reversedAttribute.name = MultipleAlignmentRowInfo::REVERSED;
207 reversedAttribute.version = chromatogram.version;
208 reversedAttribute.value = MultipleAlignmentRowInfo::getReversed(additionalInfo) ? 1 : 0;
209
210 connection.dbi->getAttributeDbi()->createIntegerAttribute(reversedAttribute, os);
211 CHECK_OP(os, );
212
213 U2IntegerAttribute complementedAttribute;
214 complementedAttribute.objectId = chromatogram.id;
215 complementedAttribute.name = MultipleAlignmentRowInfo::COMPLEMENTED;
216 complementedAttribute.version = chromatogram.version;
217 complementedAttribute.value = MultipleAlignmentRowInfo::getComplemented(additionalInfo) ? 1 : 0;
218
219 connection.dbi->getAttributeDbi()->createIntegerAttribute(complementedAttribute, os);
220 CHECK_OP(os, );
221 }
222
createRelation(U2OpStatus & os,const DbiConnection & connection,const U2Sequence & sequence,const U2DataId & chromatogramId)223 void MultipleChromatogramAlignmentImporter::createRelation(U2OpStatus &os, const DbiConnection &connection, const U2Sequence &sequence, const U2DataId &chromatogramId) {
224 U2ObjectRelation dbRelation;
225 dbRelation.id = chromatogramId;
226 dbRelation.referencedName = sequence.visualName;
227 dbRelation.referencedObject = sequence.id;
228 dbRelation.referencedType = GObjectTypes::SEQUENCE;
229 dbRelation.relationRole = ObjectRole_Sequence;
230
231 connection.dbi->getObjectRelationsDbi()->createObjectRelation(dbRelation, os);
232 CHECK_OP(os, );
233 }
234
235 } // namespace U2
236