NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
html.h
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 
28 #pragma once
29 
30 #include <nvbio-aln-diff/utils.h>
32 #include <nvbio/basic/html.h>
33 #include <string>
34 #include <vector>
35 
36 namespace nvbio {
37 namespace alndiff {
38 
39 inline
40 std::string generate_file_name(const char* report, const char* name)
41 {
42  std::string file_name = report;
43  {
44  const size_t offset = file_name.find(".html");
45  file_name.replace( offset+1, file_name.length() - offset - 1, name );
46  file_name.append( ".html" );
47  }
48  return file_name;
49 }
50 inline
51 void add_param(FILE* html_output, const char* name, const uint32 val, bool alt)
52 {
53  html::tr_object tr( html_output, "class", alt ? "alt" : "none", NULL );
54  html::th_object( html_output, html::FORMATTED, NULL, name );
55  html::td_object( html_output, html::FORMATTED, NULL, "%u", val );
56 }
57 inline
58 void add_param(FILE* html_output, const char* name, const float val, bool alt)
59 {
60  html::tr_object tr( html_output, "class", alt ? "alt" : "none", NULL );
61  html::th_object( html_output, html::FORMATTED, NULL, name );
62  html::td_object( html_output, html::FORMATTED, NULL, "%f", val );
63 }
64 inline
65 void add_param(FILE* html_output, const char* name, const char* val, bool alt)
66 {
67  html::tr_object tr( html_output, "class", alt ? "alt" : "none", NULL );
68  html::th_object( html_output, html::FORMATTED, NULL, name );
69  html::td_object( html_output, html::FORMATTED, NULL, "%s", val );
70 }
71 
72 // find greatest two values in a table
73 //
74 template <typename T>
75 void find_gt2(const int32 first_row, const int32 last_row, const T& table, int32 best_bin[2])
76 {
77  best_bin[0] = 0;
78  best_bin[1] = 1;
79  uint32 best_bin_val[2] = {0};
80  for (int32 i = first_row; i <= last_row; ++i)
81  {
82  if (best_bin_val[0] < table[i])
83  {
84  best_bin_val[1] = best_bin_val[0];
85  best_bin[1] = best_bin[0];
86  best_bin_val[0] = table[i];
87  best_bin[0] = i;
88  }
89  else if (best_bin_val[1] < table[i])
90  {
91  best_bin_val[1] = table[i];
92  best_bin[1] = i;
93  }
94  }
95 }
96 
97 // compute first row with a non-zero display value
98 //
99 template <uint32 XX>
100 int32 first_display_row(const Histogram<XX>& table, const uint32 total, const int32 last_row = 0)
101 {
102  const int32 X = XX;
103 
104  int32 first_row = last_row;
105  for (int32 i = last_row; i > -X; --i)
106  {
107  if (100.0f * float(table[i])/float(total) > 0.01f)
108  first_row = i;
109  }
110  return first_row;
111 }
112 
113 // compute last row with a non-zero display value
114 //
115 template <uint32 XX>
116 int32 last_display_row(const Histogram<XX>& table, const uint32 total, const int32 first_row = 0)
117 {
118  const int32 X = XX;
119 
120  int32 last_row = first_row;
121  for (int32 i = first_row; i < X; ++i)
122  {
123  if (100.0f * float(table[i])/float(total) > 0.01f)
124  last_row = i;
125  }
126  return last_row;
127 }
128 
129 // compute first and last rows with a non-zero display value
130 //
131 template <uint32 XX>
132 int2 display_range(const Histogram<XX>& table, const uint32 total)
133 {
134  return make_int2(
135  first_display_row( table, total ),
136  last_display_row( table, total ) );
137 }
138 
139 inline
140 void stats_string(char* buffer, const float v, const float range)
141 {
142  sprintf(buffer,"<span><statnum>%5.2f %%%%</statnum> <statbar style=\"width:%.1f%%%%\">\'</statbar></span>", v, 2.0f + range * v/100.0f);
143 }
144 
145 template <uint32 XX>
147  FILE* html_output,
148  const char* stat_by,
149  const char* name,
150  const Bins bin_type,
151  const Histogram<XX>& stats_l,
152  const Histogram<XX>& stats_r,
153  const uint32 total,
154  const uint32 n_mapped_both)
155 {
156  const int32 X = XX;
157 
158  //
159  // kernel summary stats
160  //
161  {
162  char buffer1[1024];
163  char buffer2[1024];
164  sprintf( buffer1, "%s-summary-stats", name );
165  sprintf( buffer2, "%s [%s] summary stats", name, stat_by );
166  html::table_object tab( html_output, buffer1, "stats", buffer2 );
167  {
168  html::tr_object tr(html_output, NULL);
169  html::th_object(html_output, html::FORMATTED, NULL, "file names");
170  html::td_object(html_output, html::FORMATTED, "colspan", "2", "align", "center", NULL, "[L]"/*, aln_file_name1*/);
171  html::td_object(html_output, html::FORMATTED, "colspan", "2", "align", "center", NULL, "[R]"/*, aln_file_name2*/);
172  }
173  {
174  html::tr_object tr( html_output, NULL );
175  html::th_object( html_output, html::FORMATTED, NULL, "" );
176  html::th_object( html_output, html::FORMATTED, NULL, "better/equal" );
177  html::th_object( html_output, html::FORMATTED, NULL, "equal" );
178  html::th_object( html_output, html::FORMATTED, NULL, "better" );
179  html::th_object( html_output, html::FORMATTED, NULL, "worse" );
180  }
181  {
182  html::tr_object tr( html_output, NULL );
183  html::th_object( html_output, html::FORMATTED, NULL, "items" );
184  html::td_object( html_output, html::FORMATTED, NULL, "%.2f M", float(stats_l.count) * 1.0e-6f );
185  html::td_object( html_output, html::FORMATTED, NULL, "%.2f M", float(stats_l[0]) * 1.0e-6f );
186  html::td_object( html_output, html::FORMATTED, "class", "yellow", NULL, "%.2f M", float(stats_l.all_but(0)) * 1.0e-6f );
187  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%.2f M", float(stats_r.all_but(0)) * 1.0e-6f );
188  }
189  {
190  html::tr_object tr( html_output, "class", "alt", NULL );
191  html::th_object( html_output, html::FORMATTED, NULL, "%% of total" );
192  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %%", 100.0f * float(stats_l.count)/float(total) );
193  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %%", 100.0f * float(stats_l[0])/float(total) );
194  html::td_object( html_output, html::FORMATTED, "class", "yellow", NULL, "%5.2f %%", 100.0f * float(stats_l.all_but(0))/float(total) );
195  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %%", 100.0f * float(stats_r.all_but(0))/float(total) );
196  }
197  {
198  html::tr_object tr( html_output, NULL );
199  html::th_object( html_output, html::FORMATTED, NULL, "%% of %s", stat_by );
200  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %%", 100.0f * float(stats_l.count)/float(n_mapped_both) );
201  html::td_object( html_output, html::FORMATTED, NULL, "%5.2f %%", 100.0f * float(stats_l[0])/float(n_mapped_both) );
202  html::td_object( html_output, html::FORMATTED, "class", "yellow", NULL, "%5.2f %%", 100.0f * float(stats_l.all_but(0))/float(n_mapped_both) );
203  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, "%5.2f %%", 100.0f * float(stats_r.all_but(0))/float(n_mapped_both) );
204  }
205  }
206 
207  //
208  // table stats
209  //
210  {
211  char buffer1[1024];
212  char buffer2[1024];
213  sprintf( buffer1, "%s-stats", name );
214  sprintf( buffer2, "%s [%s] stats", name, stat_by );
215  html::table_object tab( html_output, buffer1, "stats", buffer2 );
216  {
217  html::tr_object tr( html_output, NULL );
218  html::th_object( html_output, html::FORMATTED, NULL, "bin" );
219  html::th_object( html_output, html::FORMATTED, NULL, "%% of total" );
220  html::th_object( html_output, html::FORMATTED, NULL, "%% of %s", stat_by );
221  html::th_object( html_output, html::FORMATTED, NULL, "%% of diff" );
222  html::th_object( html_output, html::FORMATTED, NULL, "cumulative (+)" );
223  html::th_object( html_output, html::FORMATTED, NULL, "cumulative (-)" );
224  }
225 
226  const Histogram<X>& table = stats_l;
227  const Histogram<X>& table_neg = stats_r;
228 
229  int32 best_bin[2] = {0};
230  find_gt2( 0, X-1, table, best_bin );
231 
232  const int32 last_row = last_display_row( stats_l, n_mapped_both );
233  const int32 last_row_neg = last_display_row( stats_r, n_mapped_both );
234 
235  // compute cumulative values, from best to worst
236  float cum_pos[X];
237  float cum_neg[X];
238  cum_pos[X-1] = 100.0f * float(table[X-1])/float(n_mapped_both);
239  for (int32 i = X-2; i >= 0; --i)
240  cum_pos[i] = 100.0f * float(table[i])/float(n_mapped_both) + cum_pos[i+1];
241  cum_neg[0] = cum_pos[0];
242  for (int32 i = 1; i < X; ++i)
243  cum_neg[i] = 100.0f * float(table_neg[i])/float(n_mapped_both) + cum_neg[i-1];
244 
245  const float max_perc = 48.0f;
246 
247  char span_string[1024];
248  for (int32 i = last_row_neg; i > 0; --i)
249  {
250  html::tr_object tr( html_output, "class", i % 2 ? "none" : "alt", NULL );
251  html::th_object( html_output, html::FORMATTED, NULL, "%d", -int32(bin_type == LOG ? log_bin_range(i) : i) );
252  stats_string( span_string, 100.0f * float(table_neg[i]) / float(total), max_perc );
253  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, span_string );
254  stats_string( span_string, 100.0f * float(table_neg[i]) / float(n_mapped_both), max_perc );
255  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, span_string );
256  stats_string( span_string, stats_r.count ? 100.0f * float(table_neg[i]) / float(stats_r.count) : 0.0f, max_perc );
257  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, span_string );
258  stats_string( span_string, cum_neg[i], max_perc );
259  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, span_string );
260  stats_string( span_string, 100.0f - cum_neg[i] + 100.0f * float(table_neg[i])/float(n_mapped_both), max_perc );
261  html::td_object( html_output, html::FORMATTED, "class", "pink", NULL, span_string );
262  }
263  for (int32 i = 0; i <= last_row; ++i)
264  {
265  html::tr_object tr( html_output, "class", i % 2 ? "none" : "alt", NULL );
266  html::th_object( html_output, html::FORMATTED, NULL, "%d", (bin_type == LOG ? log_bin_range(i) : i) );
267  const char* cls = i == best_bin[0] ? "yellow" : i == best_bin[1] ? "orange" : "none";
268  stats_string( span_string, 100.0f * float(table_neg[i]) / float(total), max_perc );
269  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, span_string );
270  stats_string( span_string, 100.0f * float(table[i]) / float(n_mapped_both), max_perc );
271  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, span_string );
272  stats_string( span_string, stats_l.count ? 100.0f * float(table[i]) / float(stats_l.count) : 0.0f, max_perc );
273  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, span_string );
274  stats_string( span_string, cum_pos[i], max_perc );
275  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, span_string );
276  stats_string( span_string, 100.0f - cum_pos[i] + 100.0f * float(table[i])/float(n_mapped_both), max_perc );
277  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, span_string );
278  }
279  }
280 }
281 
282 template <uint32 XX>
284  FILE* html_output,
285  const char* stat_by,
286  const char* name,
287  const Bins bin_type,
288  const Histogram<XX>& stats,
289  const uint32 total)
290 {
291  //
292  // table stats
293  //
294 
295  const int32 X = XX;
296 
297  const Histogram<X>& table = stats;
298 
299  // find range, negative values
300  const int2 row_range = display_range( stats, total );
301 
302  // compute best 2 entries
303  int32 best_bin[2] = { 0, 1 };
304 
305  find_gt2( row_range.x, row_range.y, stats, best_bin );
306 
307  // write HTML table
308  {
309  char buffer1[1024];
310  char buffer2[1024];
311  sprintf( buffer1, "%s-stats", name );
312  sprintf( buffer2, "%s [%s] stats", name, stat_by );
313  html::table_object tab( html_output, buffer1, "stats", buffer2 );
314  {
315  html::tr_object tr( html_output, NULL );
316  html::th_object( html_output, html::FORMATTED, NULL, "bin" );
317  html::th_object( html_output, html::FORMATTED, NULL, "%%" );
318  }
319 
320  char span_string[1024];
321  const float max_perc = 70.0f;
322  for (int32 i = row_range.x; i <= row_range.y; ++i)
323  {
324  html::tr_object tr( html_output, "class", i % 2 ? "none" : "alt", NULL );
325 
326  const int32 c = bin_type == LOG ? log_bin_range(i >= 0 ? i : -i) : i >= 0 ? i : -i;
327 
328  const char* cls = (i == best_bin[0]) ? "yellow" :
329  (i == best_bin[1]) ? "orange" :
330  "none";
331 
332  html::th_object( html_output, html::FORMATTED, NULL, "%d", i >= 0 ? c : -c );
333  stats_string( span_string, total ? 100.0f * float(table[i]) / float(total) : 0.0f, max_perc );
334  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, span_string );
335  }
336  }
337 }
338 
339 template <uint32 XX>
341  FILE* html_output,
342  const char* stat_by,
343  const char* name,
344  const Bins bin_type,
345  const Histogram<XX>& stats_l,
346  const Histogram<XX>& stats_r,
347  const uint32 l_count,
348  const uint32 r_count)
349 {
350  //
351  // table stats
352  //
353 
354  const int2 row_range_l = display_range( stats_l, l_count );
355  const int2 row_range_r = display_range( stats_r, r_count );
356  const int2 row_range = make_int2( nvbio::min( row_range_l.x, row_range_r.x ),
357  nvbio::max( row_range_l.y, row_range_r.y ) );
358 
359  // compute best 2 entries
360  int32 best_bin[2] = { 0, 1 };
361  int32 worst_bin[2] = { 0, 1 };
362 
363  find_gt2( row_range.x, row_range.y, stats_l, best_bin );
364  find_gt2( row_range.x, row_range.y, stats_r, worst_bin );
365 
366  // write table
367  {
368  char buffer1[1024];
369  char buffer2[1024];
370  sprintf( buffer1, "%s-stats", name );
371  sprintf( buffer2, "%s [%s] stats", name, stat_by );
372  html::table_object tab( html_output, buffer1, "stats", buffer2 );
373  {
374  html::tr_object tr( html_output, NULL );
375  html::th_object( html_output, html::FORMATTED, NULL, "bin" );
376  html::th_object( html_output, html::FORMATTED, NULL, "[L]" );
377  html::th_object( html_output, html::FORMATTED, NULL, "[R]" );
378  }
379 
380  char span_string[1024];
381  const float max_perc = 70.0f;
382  for (int32 i = row_range.x; i <= row_range.y; ++i)
383  {
384  html::tr_object tr( html_output, "class", i % 2 ? "none" : "alt", NULL );
385 
386  const int32 c = bin_type == LOG ? log_bin_range(i >= 0 ? i : -i) : i >= 0 ? i : -i;
387 
388  const char* cls_l = (i == best_bin[0]) ? "yellow" :
389  (i == best_bin[1]) ? "orange" :
390  "none";
391  const char* cls_r = (i == worst_bin[0]) ? "red" :
392  (i == worst_bin[1]) ? "orange" :
393  "pink";
394 
395  html::th_object( html_output, html::FORMATTED, NULL, "%d", i >= 0 ? c : -c );
396  stats_string( span_string, l_count ? 100.0f * float(stats_l[i]) / float(l_count) : 0.0f, max_perc );
397  html::td_object( html_output, html::FORMATTED, "class", cls_l, NULL, span_string );
398  stats_string( span_string, r_count ? 100.0f * float(stats_r[i]) / float(r_count) : 0.0f, max_perc );
399  html::td_object( html_output, html::FORMATTED, "class", cls_r, NULL, span_string );
400  }
401  }
402 }
403 
404 template <uint32 XX, uint32 YY>
406  FILE* html_output,
407  const char* stat_by,
408  const char* name,
409  const Histogram2d<XX,YY>& stats_l,
410  const Histogram2d<XX,YY>& stats_r,
411  const char* bin_name,
412  const std::vector<std::string>& X_bins,
413  const std::vector<std::string>& Y_bins,
414  const uint32 total,
415  const uint32 n_mapped_both,
416  const bool diff_table)
417 {
418  const int32 X = int32(XX);
419  const int32 Y = int32(YY);
420 
421  //
422  // table stats
423  //
424  {
425  char buffer1[1024];
426  char buffer2[1024];
427  sprintf( buffer1, "%s-stats-%s", name, bin_name );
428  sprintf( buffer2, "%s [%s] stats by %s", name, stat_by, bin_name );
429 
430  // determine the first and last columns
431  int32 first_col = 0;
432  int32 last_col = 0;
433  if (diff_table)
434  {
435  first_col = 0;
436  last_col = Y-1;
437  }
438  else
439  {
440  for (int32 i = -X+1; i < X; ++i)
441  {
442  for (int32 j = 0; j > -Y; --j)
443  {
444  if (stats_l(i,j) > 0 ||
445  stats_r(i,j) > 0)
446  first_col = j;
447  }
448  for (int32 j = 0; j < Y; ++j)
449  {
450  if (stats_l(i,j) > 0 ||
451  stats_r(i,j) > 0)
452  last_col = j;
453  }
454  }
455  }
456 
457  // determine the first and last row
458  int32 first_row = 0;
459  for (int32 i = 0; i > -X; --i)
460  {
461  for (int32 j = last_col; j >= first_col; --j)
462  {
463  if (stats_l(i,j) > 0 ||
464  stats_r(i,j) > 0)
465  first_row = i;
466  }
467  }
468  int32 last_row = 0;
469  for (int32 i = 0; i < X; ++i)
470  {
471  for (int32 j = last_col; j >= first_col; --j)
472  {
473  if (stats_l(i,j) > 0 ||
474  stats_r(i,j) > 0)
475  last_row = i;
476  }
477  }
478 
479  // compute best 2 entries
480  int2 best_bin[2] = { make_int2(0,0) };
481  uint32 best_bin_val[2] = { 0 };
482 
483  for (int32 i = first_row; i <= last_row; ++i)
484  {
485  for (int32 j = first_col; j <= last_col; ++j)
486  {
487  if (best_bin_val[0] < stats_l(i,j))
488  {
489  best_bin_val[1] = best_bin_val[0];
490  best_bin[1] = best_bin[0];
491  best_bin_val[0] = stats_l(i,j);
492  best_bin[0] = make_int2(i,j);
493  }
494  else if (best_bin_val[1] < stats_l(i,j))
495  {
496  best_bin_val[1] = stats_l(i,j);
497  best_bin[1] = make_int2(i,j);
498  }
499  }
500  }
501 
502  // compute worst 2 entries
503  int2 worst_bin[2] = { make_int2(0,0) };
504  uint32 worst_bin_val[2] = { 0 };
505 
506  for (int32 i = first_row; i <= last_row; ++i)
507  {
508  for (int32 j = (diff_table ? 1 : first_col); j <= last_col; ++j)
509  {
510  if (worst_bin_val[0] < stats_r(i,j))
511  {
512  worst_bin_val[1] = worst_bin_val[0];
513  worst_bin[1] = worst_bin[0];
514  worst_bin_val[0] = stats_r(i,j);
515  worst_bin[0] = make_int2(i,j);
516  }
517  else if (worst_bin_val[1] < stats_l(i,j))
518  {
519  worst_bin_val[1] = stats_r(i,j);
520  worst_bin[1] = make_int2(i,j);
521  }
522  }
523  }
524 
525  html::table_object table( html_output, buffer1, "stats", buffer2 );
526  {
527  html::tr_object tr( html_output, NULL );
528  html::th_object( html_output, html::FORMATTED, NULL, "" );
529  for (int32 j = last_col; j >= (diff_table ? 1 : first_col); --j)
530  html::th_object( html_output, html::FORMATTED, NULL, "%s%s", j >= 0 ? "" : "-", Y_bins[j >= 0 ? j : -j].c_str() );
531 
532  for (int32 j = first_col; j <= last_col; ++j)
533  html::th_object( html_output, html::FORMATTED, NULL, "%s%s", j >= 0 ? "" : "-", Y_bins[j >= 0 ? j : -j].c_str() );
534 
535  html::th_object( html_output, html::FORMATTED, NULL, "%s", name );
536  }
537 
538  for (int32 i = first_row; i <= last_row; ++i)
539  {
540  html::tr_object tr( html_output, "class", i % 2 ? "none" : "alt", NULL );
541  html::th_object( html_output, html::FORMATTED, NULL, "%s%s", i >= 0 ? "" : "-", X_bins[i >= 0 ? i : -i].c_str() );
542 
543  for (int32 j = last_col; j >= (diff_table ? 1 : first_col); --j)
544  {
545  const float sval = 100.0f * float(stats_r(i,j))/float(n_mapped_both);
546  if (sval >= 0.1f)
547  {
548  const char* cls = (i == worst_bin[0].x && j == worst_bin[0].y) ? "red" :
549  (i == worst_bin[1].x && j == worst_bin[1].y) ? "orange" :
550  "pink";
551  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, "%.1f %%", sval );
552  }
553  else if (sval >= 0.01f)
554  html::td_object( html_output, html::FORMATTED, "class", "smallpink", NULL, "%.2f %%", sval );
555  else
556  {
557  const char* cls = sval == 0.0f ? "gray" : "pink";
558  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, "-" );
559  }
560  }
561  for (int32 j = first_col; j <= last_col; ++j)
562  {
563  const float sval = 100.0f * float(stats_l(i,j))/float(n_mapped_both);
564  if (sval >= 0.1f)
565  {
566  const char* cls = (i == best_bin[0].x && j == best_bin[0].y) ? "yellow" :
567  (i == best_bin[1].x && j == best_bin[1].y) ? "orange" :
568  "none";
569  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, "%.1f %%", sval );
570  }
571  else if (sval >= 0.01f)
572  html::td_object( html_output, html::FORMATTED, "class", "small", NULL, "%.2f %%", sval );
573  else
574  {
575  const char* cls = sval == 0.0f ? "gray" : "none";
576  html::td_object( html_output, html::FORMATTED, "class", cls, NULL, "-" );
577  }
578  }
579  html::td_object( html_output, html::FORMATTED, "class", "gray", NULL, "" );
580  }
581  {
582  html::tr_object tr( html_output, NULL );
583  html::th_object( html_output, html::FORMATTED, NULL, "%s", bin_name );
584  for (int32 i = last_col; i >= (diff_table ? 1 : first_col); --i)
585  html::td_object( html_output, html::FORMATTED, "class", "gray", NULL, "" );
586  for (int32 i = first_col; i <= last_col; ++i)
587  html::td_object( html_output, html::FORMATTED, "class", "gray", NULL, "" );
588  html::td_object( html_output, html::FORMATTED, "class", "gray", NULL, "" );
589  }
590  }
591 }
592 
593 inline
594 void generate_table(const char* file_name,
595  const char* stat_by,
596  const char* name,
597  const char* diff_name,
598  const Bins bin_type,
599  const StatsPartition& stats_l,
600  const StatsPartition& stats_r,
601  const uint32 total,
602  const uint32 n_mapped_both,
603  const bool absolute_values = true)
604 {
605  FILE* html_output = fopen( file_name, "w" );
606  if (html_output == NULL)
607  {
608  log_warning( stderr, "unable to write HTML report \"%s\"\n", file_name );
609  return;
610  }
611 
612  std::vector<std::string> read_bins;
613  read_bins.push_back( "0" );
614  for (uint32 x = 0; x < 12; ++x)
615  {
616  char buffer[16];
617  sprintf(buffer, "%d", read_length_bin_range(x));
618  read_bins.push_back( buffer );
619  }
620 
621  std::vector<std::string> log_bins;
622  for (uint32 y = 0; y < 32; ++y)
623  {
624  if (y == 0)
625  log_bins.push_back( "0" );
626  else if (y == 1)
627  log_bins.push_back( "1" );
628  else if (y == 2)
629  log_bins.push_back( "2" );
630  else
631  {
632  char buffer[16];
633  sprintf(buffer, "2^%u", y-1);
634  log_bins.push_back( buffer );
635  }
636  }
637 
638  {
639  html::html_object html( html_output );
640  {
641  const char* meta_list = "<meta http-equiv=\"refresh\" content=\"5\" />";
642 
643  html::header_object hd( html_output, "nv-aln-diff report", html::style(), meta_list );
644  {
645  html::body_object body( html_output );
646 
647  generate_diff_table( html_output,
648  stat_by,
649  diff_name,
650  bin_type,
651  stats_l.diff_hist,
652  stats_r.diff_hist,
653  total,
654  n_mapped_both );
655 
656  generate_table2d( html_output,
657  stat_by,
658  diff_name,
659  stats_l.diff_hist_by_length,
660  stats_r.diff_hist_by_length,
661  "read length",
662  read_bins,
663  log_bins,
664  total,
665  n_mapped_both,
666  true );
667 
668  generate_table2d( html_output,
669  stat_by,
670  diff_name,
671  stats_l.diff_hist_by_value_pos,
672  stats_r.diff_hist_by_value_pos,
673  "best value",
674  log_bins,
675  log_bins,
676  total,
677  n_mapped_both,
678  true );
679 
680  generate_table2d( html_output,
681  stat_by,
682  diff_name,
683  stats_l.diff_hist_by_mapQ1,
684  stats_r.diff_hist_by_mapQ1,
685  "mapQ [L]",
686  log_bins,
687  log_bins,
688  total,
689  n_mapped_both,
690  true );
691 
692  generate_table2d( html_output,
693  stat_by,
694  diff_name,
695  stats_l.diff_hist_by_mapQ2,
696  stats_r.diff_hist_by_mapQ2,
697  "mapQ [R]",
698  log_bins,
699  log_bins,
700  total,
701  n_mapped_both,
702  true );
703 
704  if (absolute_values)
705  {
706  generate_table( html_output,
707  stat_by,
708  name,
709  bin_type,
710  stats_l.hist,
711  stats_r.hist,
712  stats_l.hist.count,
713  stats_r.hist.count );
714 
715  generate_table2d( html_output,
716  stat_by,
717  name,
718  stats_l.hist_by_length,
719  stats_r.hist_by_length,
720  "read length",
721  read_bins,
722  log_bins,
723  total,
724  n_mapped_both,
725  false );
726 
727  generate_table2d( html_output,
728  stat_by,
729  name,
730  stats_l.hist_by_mapQ,
731  stats_r.hist_by_mapQ,
732  "mapQ",
733  log_bins,
734  log_bins,
735  total,
736  n_mapped_both,
737  false );
738  }
739  }
740  }
741  }
742  fclose( html_output );
743 }
744 
745 } // namespace alndiff
746 } // namespace nvbio