1 /**
2     This is the `showPileUps` command of `dentist`.
3 
4     Copyright: © 2018 Arne Ludwig <arne.ludwig@posteo.de>
5     License: Subject to the terms of the MIT license, as written in the
6              included LICENSE file.
7     Authors: Arne Ludwig <arne.ludwig@posteo.de>
8 */
9 module dentist.commands.showPileUps;
10 
11 import dentist.common.binio : PileUpDb;
12 import dentist.common.alignments : getType;
13 import dentist.util.log;
14 import std.algorithm : map, max;
15 import std.array : array;
16 import std.conv : to;
17 import std.file : getSize;
18 import std.math : log10, lrint, FloatingPointControl;
19 import std.stdio : stderr, writefln, writeln;
20 import std.typecons : tuple;
21 import vibe.data.json :
22     toJson = serializeToJson,
23     toJsonString = serializeToPrettyJson,
24     serializeToJsonString;
25 
26 /// Execute the `showPileUps` command with `options`.
27 void execute(Options)(in Options options)
28 {
29     size_t totalDbSize = options.pileUpsFile.getSize();
30     auto pileUpDb = PileUpDb.parse(options.pileUpsFile);
31     if (!shouldLog(LogLevel.debug_))
32         pileUpDb.releaseDb();
33 
34     auto stats = Stats(
35         totalDbSize,
36         pileUpDb.pileUps.length,
37         pileUpDb.readAlignments.length,
38         pileUpDb.seededAlignments.length,
39         pileUpDb.localAlignments.length,
40         pileUpDb.tracePoints.length,
41     );
42 
43     if (options.useJson)
44         writeln(stats.toJsonString);
45     else
46         writeTabular(stats);
47 
48     if (shouldLog(LogLevel.debug_))
49     {
50         foreach (pileUp; pileUpDb[])
51         {
52             stderr.writeln(serializeToJsonString([
53                 "type": pileUp.getType.to!string.toJson,
54                 "readAlignments": pileUp.map!"a[]".array.toJson,
55             ]));
56         }
57     }
58 }
59 
60 struct Stats
61 {
62     size_t totalDbSize;
63     size_t numPileUps;
64     size_t numReadAlignments;
65     size_t numSeededAlignments;
66     size_t numLocalAlignments;
67     size_t numTracePoints;
68 
69     size_t columnWidth() const nothrow
70     {
71         FloatingPointControl fpCtrl;
72         fpCtrl.rounding = FloatingPointControl.roundUp;
73         auto numWidth = lrint(log10(max(
74             totalDbSize,
75             numPileUps,
76             numReadAlignments,
77             numSeededAlignments,
78             numLocalAlignments,
79             numTracePoints,
80         )));
81 
82         return numWidth;
83     }
84 }
85 
86 void writeTabular(Stats stats)
87 {
88     auto columnWidth = stats.columnWidth();
89 
90     writefln!"totalDbSize:         %*d bytes"(columnWidth, stats.totalDbSize);
91     writefln!"numPileUps:          %*d"(columnWidth, stats.numPileUps);
92     writefln!"numReadAlignments:   %*d"(columnWidth, stats.numReadAlignments);
93     writefln!"numSeededAlignments: %*d"(columnWidth, stats.numSeededAlignments);
94     writefln!"numLocalAlignments:  %*d"(columnWidth, stats.numLocalAlignments);
95     writefln!"numTracePoints:      %*d"(columnWidth, stats.numTracePoints);
96 }