NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
se_analyzer.cpp
Go to the documentation of this file.
1 /*
2  * nvbio
3  * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the NVIDIA CORPORATION nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
29 #include <nvbio-aln-diff/html.h>
30 #include <nvbio-aln-diff/utils.h>
31 
32 namespace nvbio {
33 namespace alndiff {
34 
36  m_filter( filter )
37 {
38  n = 0;
39  n_mismatched = 0;
40 }
41 
43  const Alignment& alnL,
44  const Alignment& alnR)
45 {
46  if (alnL.read_id != alnR.read_id ||
47  alnL.read_len != alnR.read_len)
48  {
49  n_mismatched++;
50  return;
51  }
52 
53  mapped.push( alnL.is_mapped(), alnR.is_mapped() );
54  unique.push( alnL.is_unique(), alnR.is_unique() );
55  ambiguous.push( alnL.is_ambiguous(), alnR.is_ambiguous() );
56 
57  if ((alnL.is_mapped() == true) && (alnR.is_mapped() == false)) mapped_L_not_R_by_mapQ.push( log_bin( alnL.mapQ ) );
58  if ((alnR.is_mapped() == true) && (alnL.is_mapped() == false)) mapped_R_not_L_by_mapQ.push( log_bin( alnR.mapQ ) );
59  if ((alnL.is_unique() == true) && (alnR.is_unique() == false)) unique_L_not_R_by_mapQ.push( log_bin( alnL.mapQ ) );
60  if ((alnR.is_unique() == true) && (alnL.is_unique() == false)) unique_R_not_L_by_mapQ.push( log_bin( alnR.mapQ ) );
61  if ((alnL.is_ambiguous() == true) && (alnR.is_ambiguous() == false)) ambiguous_L_not_R_by_mapQ.push( log_bin( alnL.mapQ ) );
62  if ((alnR.is_ambiguous() == true) && (alnL.is_ambiguous() == false)) ambiguous_R_not_L_by_mapQ.push( log_bin( alnR.mapQ ) );
63 
64  if (alnL.is_mapped() && alnR.is_mapped())
65  {
66  const uint32 mapQ_bin = log_bin( alnR.mapQ );
67 
68  uint32 read_flags = 0u;
69 
70  if (alnL.ref_id != alnR.ref_id)
71  {
72  n_different_ref.push( mapQ_bin );
73  n_distant.push( mapQ_bin );
74  read_flags |= Filter::DISTANT;
75  read_flags |= Filter::DIFFERENT_REF;
76  }
77  else if (alndiff::distant( alnL, alnR ))
78  {
79  n_distant.push( mapQ_bin );
80  read_flags |= Filter::DISTANT;
81  }
82 
83  if (alnL.is_rc() != alnR.is_rc())
84  {
85  n_discordant.push( mapQ_bin );
86  read_flags |= Filter::DISCORDANT;
87  }
88 
89  const uint32 length_bin = read_length_bin( alnL.read_len );
90 
91  // generic stats
92  {
93  // ed
94  m_filter( al_stats.lower_ed.push( alnL.ed, alnR.ed, length_bin, alnL.mapQ, alnR.mapQ ), read_flags, Filter::ED, alnL.read_id );
95 
96  // mapQ
97  m_filter( al_stats.higher_mapQ.push( alnL.mapQ, alnR.mapQ, length_bin, alnL.mapQ, alnR.mapQ ), read_flags, Filter::MAPQ, alnL.read_id );
98 
99  // longer mapping
100  al_stats.longer_mapping.push( alnL.mapped_read_bases(), alnR.mapped_read_bases(), length_bin, alnL.mapQ, alnR.mapQ );
101 
102  al_stats.lower_subs.push( alnL.subs, alnR.subs, length_bin, alnL.mapQ, alnR.mapQ );
103  m_filter( al_stats.lower_mms.push( alnL.n_mm, alnR.n_mm, length_bin, alnL.mapQ, alnR.mapQ ), read_flags, Filter::MMS, alnL.read_id );
104  m_filter( al_stats.lower_ins.push( alnL.ins, alnR.ins, length_bin, alnL.mapQ, alnR.mapQ ), read_flags, Filter::INS, alnL.read_id );
105  m_filter( al_stats.lower_dels.push( alnL.dels, alnR.dels, length_bin, alnL.mapQ, alnR.mapQ ), read_flags, Filter::DELS, alnL.read_id );
106 
107  al_stats.higher_pos.push( alnL.pos, alnR.pos, length_bin, alnL.mapQ, alnR.mapQ );
108  }
109  if (read_flags & Filter::DISTANT)
110  {
111  // ed
112  distant_stats.lower_ed.push( alnL.ed, alnR.ed, length_bin, alnL.mapQ, alnR.mapQ );
113 
114  // mapQ
115  distant_stats.higher_mapQ.push( alnL.mapQ, alnR.mapQ, length_bin, alnL.mapQ, alnR.mapQ );
116 
117  // longer mapping
118  distant_stats.longer_mapping.push( alnL.mapped_read_bases(), alnR.mapped_read_bases(), length_bin, alnL.mapQ, alnR.mapQ );
119 
120  distant_stats.lower_subs.push( alnL.subs, alnR.subs, length_bin, alnL.mapQ, alnR.mapQ );
121  distant_stats.lower_mms.push( alnL.n_mm, alnR.n_mm, length_bin, alnL.mapQ, alnR.mapQ );
122  distant_stats.lower_ins.push( alnL.ins, alnR.ins, length_bin, alnL.mapQ, alnR.mapQ );
123  distant_stats.lower_dels.push( alnL.dels, alnR.dels, length_bin, alnL.mapQ, alnR.mapQ );
124  distant_stats.higher_pos.push( alnL.pos, alnR.pos, length_bin, alnL.mapQ, alnR.mapQ );
125  }
126  if (read_flags & Filter::DISCORDANT)
127  {
128  // ed
129  discordant_stats.lower_ed.push( alnL.ed, alnR.ed, length_bin, alnL.mapQ, alnR.mapQ );
130 
131  // mapQ
132  discordant_stats.higher_mapQ.push( alnL.mapQ, alnR.mapQ, length_bin, alnL.mapQ, alnR.mapQ );
133 
134  // longer mapping
135  discordant_stats.longer_mapping.push( alnL.mapped_read_bases(), alnR.mapped_read_bases(), length_bin, alnL.mapQ, alnR.mapQ );
136 
137  discordant_stats.lower_subs.push( alnL.subs, alnR.subs, length_bin, alnL.mapQ, alnR.mapQ );
138  discordant_stats.lower_mms.push( alnL.n_mm, alnR.n_mm, length_bin, alnL.mapQ, alnR.mapQ );
139  discordant_stats.lower_ins.push( alnL.ins, alnR.ins, length_bin, alnL.mapQ, alnR.mapQ );
140  discordant_stats.lower_dels.push( alnL.dels, alnR.dels, length_bin, alnL.mapQ, alnR.mapQ );
141  discordant_stats.higher_pos.push( alnL.pos, alnR.pos, length_bin, alnL.mapQ, alnR.mapQ );
142  }
143  }
144 
145  ++n;
146 }
147 
148 namespace {
149 
150 void generate_summary_header(FILE* html_output)
151 {
152  html::tr_object tr( html_output, NULL );
153  html::th_object( html_output, html::FORMATTED, NULL, "" );
154  html::th_object( html_output, html::FORMATTED, NULL, "better" );
155  html::th_object( html_output, html::FORMATTED, "class", "red", NULL, "worse" );
156 }
157 template <typename StatsType>
158 void generate_summary_cell(FILE* html_output, const std::string file_name, const char* type, const StatsType& stats, const uint32 n)
159 {
160  char link_name[1024];
161  sprintf( link_name, "<a href=\"%s\">%s</a>", local_file( file_name ), type );
162  html::tr_object tr( html_output, "class", "alt", NULL );
163  html::th_object( html_output, html::FORMATTED, NULL, link_name );
164  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %%", 100.0f * float(stats.l.diff_hist.all_but(0))/float(n) );
165  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %%", 100.0f * float(stats.r.diff_hist.all_but(0))/float(n) );
166 }
167 
168 } // anonymous namespace
169 
170 void SEAnalyzer::generate_report(const char* aln_file_name1, const char* aln_file_name2, const char* report)
171 {
172  if (report == NULL)
173  return;
174 
175  const std::string mapped_bps_name = generate_file_name( report, "mapped-bps" );
176  const std::string ed_name = generate_file_name( report, "ed" );
177  const std::string mapQ_name = generate_file_name( report, "mapQ" );
178  const std::string mms_name = generate_file_name( report, "mms" );
179  const std::string ins_name = generate_file_name( report, "ins" );
180  const std::string dels_name = generate_file_name( report, "dels" );
181  const std::string pos_name = generate_file_name( report, "pos" );
182 
183  const std::string distant_mapped_bps_name = generate_file_name( report, "distant_stats.mapped-bps" );
184  const std::string distant_ed_name = generate_file_name( report, "distant_stats.ed" );
185  const std::string distant_mapQ_name = generate_file_name( report, "distant_stats.mapQ" );
186  const std::string distant_mms_name = generate_file_name( report, "distant_stats.mms" );
187  const std::string distant_ins_name = generate_file_name( report, "distant_stats.ins" );
188  const std::string distant_dels_name = generate_file_name( report, "distant_stats.dels" );
189  const std::string distant_pos_name = generate_file_name( report, "distant_stats.pos" );
190 
191  const std::string discordant_mapped_bps_name = generate_file_name( report, "discordant_stats.mapped-bps" );
192  const std::string discordant_ed_name = generate_file_name( report, "discordant_stats.ed" );
193  const std::string discordant_mapQ_name = generate_file_name( report, "discordant_stats.mapQ" );
194  const std::string discordant_mms_name = generate_file_name( report, "discordant_stats.mms" );
195  const std::string discordant_ins_name = generate_file_name( report, "discordant_stats.ins" );
196  const std::string discordant_dels_name = generate_file_name( report, "discordant_stats.dels" );
197  const std::string discordant_pos_name = generate_file_name( report, "discordant_stats.pos" );
198 
199  generate_table( mapped_bps_name.c_str(), "mapped L & R", "mapped bps", "mapped bps diff", al_stats.longer_mapping.bin_type(), al_stats.longer_mapping.l, al_stats.longer_mapping.r, n, mapped.L_and_R );
200  generate_table( ed_name.c_str(), "mapped L & R", "edit distance", "edit distance diff", al_stats.lower_ed.bin_type(), al_stats.lower_ed.l, al_stats.lower_ed.r, n, mapped.L_and_R );
201  generate_table( mapQ_name.c_str(), "mapped L & R", "mapQ", "mapQ diff", al_stats.higher_mapQ.bin_type(), al_stats.higher_mapQ.l, al_stats.higher_mapQ.r, n, mapped.L_and_R );
202  generate_table( mms_name.c_str(), "mapped L & R", "mms", "mms diff", al_stats.lower_mms.bin_type(), al_stats.lower_mms.l, al_stats.lower_mms.r, n, mapped.L_and_R );
203  generate_table( ins_name.c_str(), "mapped L & R", "ins", "ins diff", al_stats.lower_ins.bin_type(), al_stats.lower_ins.l, al_stats.lower_ins.r, n, mapped.L_and_R );
204  generate_table( dels_name.c_str(), "mapped L & R", "dels", "dels diff", al_stats.lower_dels.bin_type(), al_stats.lower_dels.l, al_stats.lower_dels.r, n, mapped.L_and_R );
205  generate_table( pos_name.c_str(), "mapped L & R", "position", "distance", al_stats.higher_pos.bin_type(), al_stats.higher_pos.l, al_stats.higher_pos.r, n, mapped.L_and_R, false );
206 
207  generate_table( distant_mapped_bps_name.c_str(), "distant", "mapped bps", "mapped bps diff", distant_stats.longer_mapping.bin_type(), distant_stats.longer_mapping.l, distant_stats.longer_mapping.r, n, n_distant.count );
208  generate_table( distant_ed_name.c_str(), "distant", "edit distance", "edit distance diff", distant_stats.lower_ed.bin_type(), distant_stats.lower_ed.l, distant_stats.lower_ed.r, n, n_distant.count );
209  generate_table( distant_mapQ_name.c_str(), "distant", "mapQ", "mapQ diff", distant_stats.higher_mapQ.bin_type(), distant_stats.higher_mapQ.l, distant_stats.higher_mapQ.r, n, n_distant.count );
210  generate_table( distant_mms_name.c_str(), "distant", "mms", "mms diff", distant_stats.lower_mms.bin_type(), distant_stats.lower_mms.l, distant_stats.lower_mms.r, n, n_distant.count );
211  generate_table( distant_ins_name.c_str(), "distant", "ins", "ins diff", distant_stats.lower_ins.bin_type(), distant_stats.lower_ins.l, distant_stats.lower_ins.r, n, n_distant.count );
212  generate_table( distant_dels_name.c_str(), "distant", "dels", "dels diff", distant_stats.lower_dels.bin_type(), distant_stats.lower_dels.l, distant_stats.lower_dels.r, n, n_distant.count );
213  generate_table( distant_pos_name.c_str(), "distant", "position", "distance", distant_stats.higher_pos.bin_type(), distant_stats.higher_pos.l, distant_stats.higher_pos.r, n, n_distant.count, false );
214 
215  generate_table( discordant_mapped_bps_name.c_str(), "discordant", "mapped bps", "mapped bps diff", discordant_stats.longer_mapping.bin_type(), discordant_stats.longer_mapping.l, discordant_stats.longer_mapping.r, n, n_discordant.count );
216  generate_table( discordant_ed_name.c_str(), "discordant", "edit distance", "edit distance diff", discordant_stats.lower_ed.bin_type(), discordant_stats.lower_ed.l, discordant_stats.lower_ed.r, n, n_discordant.count );
217  generate_table( discordant_mapQ_name.c_str(), "discordant", "mapQ", "mapQ diff", discordant_stats.higher_mapQ.bin_type(), discordant_stats.higher_mapQ.l, discordant_stats.higher_mapQ.r, n, n_discordant.count );
218  generate_table( discordant_mms_name.c_str(), "discordant", "mms", "mms diff", discordant_stats.lower_mms.bin_type(), discordant_stats.lower_mms.l, discordant_stats.lower_mms.r, n, n_discordant.count );
219  generate_table( discordant_ins_name.c_str(), "discordant", "ins", "ins diff", discordant_stats.lower_ins.bin_type(), discordant_stats.lower_ins.l, discordant_stats.lower_ins.r, n, n_discordant.count );
220  generate_table( discordant_dels_name.c_str(), "discordant", "dels", "dels diff", discordant_stats.lower_dels.bin_type(), discordant_stats.lower_dels.l, discordant_stats.lower_dels.r, n, n_discordant.count );
221  generate_table( discordant_pos_name.c_str(), "discordant", "position", "distance", discordant_stats.higher_pos.bin_type(), discordant_stats.higher_pos.l, discordant_stats.higher_pos.r, n, n_discordant.count, false );
222 
223  FILE* html_output = fopen( report, "w" );
224  if (html_output == NULL)
225  {
226  log_warning( stderr, "unable to write HTML report \"%s\"\n", report );
227  return;
228  }
229 
230  const Histogram<8> cum_different_ref = reverse_cumulative( n_different_ref );
231  const Histogram<8> cum_distant = reverse_cumulative( n_distant );
232  const Histogram<8> cum_discordant = reverse_cumulative( n_discordant );
233 
234  const uint32 HI_MAPQ_BIN = 6; // >= 32
235  {
236  html::html_object html( html_output );
237  {
238  const char* meta_list = "<meta http-equiv=\"refresh\" content=\"5\" />";
239 
240  html::header_object hd( html_output, "nv-aln-diff report", html::style(), meta_list );
241  {
242  html::body_object body( html_output );
243 
244  //
245  // alignment stats
246  //
247  {
248  html::table_object table( html_output, "alignment-stats", "stats", "alignment stats" );
249  {
250  html::tr_object tr( html_output, NULL );
251  html::th_object( html_output, html::FORMATTED, NULL, "" );
252  html::th_object( html_output, html::FORMATTED, NULL, "L = %s", aln_file_name1 );
253  html::th_object( html_output, html::FORMATTED, NULL, "R = %s", aln_file_name2 );
254  html::th_object( html_output, html::FORMATTED, NULL, "L & R" );
255  html::th_object( html_output, html::FORMATTED, NULL, "L \\ R" );
256  html::th_object( html_output, html::FORMATTED, NULL, "R \\ L" );
257  }
258  {
259  html::tr_object tr( html_output, "class", "alt", NULL );
260  html::th_object( html_output, html::FORMATTED, NULL, "mapped");
261  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %%", 100.0f * float(mapped.L) / float(n) );
262  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %%", 100.0f * float(mapped.R) / float(n) );
263  html::td_object( html_output, html::FORMATTED, "class", "green", NULL, "%5.2f %%", 100.0f * float(mapped.L_and_R) / float(n) );
264  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %% (%.3f %%)", 100.0f * float(mapped.L_not_R) / float(n), 100.0f * float(mapped_L_not_R_by_mapQ[HI_MAPQ_BIN]) / float(n) );
265  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %% (%.3f %%)", 100.0f * float(mapped.R_not_L) / float(n), 100.0f * float(mapped_R_not_L_by_mapQ[HI_MAPQ_BIN]) / float(n) );
266  }
267  {
268  html::tr_object tr( html_output, NULL );
269  html::th_object( html_output, html::FORMATTED, NULL, "unique");
270  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %%", 100.0f * float(unique.L) / float(n) );
271  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %%", 100.0f * float(unique.R) / float(n) );
272  html::td_object( html_output, html::FORMATTED, "class", "green", NULL, "%5.2f %%", 100.0f * float(unique.L_and_R) / float(n) );
273  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %% (%.3f %%)", 100.0f * float(unique.L_not_R) / float(n), 100.0f * float(unique_L_not_R_by_mapQ[HI_MAPQ_BIN]) / float(n) );
274  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %% (%.3f %%)", 100.0f * float(unique.R_not_L) / float(n), 100.0f * float(unique_R_not_L_by_mapQ[HI_MAPQ_BIN]) / float(n) );
275  }
276  {
277  html::tr_object tr( html_output, "class", "alt", NULL );
278  html::th_object( html_output, html::FORMATTED, NULL, "ambiguous");
279  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %%", 100.0f * float(ambiguous.L) / float(n) );
280  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %%", 100.0f * float(ambiguous.R) / float(n) );
281  html::td_object( html_output, html::FORMATTED, "class", "green", NULL, "%5.2f %%", 100.0f * float(ambiguous.L_and_R) / float(n) );
282  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %% (%.3f %%)", 100.0f * float(ambiguous.L_not_R) / float(n), 100.0f * float(ambiguous_L_not_R_by_mapQ[HI_MAPQ_BIN]) / float(n) );
283  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %% (%.3f %%)", 100.0f * float(ambiguous.R_not_L) / float(n), 100.0f * float(ambiguous_R_not_L_by_mapQ[HI_MAPQ_BIN]) / float(n) );
284  }
285  }
286  //
287  // discordance stats
288  //
289  {
290  html::table_object table( html_output, "discordance-stats", "stats", "discordance stats" );
291  {
292  html::tr_object tr( html_output, NULL );
293  html::th_object( html_output, html::FORMATTED, NULL, "" );
294  html::th_object( html_output, html::FORMATTED, NULL, "items" );
295  html::th_object( html_output, html::FORMATTED, NULL, "%% of total" );
296  }
297  {
298  html::tr_object tr( html_output, NULL );
299  html::th_object( html_output, html::FORMATTED, NULL, "different reference" );
300  html::td_object( html_output, html::FORMATTED, NULL, "%.2f M (%.2f M)", float(cum_different_ref[0]) * 1.0e-6f, float(cum_different_ref[HI_MAPQ_BIN]) * 1.0e-6f );
301  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %% (%.3f %%)", 100.0f * float(cum_different_ref[0]) / float(n), 100.0f * float(cum_different_ref[HI_MAPQ_BIN]) / float(n) );
302  }
303  {
304  html::tr_object tr( html_output, "class", "alt", NULL );
305  html::th_object( html_output, html::FORMATTED, NULL, "distant" );
306  html::td_object( html_output, html::FORMATTED, NULL, "%.2f M (%.2f M)", float(cum_distant[0]) * 1.0e-6f, float(cum_distant[HI_MAPQ_BIN]) * 1.0e-6f );
307  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %% (%.3f %%)", 100.0f * float(cum_distant[0]) / float(n), 100.0f * float(cum_distant[HI_MAPQ_BIN]) / float(n) );
308  }
309  {
310  html::tr_object tr( html_output, NULL );
311  html::th_object( html_output, html::FORMATTED, NULL, "discordant" );
312  html::td_object( html_output, html::FORMATTED, NULL, "%.2f M (%.2f M)", float(cum_discordant[0]) * 1.0e-6f, float(cum_discordant[HI_MAPQ_BIN]) * 1.0e-6f );
313  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %% (%.3f %%)", 100.0f * float(cum_discordant[0]) / float(n), 100.0f * float(cum_discordant[HI_MAPQ_BIN]) / float(n) );
314  }
315  }
316  //
317  // summary stats
318  //
319  {
320  html::table_object table( html_output, "summary-stats", "stats", "summary stats" );
321  generate_summary_header( html_output );
322  generate_summary_cell( html_output, mapped_bps_name, "mapped bases", al_stats.longer_mapping, n );
323  generate_summary_cell( html_output, ed_name, "edit distance",al_stats.lower_ed, n );
324  generate_summary_cell( html_output, mapQ_name, "mapQ", al_stats.higher_mapQ, n );
325  generate_summary_cell( html_output, mms_name, "mismatches", al_stats.lower_mms, n );
326  generate_summary_cell( html_output, ins_name, "insertions", al_stats.lower_ins, n );
327  generate_summary_cell( html_output, dels_name, "deletions", al_stats.lower_dels, n );
328  generate_summary_cell( html_output, pos_name, "distance", al_stats.higher_pos, n );
329  // ------------------------------------------- distant -------------------------------------------------- //
330  generate_summary_header( html_output );
331  generate_summary_cell( html_output, distant_mapped_bps_name, "mapped bases [distant]", distant_stats.longer_mapping, n );
332  generate_summary_cell( html_output, distant_ed_name, "edit distance [distant]",distant_stats.lower_ed, n );
333  generate_summary_cell( html_output, distant_mapQ_name, "mapQ [distant]", distant_stats.higher_mapQ, n );
334  generate_summary_cell( html_output, distant_mms_name, "mismatches [distant]", distant_stats.lower_mms, n );
335  generate_summary_cell( html_output, distant_ins_name, "insertions [distant]", distant_stats.lower_ins, n );
336  generate_summary_cell( html_output, distant_dels_name, "deletions [distant]", distant_stats.lower_dels, n );
337  generate_summary_cell( html_output, distant_pos_name, "distance [distant]", distant_stats.higher_pos, n );
338  // ------------------------------------------- discordant ---------------------------------------------- //
339  generate_summary_header( html_output );
340  generate_summary_cell( html_output, discordant_mapped_bps_name, "mapped bases [discordant]", discordant_stats.longer_mapping, n );
341  generate_summary_cell( html_output, discordant_ed_name, "edit distance [discordant]",discordant_stats.lower_ed, n );
342  generate_summary_cell( html_output, discordant_mapQ_name, "mapQ [discordant]", discordant_stats.higher_mapQ, n );
343  generate_summary_cell( html_output, discordant_mms_name, "mismatches [discordant]", discordant_stats.lower_mms, n );
344  generate_summary_cell( html_output, discordant_ins_name, "insertions [discordant]", discordant_stats.lower_ins, n );
345  generate_summary_cell( html_output, discordant_dels_name, "deletions [discordant]", discordant_stats.lower_dels, n );
346  generate_summary_cell( html_output, discordant_pos_name, "distance [discordant]", discordant_stats.higher_pos, n );
347  }
348 
349  // mapped L not R
351  html_output,
352  "by mapQ",
353  "mapped (L \\ R) vs (R \\ L)",
354  LOG,
357  n,
358  n );
359 
360  // unique L not R
362  html_output,
363  "by mapQ",
364  "unique (L \\ R) vs (R \\ L)",
365  LOG,
368  n,
369  n );
370 
371  // unique L not R
373  html_output,
374  "by mapQ",
375  "ambiguous (L \\ R) vs (R \\ L)",
376  LOG,
379  n,
380  n );
381 
382  // different reference by mapQ
384  html_output,
385  "mapped L & R",
386  "different reference by mapQ",
387  LOG,
389  mapped.L_and_R );
390 
391  // different reference by mapQ
393  html_output,
394  "mapped L & R",
395  "distant by mapQ",
396  LOG,
397  n_distant,
398  mapped.L_and_R );
399 
400  // discordant reference by mapQ
402  html_output,
403  "mapped L & R",
404  "discordant by mapQ",
405  LOG,
406  n_discordant,
407  mapped.L_and_R );
408  }
409  }
410  }
411  fclose( html_output );
412 }
413 
414 } // namespace alndiff
415 } // namespace nvbio