forked from azizmithani/roast
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbyRI.cpp
More file actions
1782 lines (1319 loc) · 79.2 KB
/
Copy pathbyRI.cpp
File metadata and controls
1782 lines (1319 loc) · 79.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: byRI.cpp
* Author: madiha
*
* Created on September 17, 2018, 1:53 PM
*/
#include "byRI.h"
#include "global.h"
#include "utils.h"
#include "ROAST_extendContigs.h"
#include <sstream>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <cstdlib>
#include <cctype>
#include <climits>
#include <set>
#include <math.h>
#include <map>
#include <api/BamAlignment.h>
#include <api/BamReader.h>
#include <api/BamWriter.h>
#include <boost/regex.hpp>
#include <boost/filesystem/operations.hpp>
using namespace BamTools;
using namespace std;
using namespace boost;
byRI::byRI() {
}
byRI::byRI(const byRI& orig) {
}
byRI::~byRI() {
}
bool frgaments_merged = false;
int start_overlap, end_overlap;
struct RI_data {
string read_contig;
string mate_contig;
int read_start;
int read_end;
bool strand_read; // reverse = true, forward = false
int read_count;
int mate_start; // start of first read
int mate_end; // start of last read + read length --> because we don't have end of mate
bool strand_mate; // reverse = true, forward = false //string strand_mate1;
bool flag;
};
struct merged_info {
string updated_id;
string updated_seq;
string updated_strand; // forward or RC for merging
};
int byRI::read_island(string bam_in, string in_file, string out_file, string &log, std::ofstream &log_time) {
utils utils;
RI_data ri_data;
// create bam file containing only read islands and unmapped reads at the corners
string bam_distant = path_inter + "/DISTANT.bam";
string bam_unmapped = path_inter + "/UNMAPPED.bam";
//ofstream temp_file;
//temp_file.open(tempfile.c_str());
utils.filter_sam_distant(bam_in, bam_distant);
utils.filter_sam_unmapped(bam_in, bam_unmapped);
string bam_indx_cmd = "samtools index " + bam_distant + " > /dev/null 2>&1";
std::system(bam_indx_cmd.c_str());
bam_indx_cmd = "samtools index " + bam_unmapped + " > /dev/null 2>&1";
std::system(bam_indx_cmd.c_str());
/*first extend assembly through CAP3 using unmapped reads*/
time_t begin1, end1;
time(&begin1);
set<string> merged_check;
ofstream log_cap3;
log_cap3.open(log.c_str(), ios::app);
log_cap3 << "outer iteration:" << outer_iteration << endl;
log_cap3.close();
//cout << "before cap3" << endl;
extend_unmappedBam(bam_unmapped, in_file, out_file, log);
//cout << "after cap3" << endl;
/* Extension completed*/
time(&end1);
double elapsed_secs1 = double(end1 - begin1);
log_time << "outer_iteration:" << outer_iteration << " CAP3 assembly process time:" << elapsed_secs1 << endl;
ofstream mergedRI;
mergedRI.open(out_file.c_str(), ios::app);
ofstream log_new;
log_new.open(log.c_str(), ios::app);
int read_count = 0, count = 0, merged_count = 0;
long prev_read_id = 0, prev_mate_id = 0;
string entry, entry_m_sc, contig_RI, contig_MI, merged, RI_seq, MI_seq, header_fasta = "";
float RI_start, MI_start, RI_end, MI_end, RI_IS, MI_IS, read_contig_len, mate_contig_len;
multimap<int, RI_data> broken_byRI;
typedef map<string, RI_data> temp_data;
temp_data one_RI;
string read_contig1, read_contig2, mate_contig1; // mate_contig2, strand_read1, strand_read2, strand_mate1, strand_mate2;
bool strand_read1, strand_read2, strand_mate1, strand_mate2, RI_dir, MI_dir, flag; // reverse = true, forward = false
int read_start1, read_end1, mate_start1, mate_end1, read_start2, read_end2, mate_start2, mate_end2;
BamReader reader;
const SamHeader header = reader.GetHeader(); // returns header data object
BamTools::BamAlignment al;
BamTools::RefData read_id, mate_id;
vector<RefData> ref;
if (!reader.Open(bam_distant)) {
cerr << "Could not open BAM file." << endl;
exit(0);
}
ref = reader.GetReferenceData();
time_t start, end;
time(&start);
//cout << "before generating broken_byRI map" << endl;
while (reader.GetNextAlignment(al)) {
if (al.RefID != -1 && al.IsMateMapped() && al.IsMapped()) { // to avoid unaligned reads which gives -1 RefID
read_id = ref.at(al.RefID);
mate_id = ref.at(al.MateRefID);
if (count == 0) {
read_contig1 = read_id.RefName;
mate_contig1 = mate_id.RefName;
prev_read_id = al.RefID;
prev_mate_id = al.MateRefID;
read_start1 = al.Position;
read_end1 = al.GetEndPosition();
mate_start1 = al.MatePosition;
mate_end1 = al.MatePosition + read_length; //start of last read + read length
strand_read1 = al.IsReverseStrand(); //reverse
strand_mate1 = al.IsMateReverseStrand(); //reverse
count += 1;
} else {
read_contig_len = read_id.RefLength;
mate_contig_len = mate_id.RefLength;
if (al.RefID == prev_read_id) { //if (read_contig1 == read_contig2) {
if (al.MateRefID == prev_mate_id) { //if (mate_contig1 == mate_contig2) {
read_end2 = al.GetEndPosition();
// if (read_count == 110)
// cout << "wait" << endl;
if (al.MatePosition <= mate_start1) { // update mate start not mate end
mate_start2 = al.MatePosition; // to get start position of mate island
mate_end2 = mate_end1; // to get end position for mate island
mate_start1 = mate_start2; // to keep the first min value for start position
} else { // update mate end not mate start
mate_start2 = mate_start1;
mate_end2 = al.MatePosition + read_length;
mate_end1 = mate_end2; // to keep max end value for end position
}
strand_read2 = al.IsReverseStrand(); //true; // reverse
strand_mate2 = al.IsMateReverseStrand(); //true; //reverse
read_count++;
} else { // different mate contig
// read_count++;
temp_data::iterator it_temp = one_RI.find(mate_contig1);
if (it_temp != one_RI.end()) {
ri_data.read_count = it_temp->second.read_count + read_count;
one_RI.erase(it_temp);
if (read_start1 > it_temp->second.read_start)
read_start1 = it_temp->second.read_start;
} else {
ri_data.read_count = read_count;
}
ri_data.mate_start = mate_start1;
ri_data.read_start = read_start1;
ri_data.read_end = read_end1;
ri_data.mate_end = mate_end1;// + read_length; // to get end position of mate island
ri_data.strand_read = strand_read1;
ri_data.mate_contig = mate_contig1;
ri_data.read_contig = read_contig1;
ri_data.strand_mate = strand_mate1;
ri_data.flag = true; //active status
one_RI.insert(make_pair(mate_contig1, ri_data));
read_count = 0;
count = 0;
}
} else {
if (read_count != 0) { // for last mate contig when read contig2 change instead mate_contig2
// read_count++;
temp_data::iterator it_temp = one_RI.find(mate_contig1);
if (it_temp != one_RI.end()) {
ri_data.read_count = it_temp->second.read_count + read_count;
one_RI.erase(it_temp);
} else {
ri_data.read_count = read_count;
}
ri_data.mate_start = mate_start1;
ri_data.read_start = read_start1;
ri_data.read_end = read_end1;
ri_data.mate_end = mate_end1;// + read_length; // to get end position of mate island
ri_data.strand_read = strand_read1;
ri_data.mate_contig = mate_contig1;
ri_data.read_contig = read_contig1;
ri_data.strand_mate = strand_mate1;
ri_data.flag = true; //active status
one_RI.insert(make_pair(mate_contig1, ri_data));
read_count = 0;
}
for (temp_data::iterator itr = one_RI.begin(); itr != one_RI.end(); itr++) {
broken_byRI.insert(make_pair(itr->second.read_count, itr->second));
//temp_file << itr->second.read_count << " " << itr->second.read_contig << " " << itr->second.read_start << " " << itr->second.read_end << " " << itr->second.mate_contig << " " << itr->second.mate_start << " " << itr->second.mate_end << endl;
}
one_RI.clear();
read_count = 0;
count = 0;
}
read_contig1 = read_id.RefName;
mate_contig1 = mate_id.RefName;
prev_read_id = al.RefID;
prev_mate_id = al.MateRefID;
read_end1 = read_end2;
strand_read1 = strand_read2;
strand_mate1 = strand_mate2;
}
}
}// end of while
for (temp_data::iterator itr = one_RI.begin(); itr != one_RI.end(); itr++) {
broken_byRI.insert(make_pair(itr->second.read_count, itr->second));
//temp_file << itr->second.read_count << " " << itr->second.read_contig << " " << itr->second.read_start << " " << itr->second.read_end << " " << itr->second.mate_contig << " " << itr->second.mate_start << " " << itr->second.mate_end << endl;
}
one_RI.clear();
read_count = 0;
//cout << "after generating broken_byRI map" << endl;
// broken_byRI is in sorted order per following rules
// saved in ascending sorted order by read count
// for same outer key it get the first one, otherwise it sort based on key of inner map
// and if inner keys are same then it sort based on outer keys..
typedef map<string, string> merged_fragment; // entries of this vectors are dir(read contig), updated id, updated seq, also separate for mate_contig
merged_fragment merged_fragments;
typedef map<string, vector <string> > id_mapp;
id_mapp id_map;
typedef map<string, string> final_merged_frag;
final_merged_frag final_merged_frags;
set<string> dir_update;
multimap<int, RI_data>::reverse_iterator it_RI;
multimap<int, RI_data>::iterator it_data;
string new_seq;
map<string, string>::iterator it_fasta;
for (it_RI = broken_byRI.rbegin(); it_RI != broken_byRI.rend(); ++it_RI) { //map<sting, map <int, RI_data> >
ri_data = it_RI->second;
contig_RI = ri_data.read_contig;
contig_MI = ri_data.mate_contig;
RI_start = ri_data.read_start;
MI_start = ri_data.mate_start;
RI_end = ri_data.read_end;
MI_end = ri_data.mate_end;
RI_dir = ri_data.strand_read;
MI_dir = ri_data.strand_mate;
flag = ri_data.flag;
read_count = ri_data.read_count;
it_fasta = AllFasta_data.find(contig_RI);
RI_seq = it_fasta->second;
it_fasta = AllFasta_data.find(contig_MI);
MI_seq = it_fasta->second;
// RI_seq = utils.extract_fasta(contig_RI, in_file);
// MI_seq = utils.extract_fasta(contig_MI, in_file);
// cout << contig_RI << " and " << contig_MI << endl;
// if(contig_RI == "TART_57820_tr_trBE_tr" || contig_MI == "TART_57820_tr_trBE_tr")
// cout << "debugg" << endl;
if (extended_byCAP3.find(contig_RI) == extended_byCAP3.end() && extended_byCAP3.find(contig_MI) == extended_byCAP3.end() && read_count >= min_distMapped_reads) {
string idd1 = contig_RI;
string idd2 = contig_MI;
size_t update_ind = contig_RI.find(tool_name_flag); //tr
if (update_ind != std::string::npos) { // [] found remove it and update
idd1 = contig_RI.substr(0, update_ind - 1);
}
update_ind = contig_MI.find(tool_name_flag);
if (update_ind != std::string::npos) { // [] found remove it
idd2 = contig_MI.substr(0, update_ind - 1);
}
header_fasta = idd1;
if (flag) {
string ch1 = contig_RI;
string ch2 = contig_MI;
string ch3 = contig_MI;
string ch4 = contig_RI;
size_t chimera11 = contig_RI.rfind(ROAST_newconitg1); // because multi-gene Chimera has _a and _b at end of their ids before tag
size_t chimera12 = contig_MI.rfind(ROAST_newconitg2);
size_t chimera21 = contig_MI.rfind(ROAST_newconitg1); // because multi-gene Chimera has _a and _b at end of their ids before tag
size_t chimera22 = contig_RI.rfind(ROAST_newconitg2);
// if (contig_RI != contig_MI) { have already check in the start
if(chimera11 != string::npos)
ch1 = contig_RI.substr(0, chimera11 - 1);
if(chimera12 != string::npos)
ch2 = contig_MI.substr(0, chimera12 - 1);
if(chimera21 != string::npos)
ch3 = contig_MI.substr(0, chimera21 - 1);
if(chimera22 != string::npos)
ch4 = contig_RI.substr(0, chimera22 - 1);
if ((ch1 != ch2) && (ch4 != ch3)) { //either both contigs are not same or if they are chimeras split by _a, _b then their original contig ids should not same before _a and _b
// merge them
// find read contig if read strand is same change flag to false
// find mate contig (which appears as read now)if in same direction as just dealt here make flag false
// we also need read strand information and only change read contig direction to make it trackable
//check if contig_RI or contig_MI is already updated? use their updated name, seq, and strands
map<string, string> ::iterator it_ri;
it_ri = merged_fragments.find(contig_RI);
map<string, string> ::iterator it_mi;
it_mi = merged_fragments.find(contig_MI);
if (it_ri != merged_fragments.end()) {
//cout << "Read contig is repeating " << endl;
if (dir_update.find(contig_RI) != dir_update.end()) {
if (!RI_dir) //forward
{
int st = RI_start;
RI_start = RI_seq.size() - RI_end; // 9july21, to consider new direction after previous merging change start and end positions as well
RI_end = RI_seq.size() - st;
RI_dir = true; //reverse
}
else{ //reverse
int st = RI_start;
RI_dir = false;
RI_start = RI_seq.size() - RI_end; // 9july21, to consider new direction after previous merging change start and end positions as well
RI_end = RI_seq.size() - st;
}
}
//
header_fasta = it_ri->second; //
merged_count = merged_count + merge_RIs(final_merged_frags, id_map, merged_fragments, contig_RI, contig_MI, dir_update, RI_seq, MI_seq, RI_start, RI_end, MI_start, MI_end, RI_dir, MI_dir, header_fasta, idd2, it_ri, log_new, mergedRI, merged_check);
} else if (it_mi != merged_fragments.end()) {
//cout << "Mate contig is repeating" << endl;
if (dir_update.find(contig_MI) != dir_update.end()) { // if MI already done make it RI
if (!MI_dir) //forward
{
int st = MI_start;
MI_start = MI_seq.size() - MI_end; // 9july21, to consider new direction after previous merging change start and end positions as well
MI_end = MI_seq.size() - st;
MI_dir = true; //reverse
} else { //reverse
MI_dir = false;
int st = MI_start;
MI_start = MI_seq.size() - MI_end; // 9july21, to consider new direction after previous merging change start and end positions as well
MI_end = MI_seq.size() - st;
}
}
header_fasta = it_mi->second; //
merged_count = merged_count + merge_RIs(final_merged_frags, id_map, merged_fragments, contig_MI, contig_RI, dir_update, MI_seq, RI_seq, MI_start, MI_end, RI_start, RI_end, MI_dir, RI_dir, header_fasta, idd2, it_mi, log_new, mergedRI, merged_check);
} else { // both not already written
// cout << "new read and mate contigs" << endl;
if (!RI_dir) { //forward
if (MI_dir) { //reverse
// cout << "FR" << endl;
merged = overlap_merge(RI_seq, MI_seq, RI_start, RI_end, MI_start, MI_end ); //, RI_pos);
if (!(merged.empty())) // no overlap found so add new batch number to both contigs which shows read island but can't be merged
{
if ((contig_RI.find(ROASTcap3_left_tag) != std::string::npos) || (contig_MI.find(ROASTcap3_left_tag) != std::string::npos) || (contig_RI.find(ROASTcap3_right_tag) != std::string::npos) || (contig_MI.find(ROASTcap3_right_tag) != std::string::npos)) {
int init_size;
bool RI_largest;
if (RI_seq.size() > MI_seq.size()){
init_size = RI_seq.size();
RI_largest = true;
}
else{
init_size = MI_seq.size();
RI_largest = false;
}
if (merged.size() > init_size && (merged.size() - init_size >= (min_CAP3_ext * read_length) / 100)) {
header_fasta = header_fasta + "_and_" + idd2;
merged_count++;
// merged_contigs.push_back(header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(header_fasta, start_overlap));
merged_contigs.insert(make_pair(header_fasta, end_overlap));
log_new << contig_RI << "\t" << contig_MI << "\t" << "RI(FR)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
} else {
merged_check.insert(contig_RI); // so that it won't get read again to write
merged_check.insert(contig_MI);
if (RI_largest) { // tag RI seq, discard MI
string contig_RI_new = contig_RI + "_" + stop_RCAP3_ext;
mergedRI << ">" << contig_RI_new << endl << RI_seq << endl;
} else {
string contig_MI_new = contig_MI + "_" + stop_LCAP3_ext;
mergedRI << ">" << contig_MI_new << endl << MI_seq << endl;
}
merged.clear();
}
} else {
string temp_header = header_fasta + "_and_" + idd2;
if(temp_header.length() <= max_header_size ) //27dec 21 to avoid error in cufflink due to long ID size
header_fasta = temp_header ;
//else keep header_fasta as it is
merged_count++;
// merged_contigs.push_back(header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(header_fasta, start_overlap));
merged_contigs.insert(make_pair(header_fasta, end_overlap));
log_new << contig_RI << "\t" << contig_MI << "\t" << "RI(FR)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
}
}
} else if (!MI_dir) { // forward/ take reverse complement
// cout << "FF" << endl;
string RI_seq_RC = utils.Rcomplement(RI_seq); //now its R
int ri_end = RI_seq.size() - RI_start;
int ri_start = RI_seq.size() - RI_end;
merged = overlap_merge(MI_seq, RI_seq_RC, MI_start, MI_end, ri_start, ri_end); //, MI_pos);
if (!(merged.empty())) {
if ((contig_RI.find(ROASTcap3_left_tag) != std::string::npos) || (contig_MI.find(ROASTcap3_left_tag) != std::string::npos) || (contig_RI.find(ROASTcap3_right_tag) != std::string::npos) || (contig_MI.find(ROASTcap3_right_tag) != std::string::npos)) {
int init_size;
bool RI_largest;
if (RI_seq.size() > MI_seq.size()) {
init_size = RI_seq.size();
RI_largest = true;
} else {
init_size = MI_seq.size();
RI_largest = false;
}
if (merged.size() > init_size && ( merged.size() - init_size >= (min_CAP3_ext * read_length) / 100) ) {
string temp_header = header_fasta + "_and_" + idd2;
if(temp_header.length() <= max_header_size ) //27dec 21 to avoid error in cufflink due to long ID size
header_fasta = temp_header ;
//else keep header_fasta as it is
merged_count++;
// merged_contigs.push_back(header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(header_fasta, start_overlap));
merged_contigs.insert(make_pair(header_fasta, end_overlap));
dir_update.insert(contig_RI);
log_new << contig_RI << "\t" << contig_MI << "\t" << "RI(FF)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
} else {
merged_check.insert(contig_RI); // so that it won't get read again to write
merged_check.insert(contig_MI);
if (RI_largest) { // tag RI seq, discard MI
string contig_RI_new = contig_RI + "_" + stop_RCAP3_ext;
mergedRI << ">" << contig_RI_new << endl << RI_seq << endl;
} else {
string contig_MI_new = contig_MI + "_" + stop_LCAP3_ext;
mergedRI << ">" << contig_MI_new << endl << MI_seq << endl;
}
merged.clear();
}
} else {
string temp_header = header_fasta + "_and_" + idd2;
if(temp_header.length() <= max_header_size ) //27dec 21 to avoid error in cufflink due to long ID size
header_fasta = temp_header ;
//else keep header_fasta as it is
merged_count++;
// merged_contigs.push_back(header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(header_fasta, start_overlap));
merged_contigs.insert(make_pair(header_fasta, end_overlap));
dir_update.insert(contig_RI);
log_new << contig_RI << "\t" << contig_MI << "\t" << "RI(FF)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
}
}
}
} else if (RI_dir) { //R
if (MI_dir) { //R
// cout << "RR" << endl;
string RI_seq_RC = utils.Rcomplement(RI_seq); //now its F
int ri_end = RI_seq.size() - RI_start;
int ri_start = RI_seq.size() - RI_end;
merged = overlap_merge(RI_seq_RC, MI_seq, ri_start, ri_end, MI_start, MI_end); //, ri_pos);
if (!(merged.empty())) {
if ((contig_RI.find(ROASTcap3_left_tag) != std::string::npos) || (contig_MI.find(ROASTcap3_left_tag) != std::string::npos) || (contig_RI.find(ROASTcap3_right_tag) != std::string::npos) || (contig_MI.find(ROASTcap3_right_tag) != std::string::npos)) {
int init_size;
bool RI_largest;
if (RI_seq.size() > MI_seq.size()) {
init_size = RI_seq.size();
RI_largest = true;
} else {
init_size = MI_seq.size();
RI_largest = false;
}
if (merged.size() > init_size && (merged.size() - init_size >= (min_CAP3_ext * read_length) / 100)) {
string temp_header = header_fasta + "_and_" + idd2;
if (temp_header.length() <= max_header_size) //27dec 21 to avoid error in cufflink due to long ID size
header_fasta = temp_header;
//else keep header_fasta as it is
merged_count++;
// merged_contigs.push_back(header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(header_fasta, start_overlap));
merged_contigs.insert(make_pair(header_fasta, end_overlap));
dir_update.insert(contig_RI);
log_new << contig_RI << "\t" << contig_MI << "\t" << "RI(RR)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
} else {
merged_check.insert(contig_RI); // so that it won't get read again to write
merged_check.insert(contig_MI);
if (RI_largest) { // tag RI seq, discard MI
string contig_RI_new = contig_RI + "_" + stop_RCAP3_ext;
mergedRI << ">" << contig_RI_new << endl << RI_seq << endl;
} else {
string contig_MI_new = contig_MI + "_" + stop_LCAP3_ext;
mergedRI << ">" << contig_MI_new << endl << MI_seq << endl;
}
merged.clear();
}
} else {
string temp_header = header_fasta + "_and_" + idd2;
if(temp_header.length() <= max_header_size ) //27dec 21 to avoid error in cufflink due to long ID size
header_fasta = temp_header ;
//else keep header_fasta as it is
merged_count++;
// merged_contigs.push_back(header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(header_fasta, start_overlap));
merged_contigs.insert(make_pair(header_fasta, end_overlap));
dir_update.insert(contig_RI);
log_new << contig_RI << "\t" << contig_MI << "\t" << "RI(RR)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
}
}
} else if (!MI_dir) { //F
// cout << "RF" << endl;
merged = overlap_merge(MI_seq, RI_seq, MI_start, MI_end, RI_start, RI_end); //, MI_pos);
if (!(merged.empty())) {
if ((contig_RI.find(ROASTcap3_left_tag) != std::string::npos) || (contig_MI.find(ROASTcap3_left_tag) != std::string::npos) || (contig_RI.find(ROASTcap3_right_tag) != std::string::npos) || (contig_MI.find(ROASTcap3_right_tag) != std::string::npos)) {
int init_size;
bool RI_largest;
if (RI_seq.size() > MI_seq.size()) {
init_size = RI_seq.size();
RI_largest = true;
} else {
init_size = MI_seq.size();
RI_largest = false;
}
if (merged.size() > init_size && (merged.size() - init_size >= (min_CAP3_ext * read_length) / 100)) {
string temp_header = header_fasta + "_and_" + idd2;
if(temp_header.length() <= max_header_size ) //27dec 21 to avoid error in cufflink due to long ID size
header_fasta = temp_header ;
//else keep header_fasta as it is
merged_count++;
// merged_contigs.push_back(header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(header_fasta, start_overlap));
merged_contigs.insert(make_pair(header_fasta, end_overlap));
log_new << contig_RI << "\t" << contig_MI << "\t" << "RI(RF)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
} else {
merged_check.insert(contig_RI); // so that it won't get read again to write
merged_check.insert(contig_MI);
if (RI_largest) { // tag RI seq, discard MI
string contig_RI_new = contig_RI + "_" + stop_RCAP3_ext;
mergedRI << ">" << contig_RI_new << endl << RI_seq << endl;
} else {
string contig_MI_new = contig_MI + "_" + stop_LCAP3_ext;
mergedRI << ">" << contig_MI_new << endl << MI_seq << endl;
}
merged.clear();
}
} else {
string temp_header = header_fasta + "_and_" + idd2;
if(temp_header.length() <= max_header_size ) //27dec 21 to avoid error in cufflink due to long ID size
header_fasta = temp_header ;
//else keep header_fasta as it is
merged_count++;
// merged_contigs.push_back(header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(header_fasta, start_overlap));
merged_contigs.insert(make_pair(header_fasta, end_overlap));
log_new << contig_RI << "\t" << contig_MI << "\t" << "RI(RF)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
}
}
}
}
if (!(merged.empty())) { //fill all four data structures
merged_fragments.insert(make_pair(contig_RI, header_fasta));
merged_fragments.insert(make_pair(contig_MI, header_fasta));
vector <string> temp; // add new and vector of old ids in id map
temp.push_back(contig_RI);
temp.push_back(contig_MI);
id_map.insert(make_pair(header_fasta, temp));
temp.clear();
final_merged_frags.insert(make_pair(header_fasta, merged)); // add new id and new sequence
merged_check.insert(contig_RI);
merged_check.insert(contig_MI);
frgaments_merged = true;
if(merged.size() <= RI_seq.size()) // to check if size of contig didn't increase after merging of fragmented contigs - > embeded sequences
embed_count++ ;
}
merged.clear();
}
//considering broken_byRI is sorted by KEY which is read island count
// for current and all new entries if same contig RI appear with same strand? ignore it
if (frgaments_merged) {
for (it_data = broken_byRI.begin(); it_data != broken_byRI.end(); it_data++) {
if (it_data->second.read_contig == contig_RI && it_data->second.strand_read == RI_dir)
it_data->second.flag = false;
if (it_data->second.read_contig == contig_MI && it_data->second.strand_read == MI_dir)
it_data->second.flag = false;
if (it_data->second.mate_contig == contig_RI && it_data->second.strand_mate == RI_dir)
it_data->second.flag = false;
if (it_data->second.mate_contig == contig_MI && it_data->second.strand_mate == MI_dir)
it_data->second.flag = false;
}
}
frgaments_merged = false;
header_fasta = "";
}
//}
// find make all flags false here containing same contig_RI and direction and contig_MI and direction in broken_byRI map<sting, map <int, RI_data> >
}
}// cap3 check
}
for (final_merged_frag::iterator it_merged = final_merged_frags.begin(); it_merged != final_merged_frags.end(); it_merged++) {
mergedRI << ">" << it_merged->first << endl << it_merged->second << endl;
//cout << ">" << it_merged->first << endl << it_merged->second << endl;
}
time(&end);
double elapsed_secs = double(end - start);
log_time << "outer_iteration:" << outer_iteration << " Read islands process time:" << elapsed_secs << endl << endl << "Embeded fragmented contigs: " << embed_count << endl;
ifstream infile;
infile.open(in_file.c_str());
string ID, ID1;
while (!(getline(infile, entry_m_sc).eof())) { // rewrite merge file for RI and keep SC merged as it is
if (entry_m_sc[0] == '>') {
ID = entry_m_sc;
ID1 = entry_m_sc.substr(1, entry_m_sc.size());
} else {
if ((merged_check.find(ID1) == merged_check.end()) && (extended_byCAP3.find(ID1) == extended_byCAP3.end())) {//current contig is not being merged
mergedRI << ID << endl << entry_m_sc << endl;
} else {
continue;
}
}
}
cout << "Merged fragmented contigs using Reads Islands at iteration " << outer_iteration << ": " << merged_count << endl << endl;
merged_fragmented_contigs = merged_fragmented_contigs + merged_count; // GLOBAL COUNT
infile.close();
mergedRI.close();
log_new.close();
extended_byCAP3.clear();
//temp_file.close();
return merged_count;
}
int byRI::merge_RIs(map<string, string> &final_merged_frags, map<string, vector <string> > &id_map, map<string, string> &merged_fragments, string contig_RI2, string contig_MI2,
set<string> &dir_update, string RI_seq2, string MI_seq2, int RI_start2, int RI_end2, int MI_start2, int MI_end2, bool RI_dir2, bool MI_dir2, string header_fasta, string idd2, map<string, string> ::iterator &it_ri, ofstream &log_new, ofstream &mergedRI, set <string> &merged_check)
{
utils utils;
typedef map<string, string> merged_fragment; // entries of this vectors are dir(read contig), updated id, updated seq, also separate for mate_contig
typedef map<string, vector <string> > id_mapp;
typedef map<string, string> final_merged_frag;
multimap<int, RI_data>::reverse_iterator it_RI;
string new_seq, merged, new_header_fasta;
int merged_count = 0;
final_merged_frag::iterator it_update_seq;
it_update_seq = final_merged_frags.find(header_fasta);
string old_seq = RI_seq2; //
RI_seq2 = it_update_seq->second; // use previously merged updated seq for found contig_RI
// cout << old_seq << endl <<"old seq size " << old_seq.size() << endl;
// cout << RI_seq2 << endl << "RI size " << RI_seq2.size() << endl;
// cout << MI_seq2 << endl << "MI size" << MI_seq2.size() << endl;
//update RI_pos here
id_mapp::iterator it_newid;
it_newid = id_map.find(header_fasta);
if (!RI_dir2) { //F
if (MI_dir2) { //R
// cout << "FR" << endl;
// MI is on right means RI has something on its left earlier 213
RI_start2 = RI_seq2.size() - (old_seq.size() - RI_start2); //update position
RI_end2 = RI_seq2.size() - (old_seq.size() - RI_end2);
merged = overlap_merge(RI_seq2, MI_seq2, RI_start2, RI_end2, MI_start2, MI_end2); //, RI_pos); // RI_seq - RI_pos
if (!(merged.empty())) {
if ((contig_RI2.find(ROASTcap3_left_tag) != std::string::npos) || (contig_MI2.find(ROASTcap3_left_tag) != std::string::npos) || (contig_RI2.find(ROASTcap3_right_tag) != std::string::npos) || (contig_MI2.find(ROASTcap3_right_tag) != std::string::npos)) {
int init_size;
bool RI_largest;
if (RI_seq2.size() > MI_seq2.size()) {
init_size = RI_seq2.size();
RI_largest = true;
} else {
init_size = MI_seq2.size();
RI_largest = false;
}
if (merged.size() > init_size && (merged.size() - init_size >= (min_CAP3_ext * read_length) / 100) ) {
new_header_fasta = header_fasta + "_and_" + idd2;
if(new_header_fasta.length() > max_header_size) // //27dec 21 to avoid error in cufflink due to long ID size
new_header_fasta = header_fasta;
merged_count++;
//merged_contigs.push_back(new_header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(new_header_fasta, start_overlap));
merged_contigs.insert(make_pair(new_header_fasta, end_overlap));
log_new << contig_RI2 << "\t" << contig_MI2 << "\t" << "RI(FR)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
} else {
merged_check.insert(contig_RI2); // so that it won't get read again to write
merged_check.insert(contig_MI2);
if (RI_largest) { // tag RI seq, discard MI
string contig_RI_new = contig_RI2 + "_" + stop_RCAP3_ext;
mergedRI << ">" << contig_RI_new << endl << RI_seq2 << endl;
} else {
string contig_MI_new = contig_MI2 + "_" + stop_LCAP3_ext;
mergedRI << ">" << contig_MI_new << endl << MI_seq2 << endl;
}
merged.clear();
}
} else {
new_header_fasta = header_fasta + "_and_" + idd2;
if(new_header_fasta.length() > max_header_size) // //27dec 21 to avoid error in cufflink due to long ID size
new_header_fasta = header_fasta;
merged_count++;
//merged_contigs.push_back(new_header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(new_header_fasta, start_overlap));
merged_contigs.insert(make_pair(new_header_fasta, end_overlap));
log_new << contig_RI2 << "\t" << contig_MI2 << "\t" << "RI(FR)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
}
}
} else if (!MI_dir2) { //F // take reverse complement
// cout << "FF" << endl;
string RI_seq_RC = utils.Rcomplement(RI_seq2); //now its R
//MI is for means RI Is R and previously merged at left 213 so make it 312
RI_start2 = RI_seq2.size() - (old_seq.size() - RI_start2); //9july check
RI_end2 = RI_seq2.size() - (old_seq.size() - RI_end2);
int ri_end = RI_seq2.size() - RI_start2;
int ri_start = RI_seq2.size() - RI_end2;
if (RI_seq2.size() < old_seq.size()) {
ri_start = 0; //RI_seq.size() - RI_end;
}
merged = overlap_merge(MI_seq2, RI_seq_RC, MI_start2, MI_end2, ri_start, ri_end); //, MI_pos);
if (!(merged.empty())) {
if ((contig_RI2.find(ROASTcap3_left_tag) != std::string::npos) || (contig_MI2.find(ROASTcap3_left_tag) != std::string::npos) || (contig_RI2.find(ROASTcap3_right_tag) != std::string::npos) || (contig_MI2.find(ROASTcap3_right_tag) != std::string::npos)) {
int init_size;
bool RI_largest;
if (RI_seq2.size() > MI_seq2.size()) {
init_size = RI_seq2.size();
RI_largest = true;
} else {
init_size = MI_seq2.size();
RI_largest = false;
}
if (merged.size() > init_size && (merged.size() - init_size >= (min_CAP3_ext * read_length) / 100)) {
new_header_fasta = header_fasta + "_and_" + idd2;
if(new_header_fasta.length() > max_header_size) // //27dec 21 to avoid error in cufflink due to long ID size
new_header_fasta = header_fasta;
merged_count++;
//merged_contigs.push_back(new_header_fasta);
// 28oct21 // write for chimera
merged_contigs.insert(make_pair(new_header_fasta, start_overlap));
merged_contigs.insert(make_pair(new_header_fasta, end_overlap));
dir_update.insert(contig_RI2);
log_new << contig_RI2 << "\t" << contig_MI2 << "\t" << "RI(FF)," << "\t" << "overlap=" << start_overlap << "-" << end_overlap << endl;
} else {
merged_check.insert(contig_RI2); // so that it won't get read again to write