1
2 /* $Id: psl_formatter.cpp 632624 2021-06-03 17:38:23Z ivanov $
3 * ===========================================================================
4 *
5 * PUBLIC DOMAIN NOTICE
6 * National Center for Biotechnology Information
7 *
8 * This software/database is a "United States Government Work" under the
9 * terms of the United States Copyright Act. It was written as part of
10 * the author's official duties as a United States Government employee and
11 * thus cannot be copyrighted. This software/database is freely available
12 * to the public for use. The National Library of Medicine and the U.S.
13 * Government have not placed any restriction on its use or reproduction.
14 *
15 * Although all reasonable efforts have been taken to ensure the accuracy
16 * and reliability of the software and data, the NLM and the U.S.
17 * Government do not and cannot warrant the performance or results that
18 * may be obtained by using this software or data. The NLM and the U.S.
19 * Government disclaim all warranties, express or implied, including
20 * warranties of performance, merchantability or fitness for any particular
21 * purpose.
22 *
23 * Please cite the author in any work or product based on this material.
24 *
25 * ===========================================================================
26 *
27 * Authors: Frank Ludwig
28 *
29 * File Description: Write alignment
30 *
31 */
32
33 #include <ncbi_pch.hpp>
34
35 #include "psl_record.hpp"
36 #include "psl_formatter.hpp"
37
38 BEGIN_NCBI_SCOPE
39 USING_SCOPE(objects);
40
41 // ----------------------------------------------------------------------------
42 static string
sDebugFormatValue(const string & label,const string & data)43 sDebugFormatValue(
44 const string& label,
45 const string& data)
46 // ----------------------------------------------------------------------------
47 {
48 string formattedValue = (label + string(12, ' ')).substr(0, 12) + ": ";
49 formattedValue += data;
50 formattedValue += "\n";
51 return formattedValue;
52 }
53
54 // ----------------------------------------------------------------------------
55 static void
sDebugChunkArray(const vector<int> & origArray,int chunkSize,vector<vector<int>> & chunks)56 sDebugChunkArray(
57 const vector<int>& origArray,
58 int chunkSize,
59 vector<vector<int>>& chunks)
60 // ----------------------------------------------------------------------------
61 {
62 if (origArray.empty()) {
63 return;
64 }
65 auto numElements = origArray.size();
66 for (auto index=0; index < numElements; ++index) {
67 if (0 == index % chunkSize) {
68 chunks.push_back(vector<int>());
69 }
70 chunks.back().push_back(origArray[index]);
71 }
72 }
73
74 // ----------------------------------------------------------------------------
75 static string
sFormatInt(int value,int dflt)76 sFormatInt(
77 int value,
78 int dflt)
79 // ----------------------------------------------------------------------------
80 {
81 if (value == dflt) {
82 return ".";
83 }
84 return NStr::IntToString(value);
85 }
86
87 // ----------------------------------------------------------------------------
CPslFormatter(CNcbiOstream & ostr,bool debugMode)88 CPslFormatter::CPslFormatter(
89 CNcbiOstream& ostr,
90 bool debugMode):
91 // ----------------------------------------------------------------------------
92 mOstr(ostr),
93 mDebugMode(debugMode)
94 {
95 }
96
97 // ----------------------------------------------------------------------------
98 string
xFieldMatches(const CPslRecord & record) const99 CPslFormatter::xFieldMatches(
100 const CPslRecord& record) const
101 // ----------------------------------------------------------------------------
102 {
103 auto rawString = sFormatInt(record.GetMatches(), -1);
104 if (mDebugMode) {
105 return sDebugFormatValue("matches", rawString);
106 }
107 return rawString;
108 }
109
110 // ----------------------------------------------------------------------------
111 string
xFieldMisMatches(const CPslRecord & record) const112 CPslFormatter::xFieldMisMatches(
113 const CPslRecord& record) const
114 // ----------------------------------------------------------------------------
115 {
116 auto rawString = sFormatInt(record.GetMisMatches(), -1);
117 if (mDebugMode) {
118 return sDebugFormatValue("misMatches", rawString);
119 }
120 return "\t" + rawString;
121 }
122
123 // ----------------------------------------------------------------------------
124 string
xFieldRepMatches(const CPslRecord & record) const125 CPslFormatter::xFieldRepMatches(
126 const CPslRecord& record) const
127 // ----------------------------------------------------------------------------
128 {
129 auto rawString = sFormatInt(record.GetRepMatches(), -1);
130 if (mDebugMode) {
131 return sDebugFormatValue("repMatches", rawString);
132 }
133 return "\t" + rawString;
134 }
135
136 // ----------------------------------------------------------------------------
137 string
xFieldCountN(const CPslRecord & record) const138 CPslFormatter::xFieldCountN(
139 const CPslRecord& record) const
140 // ----------------------------------------------------------------------------
141 {
142 auto rawString = sFormatInt(record.GetCountN(), -1);
143 if (mDebugMode) {
144 return sDebugFormatValue("nCount", rawString);
145 }
146 return "\t" + rawString;
147 }
148
149 // ----------------------------------------------------------------------------
150 string
xFieldNumInsertQ(const CPslRecord & record) const151 CPslFormatter::xFieldNumInsertQ(
152 const CPslRecord& record) const
153 // ----------------------------------------------------------------------------
154 {
155 auto rawString = sFormatInt(record.GetNumInsertQ(), -1);
156 if (mDebugMode) {
157 return sDebugFormatValue("qNumInsert", rawString);
158 }
159 return "\t" + rawString;
160 }
161
162 // ----------------------------------------------------------------------------
163 string
xFieldBaseInsertQ(const CPslRecord & record) const164 CPslFormatter::xFieldBaseInsertQ(
165 const CPslRecord& record) const
166 // ----------------------------------------------------------------------------
167 {
168 auto rawString = sFormatInt(record.GetBaseInsertQ(), -1);
169 if (mDebugMode) {
170 return sDebugFormatValue("qBaseInsert", rawString);
171 }
172 return "\t" + rawString;
173 }
174
175 // ----------------------------------------------------------------------------
176 string
xFieldNumInsertT(const CPslRecord & record) const177 CPslFormatter::xFieldNumInsertT(
178 const CPslRecord& record) const
179 // ----------------------------------------------------------------------------
180 {
181 auto rawString = sFormatInt(record.GetNumInsertT(), -1);
182 if (mDebugMode) {
183 return sDebugFormatValue("tNumInsert", rawString);
184 }
185 return "\t" + rawString;
186 }
187
188 // ----------------------------------------------------------------------------
189 string
xFieldBaseInsertT(const CPslRecord & record) const190 CPslFormatter::xFieldBaseInsertT(
191 const CPslRecord& record) const
192 // ----------------------------------------------------------------------------
193 {
194 auto rawString = sFormatInt(record.GetBaseInsertT(), -1);
195 if (mDebugMode) {
196 return sDebugFormatValue("tBaseInsert", rawString);
197 }
198 return "\t" + rawString;
199 }
200
201 // ----------------------------------------------------------------------------
202 string
xFieldStrand(const CPslRecord & record) const203 CPslFormatter::xFieldStrand(
204 const CPslRecord& record) const
205 // ----------------------------------------------------------------------------
206 {
207 string rawString = ".";
208 if (record.GetStrandT() != eNa_strand_unknown) {
209 rawString = (record.GetStrandT() == eNa_strand_minus ? "-" : "+");
210 }
211 if (mDebugMode) {
212 return sDebugFormatValue("strand", rawString);
213 }
214 return "\t" + rawString;
215 }
216
217 // ----------------------------------------------------------------------------
218 string
xFieldNameQ(const CPslRecord & record) const219 CPslFormatter::xFieldNameQ(
220 const CPslRecord& record) const
221 // ----------------------------------------------------------------------------
222 {
223 auto rawString = record.GetNameQ();
224 if (rawString.empty()) {
225 rawString = ".";
226 }
227 if (mDebugMode) {
228 return sDebugFormatValue("qName", rawString);
229 }
230 return "\t" + rawString;
231 }
232
233 // ----------------------------------------------------------------------------
234 string
xFieldSizeQ(const CPslRecord & record) const235 CPslFormatter::xFieldSizeQ(
236 const CPslRecord& record) const
237 // ----------------------------------------------------------------------------
238 {
239 auto rawString = sFormatInt(record.GetSizeQ(), -1);
240 if (mDebugMode) {
241 return sDebugFormatValue("qSize", rawString);
242 }
243 return "\t" + rawString;
244 }
245
246 // ----------------------------------------------------------------------------
247 string
xFieldStartQ(const CPslRecord & record) const248 CPslFormatter::xFieldStartQ(
249 const CPslRecord& record) const
250 // ----------------------------------------------------------------------------
251 {
252 auto rawString = sFormatInt(record.GetStartQ(), -1);
253 if (mDebugMode) {
254 return sDebugFormatValue("qStart", rawString);
255 }
256 return "\t" + rawString;
257 }
258
259 // ----------------------------------------------------------------------------
260 string
xFieldEndQ(const CPslRecord & record) const261 CPslFormatter::xFieldEndQ(
262 const CPslRecord& record) const
263 // ----------------------------------------------------------------------------
264 {
265 auto rawString = sFormatInt(record.GetEndQ(), -1);
266 if (mDebugMode) {
267 return sDebugFormatValue("qEnd", rawString);
268 }
269 return "\t" + rawString;
270 }
271
272 // ----------------------------------------------------------------------------
273 string
xFieldNameT(const CPslRecord & record) const274 CPslFormatter::xFieldNameT(
275 const CPslRecord& record) const
276 // ----------------------------------------------------------------------------
277 {
278 auto rawString = record.GetNameT();
279 if (rawString.empty()) {
280 rawString = ".";
281 }
282 if (mDebugMode) {
283 return sDebugFormatValue("tName", rawString);
284 }
285 return "\t" + rawString;
286 }
287
288 // ----------------------------------------------------------------------------
289 string
xFieldSizeT(const CPslRecord & record) const290 CPslFormatter::xFieldSizeT(
291 const CPslRecord& record) const
292 // ----------------------------------------------------------------------------
293 {
294 auto rawString = sFormatInt(record.GetSizeT(), -1);
295 if (mDebugMode) {
296 return sDebugFormatValue("tSize", rawString);
297 }
298 return "\t" + rawString;
299 }
300
301 // ----------------------------------------------------------------------------
302 string
xFieldStartT(const CPslRecord & record) const303 CPslFormatter::xFieldStartT(
304 const CPslRecord& record) const
305 // ----------------------------------------------------------------------------
306 {
307 auto rawString = sFormatInt(record.GetStartT(), -1);
308 if (mDebugMode) {
309 return sDebugFormatValue("tStart", rawString);
310 }
311 return "\t" + rawString;
312 }
313
314 // ----------------------------------------------------------------------------
315 string
xFieldEndT(const CPslRecord & record) const316 CPslFormatter::xFieldEndT(
317 const CPslRecord& record) const
318 // ----------------------------------------------------------------------------
319 {
320 auto rawString = sFormatInt(record.GetEndT(), -1);
321 if (mDebugMode) {
322 return sDebugFormatValue("tEnd", rawString);
323 }
324 return "\t" + rawString;
325 }
326
327 // ----------------------------------------------------------------------------
328 string
xFieldBlockCount(const CPslRecord & record) const329 CPslFormatter::xFieldBlockCount(
330 const CPslRecord& record) const
331 // ----------------------------------------------------------------------------
332 {
333 auto rawString = sFormatInt(record.GetBlockCount(), -1);
334 if (mDebugMode) {
335 return sDebugFormatValue("blockCount", rawString);
336 }
337 return "\t" + rawString;
338 }
339
340 // ----------------------------------------------------------------------------
341 string
xFieldBlockSizes(const CPslRecord & record) const342 CPslFormatter::xFieldBlockSizes(
343 const CPslRecord& record) const
344 // ----------------------------------------------------------------------------
345 {
346 auto blockSizes = record.GetBlockSizes();
347 if (mDebugMode) {
348 if (blockSizes.empty()) {
349 return sDebugFormatValue("blockSizes", ".");
350 }
351 vector<vector<int>> chunks;
352 sDebugChunkArray(blockSizes, 5, chunks);
353 bool labelWritten = false;
354 string field;
355 for (auto& chunk: chunks) {
356 auto value = NStr::JoinNumeric(chunk.begin(), chunk.end(), ", ");
357 if (!labelWritten) {
358 field += sDebugFormatValue("blockSizes", value);
359 labelWritten = true;
360 }
361 else {
362 field += " ";
363 field += value;
364 field += "\n";
365 }
366 }
367 return field;
368 }
369 return "\t" + NStr::JoinNumeric(blockSizes.begin(), blockSizes.end(), ",");
370 }
371
372 // ----------------------------------------------------------------------------
373 string
xFieldStartsQ(const CPslRecord & record) const374 CPslFormatter::xFieldStartsQ(
375 const CPslRecord& record) const
376 // ----------------------------------------------------------------------------
377 {
378 auto blockStartsQ = record.GetBlockStartsQ();
379 if (mDebugMode) {
380 if (blockStartsQ.empty()) {
381 return sDebugFormatValue("qStarts", ".");
382 }
383 vector<vector<int>> chunks;
384 sDebugChunkArray(blockStartsQ, 5, chunks);
385 bool labelWritten = false;
386 string field;
387 for (auto& chunk: chunks) {
388 auto value = NStr::JoinNumeric(chunk.begin(), chunk.end(), ", ");
389 if (!labelWritten) {
390 field += sDebugFormatValue("qStarts", value);
391 labelWritten = true;
392 }
393 else {
394 field += " ";
395 field += value;
396 field += "\n";
397 }
398 }
399 return field;
400 }
401 return "\t" + NStr::JoinNumeric(blockStartsQ.begin(), blockStartsQ.end(), ",");
402 }
403
404 // ----------------------------------------------------------------------------
405 string
xFieldStartsT(const CPslRecord & record) const406 CPslFormatter::xFieldStartsT(
407 const CPslRecord& record) const
408 // ----------------------------------------------------------------------------
409 {
410 auto blockStartsT = record.GetBlockStartsT();
411 if (mDebugMode) {
412 if (blockStartsT.empty()) {
413 return sDebugFormatValue("tStarts", ".");
414 }
415 vector<vector<int>> chunks;
416 sDebugChunkArray(blockStartsT, 5, chunks);
417 bool labelWritten = false;
418 string field;
419 for (auto& chunk: chunks) {
420 auto value = NStr::JoinNumeric(chunk.begin(), chunk.end(), ", ");
421 if (!labelWritten) {
422 field += sDebugFormatValue("tStarts", value);
423 labelWritten = true;
424 }
425 else {
426 field += " ";
427 field += value;
428 field += "\n";
429 }
430 }
431 return field;
432 }
433 return "\t" + NStr::JoinNumeric(blockStartsT.begin(), blockStartsT.end(), ",");
434 }
435
436 // ----------------------------------------------------------------------------
437 void
Format(const CPslRecord & record)438 CPslFormatter::Format(
439 const CPslRecord& record)
440 // ----------------------------------------------------------------------------
441 {
442 mOstr << xFieldMatches(record)
443 << xFieldMisMatches(record)
444 << xFieldRepMatches(record)
445 << xFieldCountN(record)
446 << xFieldNumInsertQ(record)
447 << xFieldBaseInsertQ(record)
448 << xFieldNumInsertT(record)
449 << xFieldBaseInsertT(record)
450 << xFieldStrand(record)
451 << xFieldNameQ(record)
452 << xFieldSizeQ(record)
453 << xFieldStartQ(record)
454 << xFieldEndQ(record)
455 << xFieldNameT(record)
456 << xFieldSizeT(record)
457 << xFieldStartT(record)
458 << xFieldEndT(record)
459 << xFieldBlockCount(record)
460 << xFieldBlockSizes(record)
461 << xFieldStartsQ(record)
462 << xFieldStartsT(record)
463 << endl;
464 }
465
466 END_NCBI_SCOPE
467
468