nvbio-aln-diff.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  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. #include <nvbio-aln-diff/se_analyzer.h>
  28. #include <nvbio-aln-diff/pe_analyzer.h>
  29. #include <nvbio-aln-diff/alignment.h>
  30. #include <nvbio-aln-diff/utils.h>
  31. #include <nvbio/basic/types.h>
  32. #include <nvbio/basic/console.h>
  33. #include <nvbio/basic/html.h>
  34. #include <nvbio/basic/shared_pointer.h>
  35. #include <cuda_runtime_api.h>
  36. #include <vector_types.h>
  37. #include <vector_functions.h>
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <vector>
  42. #include <string>
  43. void crcInit();
  44. using namespace nvbio;
  45. using namespace alndiff;
  46. int main(int argc, char* argv[])
  47. {
  48. crcInit();
  49. int cuda_device = -1;
  50. int device_count;
  51. cudaGetDeviceCount(&device_count);
  52. log_verbose(stderr, " cuda devices : %d\n", device_count);
  53. const char* report_name = NULL;
  54. const char* filter_name = NULL;
  55. uint32 filter_flags = Filter::ALL;
  56. uint32 filter_stats = Filter::ALL;
  57. int32 filter_delta = 5;
  58. bool paired = false;
  59. bool id_check = true;
  60. int arg = 1;
  61. while (arg < argc)
  62. {
  63. if (strcmp( argv[arg], "-device" ) == 0)
  64. {
  65. cuda_device = atoi(argv[++arg]);
  66. ++arg;
  67. }
  68. else if (strcmp( argv[arg], "-paired" ) == 0)
  69. {
  70. paired = true;
  71. ++arg;
  72. }
  73. else if (strcmp( argv[arg], "-report" ) == 0)
  74. {
  75. report_name = argv[++arg];
  76. ++arg;
  77. }
  78. else if (strcmp( argv[arg], "-no-ids" ) == 0)
  79. {
  80. id_check = false;
  81. ++arg;
  82. }
  83. else if (strcmp( argv[arg], "-filter" ) == 0)
  84. {
  85. filter_name = argv[++arg];
  86. const std::string flags_string( argv[++arg] );
  87. const std::string stats_string( argv[++arg] );
  88. filter_delta = atoi(argv[++arg]);
  89. ++arg;
  90. char temp[256];
  91. // parse the filter flags
  92. const char* begin = flags_string.c_str();
  93. const char* end = begin;
  94. filter_flags = 0u;
  95. while (1)
  96. {
  97. while (*end != '|' && *end != '\0')
  98. {
  99. temp[end - begin] = *end;
  100. end++;
  101. }
  102. temp[end - begin] = '\0';
  103. if (strcmp( temp, "distant" ) == 0)
  104. filter_flags |= Filter::DISTANT;
  105. else if (strcmp( temp, "discordant" ) == 0)
  106. filter_flags |= Filter::DISCORDANT;
  107. else if (strcmp( temp, "diff-ref" ) == 0)
  108. filter_flags |= Filter::DIFFERENT_REF;
  109. if (*end == '\0')
  110. break;
  111. ++end; begin = end;
  112. }
  113. // parse the filter stats
  114. begin = stats_string.c_str();
  115. end = begin;
  116. filter_stats = 0u;
  117. while (1)
  118. {
  119. while (*end != '|' && *end != '\0')
  120. {
  121. temp[end - begin] = *end;
  122. end++;
  123. }
  124. temp[end - begin] = '\0';
  125. if (strcmp( temp, "ed" ) == 0)
  126. filter_stats |= Filter::ED;
  127. else if (strcmp( temp, "mapQ" ) == 0)
  128. filter_stats |= Filter::MAPQ;
  129. else if (strcmp( temp, "mms" ) == 0)
  130. filter_stats |= Filter::MMS;
  131. else if (strcmp( temp, "ins" ) == 0)
  132. filter_stats |= Filter::INS;
  133. else if (strcmp( temp, "dels" ) == 0)
  134. filter_stats |= Filter::DELS;
  135. if (*end == '\0')
  136. break;
  137. ++end; begin = end;
  138. }
  139. }
  140. else
  141. break;
  142. }
  143. // inspect and select cuda devices
  144. if (device_count)
  145. {
  146. if (cuda_device == -1)
  147. {
  148. int best_device = 0;
  149. cudaDeviceProp best_device_prop;
  150. cudaGetDeviceProperties( &best_device_prop, best_device );
  151. for (int device = 0; device < device_count; ++device)
  152. {
  153. cudaDeviceProp device_prop;
  154. cudaGetDeviceProperties( &device_prop, device );
  155. log_verbose(stderr, " device %d has compute capability %d.%d\n", device, device_prop.major, device_prop.minor);
  156. log_verbose(stderr, " SM count : %u\n", device_prop.multiProcessorCount);
  157. log_verbose(stderr, " SM clock rate : %u Mhz\n", device_prop.clockRate / 1000);
  158. log_verbose(stderr, " memory clock rate : %.1f Ghz\n", float(device_prop.memoryClockRate) * 1.0e-6f);
  159. if (device_prop.major >= best_device_prop.major &&
  160. device_prop.minor >= best_device_prop.minor)
  161. {
  162. best_device_prop = device_prop;
  163. best_device = device;
  164. }
  165. }
  166. cuda_device = best_device;
  167. }
  168. log_verbose(stderr, " chosen device %d\n", cuda_device);
  169. {
  170. cudaDeviceProp device_prop;
  171. cudaGetDeviceProperties( &device_prop, cuda_device );
  172. log_verbose(stderr, " device name : %s\n", device_prop.name);
  173. log_verbose(stderr, " compute capability : %d.%d\n", device_prop.major, device_prop.minor);
  174. }
  175. cudaSetDevice( cuda_device );
  176. }
  177. if (argc < arg + 2)
  178. {
  179. log_info(stderr, "nvbio-aln-diff [OPTIONS] <file1> <file2>\n");
  180. log_info(stderr, "OPTIONS:\n");
  181. log_info(stderr, " -paired # paired-end input\n" );
  182. log_info(stderr, " -no-ids # do not perform id checks\n" );
  183. log_info(stderr, " -report <file-name> # HTML report\n" );
  184. log_info(stderr, " -filter <file-name>\n" );
  185. log_info(stderr, " <flags={distant|discordant|diff-ref}>\n" );
  186. log_info(stderr, " <stats={ed|mapQ|mms|ins|dels}>\n" );
  187. log_info(stderr, " int:delta\n" );
  188. return 0;
  189. }
  190. if (filter_name)
  191. {
  192. std::string filter_flags_string;
  193. if (filter_flags & Filter::DISTANT)
  194. filter_flags_string += std::string(filter_flags_string.length() ? "|" : "") + "distant";
  195. if (filter_flags & Filter::DISCORDANT)
  196. filter_flags_string += std::string(filter_flags_string.length() ? "|" : "") + "discordant";
  197. if (filter_flags & Filter::DIFFERENT_REF)
  198. filter_flags_string += std::string(filter_flags_string.length() ? "|" : "") + "diff-ref";
  199. std::string filter_stats_string;
  200. if (filter_stats & Filter::ED)
  201. filter_stats_string += std::string(filter_stats_string.length() ? "|" : "") + "ed";
  202. if (filter_stats & Filter::MAPQ)
  203. filter_stats_string += std::string(filter_stats_string.length() ? "|" : "") + "mapQ";
  204. if (filter_stats & Filter::MMS)
  205. filter_stats_string += std::string(filter_stats_string.length() ? "|" : "") + "mms";
  206. if (filter_stats & Filter::INS)
  207. filter_stats_string += std::string(filter_stats_string.length() ? "|" : "") + "ins";
  208. if (filter_stats & Filter::DELS)
  209. filter_stats_string += std::string(filter_stats_string.length() ? "|" : "") + "dels";
  210. log_info(stderr, "filter file : %s\n", filter_name);
  211. log_info(stderr, " flags : %s\n", filter_flags_string.c_str());
  212. log_info(stderr, " stats : %s\n", filter_stats_string.c_str());
  213. log_info(stderr, " delta : %d\n", filter_delta);
  214. }
  215. if (argc == arg + 2)
  216. {
  217. const char *aln_file_nameL = argv[arg];
  218. const char *aln_file_nameR = argv[arg+1];
  219. if (paired)
  220. {
  221. const char *aln_file_nameL = argv[arg];
  222. const char *aln_file_nameR = argv[arg+1];
  223. SharedPointer<AlignmentStream> aln_streamL = SharedPointer<AlignmentStream>( open_alignment_file( aln_file_nameL ) );
  224. SharedPointer<AlignmentStream> aln_streamR = SharedPointer<AlignmentStream>( open_alignment_file( aln_file_nameR ) );
  225. if (aln_streamL == NULL || aln_streamL->is_ok() == false) { log_error(stderr, "failed opening \"%s\"\n", aln_file_nameL); exit(1); }
  226. if (aln_streamR == NULL || aln_streamR->is_ok() == false) { log_error(stderr, "failed opening \"%s\"\n", aln_file_nameR); exit(1); }
  227. const uint32 BATCH_SIZE = 500000;
  228. std::vector<Alignment> batchL( BATCH_SIZE );
  229. std::vector<Alignment> batchR( BATCH_SIZE );
  230. Filter filter( filter_name, filter_flags, filter_stats, filter_delta );
  231. SharedPointer<PEAnalyzer> analyzer = SharedPointer<PEAnalyzer>( new PEAnalyzer( filter, id_check ) );
  232. uint32 n_batch = 0;
  233. while (1)
  234. {
  235. const uint32 batch_sizeL = aln_streamL->next_batch( BATCH_SIZE, &batchL[0] );
  236. const uint32 batch_sizeR = aln_streamR->next_batch( BATCH_SIZE, &batchR[0] );
  237. const uint32 min_batch_size = nvbio::min( batch_sizeL, batch_sizeR );
  238. const uint32 max_batch_size = nvbio::max( batch_sizeL, batch_sizeR );
  239. if (min_batch_size != max_batch_size)
  240. log_warning(stderr, "alignment files have different size\n");
  241. log_info(stderr, "analizing batch[%u]: %u alignments (%.1f M)\n", n_batch, min_batch_size, float(n_batch * BATCH_SIZE + min_batch_size)*1.0e-6f);
  242. for (uint32 i = 0; i < min_batch_size; i += 2)
  243. {
  244. const Alignment* alnL1 = &batchL[i];
  245. const Alignment* alnL2 = &batchL[i+1];
  246. const Alignment* alnR1 = &batchR[i];
  247. const Alignment* alnR2 = &batchR[i+1];
  248. if (alnL1->is_mapped() && alnL1->mate == alnL2->mate)
  249. {
  250. log_error(stderr, "alignments %u and %u in \"%s\" refer to the same mate, must come from different reads\n", i, i+1, aln_file_nameL);
  251. return 1;
  252. }
  253. if (alnR1->is_mapped() && alnR1->mate == alnR2->mate)
  254. {
  255. log_error(stderr, "alignments %u and %u in \"%s\" refer to the same mate, must come from different reads\n", i, i+1, aln_file_nameR);
  256. return 1;
  257. }
  258. if (alnL1->mate) std::swap( alnL1, alnL2 );
  259. if (alnR1->mate) std::swap( alnR1, alnR2 );
  260. analyzer->push(
  261. AlignmentPair( *alnL1, *alnL2 ),
  262. AlignmentPair( *alnR1, *alnR2 ));
  263. }
  264. if (report_name)
  265. analyzer->generate_report( aln_file_nameL, aln_file_nameR, report_name );
  266. analyzer->flush();
  267. log_verbose(stderr, " mismatched : %5.2f%%\n", 100.0f * analyzer->mismatched());
  268. log_verbose(stderr, " mapped [L] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L());
  269. log_verbose(stderr, " mapped [R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_R());
  270. log_verbose(stderr, " mapped [L&R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L_and_R());
  271. log_verbose(stderr, " mapped/unmapped [L] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L_not_R());
  272. log_verbose(stderr, " mapped/unmapped [R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_R_not_L());
  273. log_verbose(stderr, " paired [L] : %5.2f%%\n", 100.0f * analyzer->paired.avg_L());
  274. log_verbose(stderr, " paired [R] : %5.2f%%\n", 100.0f * analyzer->paired.avg_R());
  275. log_verbose(stderr, " paired [L&R] : %5.2f%%\n", 100.0f * analyzer->paired.avg_L_and_R());
  276. log_verbose(stderr, " paired/unpaired [L] : %5.2f%%\n", 100.0f * analyzer->paired.avg_L_not_R());
  277. log_verbose(stderr, " paired/unpaired [R] : %5.2f%%\n", 100.0f * analyzer->paired.avg_R_not_L());
  278. log_verbose(stderr, " different ref : %5.2f%%\n", 100.0f * analyzer->different_ref());
  279. log_verbose(stderr, " distant : %5.2f%%\n", 100.0f * analyzer->distant());
  280. log_verbose(stderr, " discordant : %5.2f%%\n", 100.0f * analyzer->discordant());
  281. log_verbose(stderr, " filtered : %u\n", analyzer->filtered());
  282. if (min_batch_size < BATCH_SIZE)
  283. break;
  284. ++n_batch;
  285. }
  286. }
  287. else
  288. {
  289. SharedPointer<AlignmentStream> aln_streamL = SharedPointer<AlignmentStream>( open_alignment_file( aln_file_nameL ) );
  290. SharedPointer<AlignmentStream> aln_streamR = SharedPointer<AlignmentStream>( open_alignment_file( aln_file_nameR ) );
  291. if (aln_streamL == NULL || aln_streamL->is_ok() == false) { log_error(stderr, "failed opening \"%s\"\n", aln_file_nameL); exit(1); }
  292. if (aln_streamR == NULL || aln_streamR->is_ok() == false) { log_error(stderr, "failed opening \"%s\"\n", aln_file_nameR); exit(1); }
  293. const uint32 BATCH_SIZE = 500000;
  294. std::vector<Alignment> batchL( BATCH_SIZE );
  295. std::vector<Alignment> batchR( BATCH_SIZE );
  296. Filter filter( filter_name, filter_flags, filter_stats, filter_delta );
  297. SharedPointer<SEAnalyzer> analyzer = SharedPointer<SEAnalyzer>( new SEAnalyzer( filter ) );
  298. uint32 n_batch = 0;
  299. while (1)
  300. {
  301. const uint32 batch_sizeL = aln_streamL->next_batch( BATCH_SIZE, &batchL[0] );
  302. const uint32 batch_sizeR = aln_streamR->next_batch( BATCH_SIZE, &batchR[0] );
  303. if (batch_sizeL != batch_sizeR)
  304. log_warning(stderr, "alignment files have different size\n");
  305. const uint32 min_batch_size = nvbio::min( batch_sizeL, batch_sizeR );
  306. log_info(stderr, "analizing batch[%u]: %u alignments (%.1f M)\n", n_batch, min_batch_size, float(n_batch * BATCH_SIZE + min_batch_size)*1.0e-6f);
  307. for (uint32 i = 0; i < min_batch_size; ++i)
  308. analyzer->push( batchL[i], batchR[i] );
  309. if (report_name)
  310. analyzer->generate_report( aln_file_nameL, aln_file_nameR, report_name );
  311. analyzer->flush();
  312. log_verbose(stderr, " mismatched : %5.2f%%\n", 100.0f * analyzer->mismatched());
  313. log_verbose(stderr, " mapped [L] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L());
  314. log_verbose(stderr, " mapped [R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_R());
  315. log_verbose(stderr, " mapped [L&R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L_and_R());
  316. log_verbose(stderr, " mapped/unmapped [L] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L_not_R());
  317. log_verbose(stderr, " mapped/unmapped [R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_R_not_L());
  318. log_verbose(stderr, " different ref : %5.2f%%\n", 100.0f * analyzer->different_ref());
  319. log_verbose(stderr, " distant : %5.2f%%\n", 100.0f * analyzer->distant());
  320. log_verbose(stderr, " discordant : %5.2f%%\n", 100.0f * analyzer->discordant());
  321. log_verbose(stderr, " filtered : %u\n", analyzer->filtered());
  322. if (min_batch_size < BATCH_SIZE)
  323. break;
  324. ++n_batch;
  325. }
  326. }
  327. }
  328. else if (argc == arg + 4)
  329. {
  330. const char *aln_file_nameL1 = argv[arg];
  331. const char *aln_file_nameL2 = argv[arg+1];
  332. const char *aln_file_nameR1 = argv[arg+2];
  333. const char *aln_file_nameR2 = argv[arg+3];
  334. const char* aln_file_nameL = aln_file_nameL1;
  335. const char* aln_file_nameR = aln_file_nameR1;
  336. SharedPointer<AlignmentStream> aln_streamL1 = SharedPointer<AlignmentStream>( open_alignment_file( aln_file_nameL1 ) );
  337. SharedPointer<AlignmentStream> aln_streamL2 = SharedPointer<AlignmentStream>( open_alignment_file( aln_file_nameL2 ) );
  338. SharedPointer<AlignmentStream> aln_streamR1 = SharedPointer<AlignmentStream>( open_alignment_file( aln_file_nameR1 ) );
  339. SharedPointer<AlignmentStream> aln_streamR2 = SharedPointer<AlignmentStream>( open_alignment_file( aln_file_nameR2 ) );
  340. if (aln_streamL1 == NULL || aln_streamL1->is_ok() == false) { log_error(stderr, "failed opening \"%s\"\n", aln_file_nameL1); exit(1); }
  341. if (aln_streamL2 == NULL || aln_streamL2->is_ok() == false) { log_error(stderr, "failed opening \"%s\"\n", aln_file_nameL2); exit(1); }
  342. if (aln_streamR2 == NULL || aln_streamR1->is_ok() == false) { log_error(stderr, "failed opening \"%s\"\n", aln_file_nameR1); exit(1); }
  343. if (aln_streamR2 == NULL || aln_streamR2->is_ok() == false) { log_error(stderr, "failed opening \"%s\"\n", aln_file_nameR2); exit(1); }
  344. const uint32 BATCH_SIZE = 500000;
  345. std::vector<Alignment> batchL1( BATCH_SIZE );
  346. std::vector<Alignment> batchL2( BATCH_SIZE );
  347. std::vector<Alignment> batchR1( BATCH_SIZE );
  348. std::vector<Alignment> batchR2( BATCH_SIZE );
  349. Filter filter( filter_name, filter_flags, filter_stats, filter_delta );
  350. SharedPointer<PEAnalyzer> analyzer = SharedPointer<PEAnalyzer>( new PEAnalyzer( filter, id_check ) );
  351. uint32 n_batch = 0;
  352. while (1)
  353. {
  354. const uint32 batch_sizeL1 = aln_streamL1->next_batch( BATCH_SIZE, &batchL1[0] );
  355. const uint32 batch_sizeL2 = aln_streamL2->next_batch( BATCH_SIZE, &batchL2[0] );
  356. const uint32 batch_sizeR1 = aln_streamR1->next_batch( BATCH_SIZE, &batchR1[0] );
  357. const uint32 batch_sizeR2 = aln_streamR2->next_batch( BATCH_SIZE, &batchR2[0] );
  358. const uint32 min_batch_size = nvbio::min(
  359. nvbio::min( batch_sizeL1, batch_sizeL2 ),
  360. nvbio::min( batch_sizeR1, batch_sizeR2 ) );
  361. const uint32 max_batch_size = nvbio::min(
  362. nvbio::max( batch_sizeL1, batch_sizeL2 ),
  363. nvbio::max( batch_sizeR1, batch_sizeR2 ) );
  364. if (min_batch_size != max_batch_size)
  365. log_warning(stderr, "alignment files have different size\n");
  366. log_info(stderr, "analizing batch[%u]: %u alignments (%.1f M)\n", n_batch, min_batch_size, float(n_batch * BATCH_SIZE + min_batch_size)*1.0e-6f);
  367. for (uint32 i = 0; i < min_batch_size; ++i)
  368. analyzer->push(
  369. AlignmentPair( batchL1[i], batchL2[i] ),
  370. AlignmentPair( batchR1[i], batchR2[i] ));
  371. if (report_name)
  372. analyzer->generate_report( aln_file_nameL, aln_file_nameR, report_name );
  373. analyzer->flush();
  374. log_verbose(stderr, " mismatched : %5.2f%%\n", 100.0f * analyzer->mismatched());
  375. log_verbose(stderr, " mapped [L] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L());
  376. log_verbose(stderr, " mapped [R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_R());
  377. log_verbose(stderr, " mapped [L&R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L_and_R());
  378. log_verbose(stderr, " mapped/unmapped [L] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_L_not_R());
  379. log_verbose(stderr, " mapped/unmapped [R] : %5.2f%%\n", 100.0f * analyzer->mapped.avg_R_not_L());
  380. log_verbose(stderr, " paired [L] : %5.2f%%\n", 100.0f * analyzer->paired.avg_L());
  381. log_verbose(stderr, " paired [R] : %5.2f%%\n", 100.0f * analyzer->paired.avg_R());
  382. log_verbose(stderr, " paired [L&R] : %5.2f%%\n", 100.0f * analyzer->paired.avg_L_and_R());
  383. log_verbose(stderr, " paired/unpaired [L] : %5.2f%%\n", 100.0f * analyzer->paired.avg_L_not_R());
  384. log_verbose(stderr, " paired/unpaired [R] : %5.2f%%\n", 100.0f * analyzer->paired.avg_R_not_L());
  385. log_verbose(stderr, " different ref : %5.2f%%\n", 100.0f * analyzer->different_ref());
  386. log_verbose(stderr, " distant : %5.2f%%\n", 100.0f * analyzer->distant());
  387. log_verbose(stderr, " discordant : %5.2f%%\n", 100.0f * analyzer->discordant());
  388. log_verbose(stderr, " filtered : %u\n", analyzer->filtered());
  389. if (min_batch_size < BATCH_SIZE)
  390. break;
  391. ++n_batch;
  392. }
  393. }
  394. cudaDeviceReset();
  395. return 0;
  396. }