html.h 30 KB

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