@@ -271,8 +271,11 @@ namespace torali
271271 // Parse genome, process chromosome by chromosome
272272 boost::posix_time::ptime now = boost::posix_time::second_clock::local_time ();
273273 std::cerr << ' [' << boost::posix_time::to_simple_string (now) << " ] " << " Paired-end and split-read scanning" << std::endl;
274+
275+ // Multi-threading
276+ ThreadPool pool (std::max<std::size_t >(1 , c.maxThreads ));
277+
274278 // Iterate all samples
275- #pragma omp parallel for default(shared)
276279 for (unsigned int file_c = 0 ; file_c < c.files .size (); ++file_c) {
277280 // Inter-chromosomal mate map and alignment length
278281 typedef std::pair<uint8_t , int32_t > TQualLen;
@@ -399,11 +402,7 @@ namespace torali
399402 alenmate = p.second ;
400403 mateMap[hv].first = 0 ;
401404 }
402-
403- #pragma omp critical
404- {
405- bamRecord[svt].push_back (BamAlignRecord (rec, pairQuality, alignmentLength (rec), alenmate, sampleLib[file_c].median , sampleLib[file_c].mad , sampleLib[file_c].maxNormalISize ));
406- }
405+ bamRecord[svt].push_back (BamAlignRecord (rec, pairQuality, alignmentLength (rec), alenmate, sampleLib[file_c].median , sampleLib[file_c].mad , sampleLib[file_c].maxNormalISize ));
407406 ++sampleLib[file_c].abnormal_pairs ;
408407 }
409408 }
@@ -417,14 +416,11 @@ namespace torali
417416 for (typename TReadBp::iterator it = readBp.begin (); it != readBp.end (); ++it) std::sort (it->second .begin (), it->second .end ());
418417
419418 // Collect split-read SVs
420- #pragma omp critical
421- {
422- if ((c.svtset .empty ()) || (c.svtset .find (2 ) != c.svtset .end ())) selectDeletions (c, readBp, srBR);
423- if ((c.svtset .empty ()) || (c.svtset .find (3 ) != c.svtset .end ())) selectDuplications (c, readBp, srBR);
424- if ((c.svtset .empty ()) || (c.svtset .find (0 ) != c.svtset .end ()) || (c.svtset .find (1 ) != c.svtset .end ())) selectInversions (c, readBp, srBR);
425- if ((c.svtset .empty ()) || (c.svtset .find (4 ) != c.svtset .end ())) selectInsertions (c, readBp, srBR);
426- if ((c.svtset .empty ()) || (c.svtset .find (DELLY_SVT_TRANS ) != c.svtset .end ()) || (c.svtset .find (DELLY_SVT_TRANS + 1 ) != c.svtset .end ()) || (c.svtset .find (DELLY_SVT_TRANS + 2 ) != c.svtset .end ()) || (c.svtset .find (DELLY_SVT_TRANS + 3 ) != c.svtset .end ())) selectTranslocations (c, readBp, srBR);
427- }
419+ if ((c.svtset .empty ()) || (c.svtset .find (2 ) != c.svtset .end ())) selectDeletions (c, readBp, srBR);
420+ if ((c.svtset .empty ()) || (c.svtset .find (3 ) != c.svtset .end ())) selectDuplications (c, readBp, srBR);
421+ if ((c.svtset .empty ()) || (c.svtset .find (0 ) != c.svtset .end ()) || (c.svtset .find (1 ) != c.svtset .end ())) selectInversions (c, readBp, srBR);
422+ if ((c.svtset .empty ()) || (c.svtset .find (4 ) != c.svtset .end ())) selectInsertions (c, readBp, srBR);
423+ if ((c.svtset .empty ()) || (c.svtset .find (DELLY_SVT_TRANS ) != c.svtset .end ()) || (c.svtset .find (DELLY_SVT_TRANS + 1 ) != c.svtset .end ()) || (c.svtset .find (DELLY_SVT_TRANS + 2 ) != c.svtset .end ()) || (c.svtset .find (DELLY_SVT_TRANS + 3 ) != c.svtset .end ())) selectTranslocations (c, readBp, srBR);
428424 }
429425
430426 // Debug abnormal paired-ends and split-reads
@@ -433,6 +429,8 @@ namespace torali
433429 // Cluster split-read records
434430 now = boost::posix_time::second_clock::local_time ();
435431 std::cerr << ' [' << boost::posix_time::to_simple_string (now) << " ] " << " Split-read clustering" << std::endl;
432+ std::vector<std::vector<StructuralVariantRecord>> srBySvt (srBR.size ());
433+ std::vector<std::future<void >> cluster_futures;
436434 for (uint32_t svt = 0 ; svt < srBR.size (); ++svt) {
437435 if ((!c.svtset .empty ()) && (c.svtset .find (svt) == c.svtset .end ())) continue ;
438436 if (srBR[svt].empty ()) continue ;
@@ -441,18 +439,26 @@ namespace torali
441439 std::sort (srBR[svt].begin (), srBR[svt].end ());
442440
443441 // Cluster
444- cluster (c, srBR[svt], srSVs, svt);
445-
446- // Debug SR SVs
447- // outputStructuralVariants(c, srSVs, srBR, svt, false); // Short reads
442+ cluster_futures.push_back (pool.enqueue ([&, svt]() {
443+ cluster (c, srBR[svt], srBySvt[svt], svt);
444+ }));
445+ }
446+ // Wait and merge
447+ for (auto &f : cluster_futures) f.get ();
448+ for (auto &vec : srBySvt) {
449+ if (!vec.empty ()) {
450+ srSVs.insert (srSVs.end (), std::make_move_iterator (vec.begin ()), std::make_move_iterator (vec.end ()));
451+ }
448452 }
449453
450454 // Cluster paired-end records
451455 now = boost::posix_time::second_clock::local_time ();
452456 std::cerr << ' [' << boost::posix_time::to_simple_string (now) << " ] " << " Paired-end clustering" << std::endl;
453457
454458 // Maximum variability in insert size
455- int32_t varisize = getVariability (c, sampleLib);
459+ int32_t varisize = getVariability (c, sampleLib);
460+ std::vector<std::vector<StructuralVariantRecord>> peBySvt (srBR.size ());
461+ std::vector<std::future<void >> pe_cluster_futures;
456462 for (int32_t svt = 0 ; svt < (int32_t ) bamRecord.size (); ++svt) {
457463 if ((!c.svtset .empty ()) && (c.svtset .find (svt) == c.svtset .end ())) continue ;
458464 if (bamRecord[svt].empty ()) continue ;
@@ -461,7 +467,16 @@ namespace torali
461467 std::sort (bamRecord[svt].begin (), bamRecord[svt].end ());
462468
463469 // Cluster
464- cluster (c, bamRecord[svt], svs, varisize, svt);
470+ pe_cluster_futures.push_back (pool.enqueue ([&, svt]() {
471+ cluster (c, bamRecord[svt], peBySvt[svt], varisize, svt);
472+ }));
473+ }
474+ // Wait and merge
475+ for (auto &f : pe_cluster_futures) f.get ();
476+ for (auto &vec : peBySvt) {
477+ if (!vec.empty ()) {
478+ svs.insert (svs.end (), std::make_move_iterator (vec.begin ()), std::make_move_iterator (vec.end ()));
479+ }
465480 }
466481
467482 // Track split-reads
0 commit comments