From c8518cde9e4def44b657b34eee23096bb7bdcb00 Mon Sep 17 00:00:00 2001 From: Derek Date: Tue, 8 Jun 2010 23:29:45 -0400 Subject: [PATCH] Added GetNextAlignmentCore() to BamReader API as well as a corresponding SaveAlignment() in BamWriter. Both utilitze the BamAlignmentSupportData structure which contains the raw character data and lengths, and which has been bumped to BamAux.h. Exposing these methods should allow for quicker read/writes for tools that are only concerned with alignment/positional data, not the actual sequences. --- BamAux.h | 29 ++++++++++++++++++++++++++++- BamReader.cpp | 46 +++++++++++++++++++++++++++++++++------------- BamReader.h | 7 ++++++- BamReader.o | Bin 0 -> 64760 bytes BamWriter.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++------- BamWriter.h | 4 +++- BamWriter.o | Bin 0 -> 11092 bytes 7 files changed, 113 insertions(+), 23 deletions(-) create mode 100644 BamReader.o create mode 100644 BamWriter.o diff --git a/BamAux.h b/BamAux.h index 3d14a46..4659249 100644 --- a/BamAux.h +++ b/BamAux.h @@ -3,7 +3,7 @@ // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- -// Last modified: 14 April 2010 (DB) +// Last modified: 8 June 2010 (DB) // --------------------------------------------------------------------------- // Provides the basic constants, data structures, etc. for using BAM files // *************************************************************************** @@ -154,9 +154,36 @@ struct BamAlignment { // ---------------------------------------------------------------- // Auxiliary data structs & typedefs +struct BamAlignmentSupportData { + + // data members + std::string AllCharData; + uint32_t BlockLength; + uint32_t NumCigarOperations; + uint32_t QueryNameLength; + uint32_t QuerySequenceLength; + + // constructor + BamAlignmentSupportData(void) + : BlockLength(0) + , NumCigarOperations(0) + , QueryNameLength(0) + , QuerySequenceLength(0) + { } +}; + struct CigarOp { + + // data members char Type; // Operation type (MIDNSHP) uint32_t Length; // Operation length (number of bases) + + // constructor + CigarOp(const char type = '\0', + const uint32_t length = 0) + : Type(type) + , Length(length) + { } }; struct RefData { diff --git a/BamReader.cpp b/BamReader.cpp index 7213b23..53c32e9 100644 --- a/BamReader.cpp +++ b/BamReader.cpp @@ -3,7 +3,7 @@ // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- -// Last modified: 14 April 2010 (DB) +// Last modified: 8 June 2010 (DB) // --------------------------------------------------------------------------- // Uses BGZF routines were adapted from the bgzf.c code developed at the Broad // Institute. @@ -23,16 +23,6 @@ using namespace BamTools; using namespace std; -namespace BamTools { - struct BamAlignmentSupportData { - string AllCharData; - uint32_t BlockLength; - uint32_t NumCigarOperations; - uint32_t QueryNameLength; - uint32_t QuerySequenceLength; - }; -} // namespace BamTools - struct BamReader::BamReaderPrivate { // ------------------------------- @@ -79,6 +69,7 @@ struct BamReader::BamReaderPrivate { // access alignment data bool GetNextAlignment(BamAlignment& bAlignment); + bool GetNextAlignmentCore(BamAlignment& bAlignment, BamAlignmentSupportData& supportData); // access auxiliary data int GetReferenceID(const string& refName) const; @@ -148,6 +139,7 @@ bool BamReader::Rewind(void) { return d->Rewind(); } // access alignment data bool BamReader::GetNextAlignment(BamAlignment& bAlignment) { return d->GetNextAlignment(bAlignment); } +bool BamReader::GetNextAlignmentCore(BamAlignment& bAlignment, BamAlignmentSupportData& supportData) { return d->GetNextAlignmentCore(bAlignment, supportData); } // access auxiliary data const string BamReader::GetHeaderText(void) const { return d->HeaderText; } @@ -526,7 +518,7 @@ bool BamReader::BamReaderPrivate::GetNextAlignment(BamAlignment& bAlignment) { // load next alignment until region overlap is found while ( !IsOverlap(bAlignment) ) { // if no valid alignment available (likely EOF) return failure - if ( !LoadNextAlignment(bAlignment, supportData) ) { return false; } + if ( !LoadNextAlignment(bAlignment, supportData) ) return false; } // return success (alignment found that overlaps region) @@ -535,7 +527,35 @@ bool BamReader::BamReaderPrivate::GetNextAlignment(BamAlignment& bAlignment) { } // no valid alignment - else { return false; } + else + return false; +} + +// retrieves next available alignment core data (returns success/fail) +// ** DOES NOT parse any character data (bases, qualities, tag data) +// these can be accessed, if necessary, from the supportData +// useful for operations requiring ONLY positional or other alignment-related information +bool BamReader::BamReaderPrivate::GetNextAlignmentCore(BamAlignment& bAlignment, BamAlignmentSupportData& supportData) { + + // if valid alignment available + if ( LoadNextAlignment(bAlignment, supportData) ) { + + // if region not specified, return success + if ( !IsRegionSpecified ) return true; + + // load next alignment until region overlap is found + while ( !IsOverlap(bAlignment) ) { + // if no valid alignment available (likely EOF) return failure + if ( !LoadNextAlignment(bAlignment, supportData) ) return false; + } + + // return success (alignment found that overlaps region) + return true; + } + + // no valid alignment + else + return false; } // calculate closest indexed file offset for region specified diff --git a/BamReader.h b/BamReader.h index fe28abc..88cc74a 100644 --- a/BamReader.h +++ b/BamReader.h @@ -3,7 +3,7 @@ // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- -// Last modified: 30 March 2010 (DB) +// Last modified: 8 June 2010 (DB) // --------------------------------------------------------------------------- // Uses BGZF routines were adapted from the bgzf.c code developed at the Broad // Institute. @@ -51,6 +51,11 @@ class BamReader { // retrieves next available alignment (returns success/fail) bool GetNextAlignment(BamAlignment& bAlignment); + // retrieves next available alignment core data (returns success/fail) + // ** DOES NOT parse any character data (bases, qualities, tag data) + // these can be accessed, if necessary, from the supportData + // useful for operations requiring ONLY positional or other alignment-related information + bool GetNextAlignmentCore(BamAlignment& bAlignment, BamAlignmentSupportData& supportData); // ---------------------- // access auxiliary data diff --git a/BamReader.o b/BamReader.o new file mode 100644 index 0000000000000000000000000000000000000000..44fc7d92c9fb6d79a60716f3e553b085b23d76f5 GIT binary patch literal 64760 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 C{TXr>j|XSx?E%Tm*PHt#6McU5IJ5;odK zd}&wSvQ1W$U1^S8s{OBN!+xOJeq~46bLtg}@@v(B6J9MU!iUvC_ynJcV!FF+S=o*m z$_U4|Y|8BpZd1lP*4vbO0l3zN|GE{F^HoQqUGX9G_;s(@6>giPC?DG#YgN0RHtZd{ zZBJS~(6v!vpW7XExImQ3d0xE^pO$iNyg^6kw>HNIY07IhM@yRWruhD0+Au|VCkGRX%|$9|GI6N*B~v=(RsO2;8@#VnewB{ z73J@j8}I`L;GOAs(Wd;$gieV;-EwU=&T=%_P$kEHn=MLk`)m}^VRN6dDc>TZKr@@0b=WnQ5nYP_S)rc_;H=JVJ_QmyYB@vPm3X8fhy{+Bcd zzW>dBdDO1#vOC_g+jrY3en0g{Pkh&X!*Rr>{M_c~uqp3RaVO}%&qWwCebqK}w&VM0 z_E&9=?P>O3q&cE#%I-A!-cL>OmWW7TB=})-5x?5zIAgQ@%;tDLP5B!k{BD|KQ=0Mv z%JZupZ8-Q}ZCUH>3h@8lt{k;FUbHK#?bnNjyW&bfC#s6}cHfPNdfO*9-LAYyRq0lq zusu@ZcrIPpZFBrIUD=lA=yocb?T!zf%CqWoX$|Sh_I{2Zrz>b`Mfumu9PgytcV0I1 z72H?mbo@G9`I{5bXPg9HM@+@i3Ckw>d^6qgLAugOpJ&sr!>6ny=qS^vN^NP569bh! zcE|TKlpm;$|COQqQg!UhP~Ie7Kjzq~wqz*3>hE|tLwVNq1qHrC^=Tb=JwBh!z~{F! zDC;jX9EkWmMMT9X3UGQHk15k~4EB-Vf=71PY`?VSJ04KV8EkHUw|}MSX60WTj&BcF ze&5gW{w>O{oesq4>Hm_}Hca`C{>RjFw{1^4Lo0Yaq$A`mg9oIPUz2#a5(zoB> z*q5WcJjC&@Im+*|9WULaymX`E?VFShLmi(FRsMabB;2J5cU-hZ9|BHX;8mZLQ z$T8+>$4}Cf$&UYJSJv3*vq5mu4{VPAVOM@_bF8xyUw@XSd?(HEX`1pQD)D3b@1M+j zb%Em(j6}x^X-cEbfi9^dq=`q`C**u`OL9J;Er5iPA{13gr75E+kS>8T7-V4!Lgt0UYyFy9S%0d=MdXpd9CeL5nFk=;V#cwYBX{2b7KQL z82^CgeFOyvbQ#MmChiLr>q+?L2L_6LmYM+Xs^k#!lt!)S8}@PeKpM2|gzT;i1k$^IEj{&i>}9FDtJ z_1^2$>ed1TJ~n#;*Yfe5%*Mx`V&mb!(}g21eEc~!-i7OT^kTYHh~doEOegKN!h|Ny zCt?E`2Lbs?mEXR~86OIJ1HkyCPSWnMrFx27ZYFh+%gv;7*sR4qG9BgaV58a7xYEbC z1=6^^l@AsQW-d&(DlQj^$It2+yK;; z+k)$NKj^gMdYD1DRVt0{lY-X-?Bej6zv&LKU5A=6nO}FqtB3-Osr$XPu(BxIB zw+fx#j8xish){DEo}wiPwXQS_;85NK;~f12I!BK~^<=m!fFX*G50PcZ=z<4v4U4K* z9UB2N5Z&Zl98-r(z~|9s`Gp}5QN3n(~-Pf>`uc;^LOI4NEKxv&owoP&LE)gfG= zL+dKKRx+^;1LL3*$%fdmVS>|Q|B|*zJ}~NQK|Pe*w-Tj8oxMs|Z^xA+>pnyZ0B9)E zG6_zNRMXNXlZl$JIfdJse6HMbnNCpmeqEJ8q!7QL_v`g6qu(QAl!`e8=w^k zahsLYe9=-kyGY5fdeMCZl#DuI6E-x(>rgHUO-CWnc^;ZP1h2I@-mE(bfXihiFk*u(X<(gi=p_CQ1y| z?t^g{$Ik+zq=?0OHvS3O({TX}jTZqY6LCgO*4AoI5-0U|@5hlZRPB;*WyWV;||$WMiih6MkL zr4Q~9@7T~^4jrPG4l#XQj#8-Ti#bip29Cz*o}nymnP|2t7%J9QoKnWmH2XFWv@ z`jdX{0C$ChwTD~D&T8VqaWo{MLYylYA*xRxKs z-#hqwod`}mNq!?ku^YqBTL5`S>pt@Dqzz8J_?$4_NC`v24YQJ}qf5v>J=V02J_yOy z1<3}X0!cO`6j#wtI;2)y3~4zSgb-Wx5s3_o+>%&iPjIiW*$@o}L5rS&8{$}Lv$pOd zgdiPuU=t2!=9=;UH*(Lgwm%|A&0(z92y7{Qo^l`PQjuSTnB*j1_O2V86kv> z`3gel6|f45M=gXjKF!`hEg&nP%!q9+p?rNqTYm*ADd6btK_%CKqYEkNu7LRK2_|Wj zjVPO1rr>TvA+l~Ek@Xds3jGrHt>YxI7B=*dR}xPMuB~(*LSpyhe2FFIQ*obw&?trB z*-a9hG=VN*_%m5hS8qsKoT(z>L4Ki+!diwV##~0zN*8PV;;_Ap@FcE5H-CDhvASY@ zU}@!@cb5Ch7cN@7xO~x)s*1{hQm{0*ctQ4(rGf0qig^pNAH{zamDzzOmsMP@Oc?LC zDK(W#mpo#PzwvVAuJHx_qUj|wXUw{P(v*o4rYZi(6Q`9-DpnqzSG8zU4<#Kis)|6>t(Pm6 z52MB8cpXU>3!u@08PG^q!ov>N4$z3f#T_+IGuZt{;L3$+RYX7xYimb<$41~{Vt+gK z1G*ZFUk3;~Lor+MGl(x;eFIarXz;|qgya+*4%rNu3TbGYpn7Xv0gbv!{JH>ScQklP z-itu<2#qC7ptONS{R<^5fdz87%r)X#QbIFw;737RV&KOm?of@9emh7dQ(SX{P<=y< znBIuKGGRidVo5ikkq)fDEwk%tGm%axL?tlblE!01UJldl-a!9^JsDA`6D9%7Lur&5 zcQ%+m1YnwbBk$Xxv9r_EWGldhXcY3twv;MxphYN|?kgZ6Vky<{vim!{emGvfL&MzX zGVG9vc8et2O$-F{zyE^q6goa8vEN9WjU_7XB@z0=0eA*f!XN7#JQ~0;xJ4Elk#G+! zQE{vdTazQ8aL@#fk(=8l#x7l8a>Tk(38Owo%ph`xvTii;{^C?CNu~clRrIk}dCtJb z3};P*@Vh=cNP{rWI1kBv0}kt_(Y}eZ^@MV_uD*)-@e0zq#m%{-tx%U6Zf0UJMZKR8 z)YRJ08Zp<4zK7yy@hjo|L23P7w#VA*?Q{!0%;XToCn1VsbTm)yTlye}Veo={Z59{* zfkD9Wu~`6-K27A80D|%km>~6VoGU_H{7tj-@Dlweejr5*BPSn)9DLd-J|-{hz4sKx zPJRw2W}=%^FkU=+Kl_OprF}0l#9@HdAZciV8z?%hxf`cDh#&smLpB7QYxx3+#aU@Oz<{6Xk9l;SWEZe zhfiug{QALy0!_vkE}x?6a+8a+3Ac5`;5Oek>7pVkgnYc>PUD6k!Q-RJNvIR} zX`xRN44XgX3<@0NazPv*C-Kmi8tYuOOWsYv^Kfq_`i?F@ejH??gG4K8Ys(SxbXICY z->$jZTPE&PzJjhkK7ksGABEMS(}HpkGD6n9Gsl@p%CPo{Li`mDmiCe<$$0 z*%GFB3U4*xHdx?4L3}?Pmm7yTde1SxbItchh?n04)7ResGf!_YghxI?-uxes_cX!p z1QEog5D1BVSP112{V~8y`Ho=$0CSoaGQRnOG9GhHs(k+^WcxG>chFTT?q|vCrbQTj zV?_L_-Ar}Fpr~>82zEp8h!Y-Bjnbo2^XuB=laMYytG63frmbV7x)<5St2i1G;E@Bpc6%j zN6LS)M}}%$idNSTR(_gO#*x{C)OxM%H4@3VrXIgXQwmKV=h5mKC<+_h1l1aep;1AD3YTK%{H~c&#{CSx5YN z(l;h#@CSNeBJ-r0Be)8H@N;R8JwVbOWcLD_&@y1sj13lWZN0(KRq4ijP}UYZLP8Q3 ziS&Z6H3`=$u0O{buQ#~FstLEx#}*2F`+9@hm&CWv_=N~u%GOJ{3Bv#@bHzI0zbeKjg|DfkGl*8nwFb0uHwL zyzUXWU!k9Q?+}K2v_KpUVFmbgJ{+4hE(}Tx{l|J4`moj%WU{BT_(~_%RdVo;76(E8 z(Q%LKZbzCwU|}$vWIS_(7?FF7m$`g4D=hkVjL=ZvQs`pv?epO`tH|A}{(%0p8klCP zv83cA#v=Ka&^pFYrVTY2>o8FO22-dY!^ZmIWSB*x$Ns<2Pir#*zoc80-QN3f0%y0j z9a5nq{v%8K(|QABz@&}r&;o1EtpT%l52;zfy}ZC&mF}s50%CDY#Nq?TV?QT>lA)_~ zJ##|Qfk!?B0crilj3BKMxJ3*qeHaS8*<2(W068$Xi$y~p;aI_)q}PibllXV6KEje% zyp#L_mm`?nXvRt2*n*>7R7xA2C3Qz92*Jb9U-8?!;Yd9q<7!$fTiT zcxmF!eq)}bA0lxv{Hjd}-7GgqHVS!qNp3EH1p>nP2pXlHe!>U#R=LUsY4M+8C&6TH zG`XSqCXPQ{cwF>0IG8b3;{TrLU)oj?9MTq7a^9!$&o}WW=UC?h&t~# z1Vx)rL5cc99y;NBrPY0oNZMmQYuF#?KDIXyWi||2<-htqHfy_tNA%SykW@r+;98?` zwDoHcihN)vuFEi{ViH>ry9HT#1~@I7dW!ejL{XSwb3BkiXEkw2fZQ@Sf88;`Y2Gq- zAkVU64Zo|L_{ZQxQ}o8)>W#m8Z{IcexngWUYwPJ6Ic%k3C>AnV%^*K ztc`j0J=`;WH}17fTwNxHxr<>1dj!N{6VHx9u$QDBfIy{N)o4G&Xg8}6mBfW=+sP;l z*=+Wa(O{BYeWpN~n@^>t4Zefe-Y2rUr76kfeb$(@hprKzDImNBdkS%T& z^~`eD{FN8EaMC}F`y}?VuHX&0Cl!~z_S=IKU-0o{o#Y;fNsC2Ae(%$+z~aQrL5Klg z-Quln7ia^{yuIF8n9y*k0l7!hpo2Y1RE4TWCO=w-(^!OU3Nxlp+Cq=eY>84aV_M6_ zlx+MQ7frJX^XClM0_MmCkgvnY1~1mwWMg?^8LzcYPc6pl3N#g|_p`8Xr}9i3G&+%c z5H~rWR-v|d_LET(PN3`05!fu1?a!rOD8a4gpuT20j9WCTYR?H>-`@`Y$REh^-8?W* zWdXN}Hx5nVMzO#^Y>T+X-5xLiAA&fBlZO2={KPM*CSB$k7TBl6MtZyM>JR)dmn^!9`grssTzv?{^9`E}m{9bVocVg6XlJp(+hn81;Fk*7JJsNURi%X4;o% zH`E+Oxa|bzx4X5PWkxk<=$NbrW%R3Tcigeiz>oPDtF-<&(GDM29L$;`PP9*<6YX@J z=)1v#d@!gO05w1|H|8vM84ZvkXY5^}!*}2(E^RHb{Rkw*f|b9M_E$RTK`I)C>O9&O zAB?iGd)`4>5%%8g#xMTvsd)<8kojFbO;_o6d7Y8J*g*p^puv?ARnh zcbV0+kA`8B!AClI&?9jk13e2&bVG*)n|*ZrKMi?=Yi~Xe3^5fppVY)K0!-927;t%q zVFb5e=(*dj=YPSx_-)Tv03FezRpfYIOzVSk)mx6u#SvI^(>yd3_AR|iDinQAMR!u= zg(NiPG|ac+{9N)dYhUy8#pWS#Ay9H2Y5{>_9@;9|z?g(^oybMzA?js6?#s!M8;x-H zfRPfv2?Pu2eM$d%@+ZNKoh?{n`&t9vpxO}}iF&i)X%BKY?yF7cAO04x&X&hjVdR9! z!8#Gl3K^F7xjCEi*;#xNejz<-Tp4YS5q8Kl&j)hkWP1d51U=ul0X3n9x%oYr{DCYz ze-z!H3GWqfKIE5Zed&x3m!7H}BQVwa+J*lJUE4`A=Xq2q6wfjEN`HC>zQOp9g4uhl zMM^qI;ulEO3~Dc_N#clpz}tH_)4o!o9a8(bpwrO9LeWeessh>8%_bB(&Dyt~08irT z8jsHvsK!)_jWX*{pa~hafAhyTN^!lk3STZZo~RmcP&F<=m23jo;(>+EZzkv>`}{qw zhU9T#!rR8~bF=Xo=CL%C6AC93J50Zr+!ER{Y}$Hhla;bi(_$fq`5mkcS65+Gq2$6; zY+jU#yjO``aU=;XWZfYE(9fI02!p*SF$!@KmVS)EmD@?aIym{T89UZkUb(I1(1Zof z#)&>i2>_$EB(Kdz)Mw`q0PO~WxkVakYEJ$56(d^oU*_4v8UrJUKQFG2(C=RK^ymT- z{1^eQ(!*d;58%>yrU}O`qx#q={~0#>*PNkR;#Ujs3x?=Wv(^nU`hh{*$>(p9n|pFi zVKhKO@e{%Lr*wT^ldPKrjkj48z}MriB3+&*71`?XBduElxi|nbN@jt!8UGahAAb`V zQE#I(IgapCRVJ&1YPXWMOyq&Em4Haqu}33b``Ke-9n)-aL3;R{@m!tlK!%6AB z0BkML=Ol`)K3M?WxM|15%I(=|dyD3pQop?zSG&anj)}w70uci%fFX?_IS+_kTo933kNB zp&1W6yQVMPKX5O<$;<|m*EUI_h7eJ~rr@Ws3L1rUPrdtr8UD*iTA94@d%-OY-(#>G#Yn7A${TxFw9RzlvUXh+jIrMFjo*W}eS&KK+(IoE4M%mejnndw) zsbeG#OZpa*jysT?NS_)~3&B*>e*4VyJZpMs$WC=QW~Q}T>tOO5r8~iwTfw|Xt$C*! zJVEKhkxoxJSW$KPj6qz!m~VJ%$KbM@u;kCY}jMPNd&! zAfY;LMY`JwP2QSbWQ>b_NZZs)ny5e0Mx`st>sI|KeytwwEb`~SQKRu zwWFl_{^Xch0sLE$e-q%;D^Q4pF>z!g+a|yiyOB=yzvX-ws$T>0&&6>#p@~Zzh^PEp zkhU6W8-XW*e!g{XfUV zGZe7ub_+db{uO5W?UYU)M-m5kGaGR)AUzB^ODLU~P^O!-5)9Rap5^#c>AHIfW1(X! z#!q%O*3twh)2Af+Mn(Eoq`wRvQUB6Aj#GeHhQ|4>702X|I@y#X8JIWR!+Phz1;|TJ z41a3Z`S`ODKf|1NHsCu!BkDQTA`6zAFh91!OkSrJh8$CH7*febd<)7N1v;L^x0;24 zC+lnBXQ~T5?|~F`RPQjEW?5$er!MXtW~>SGAmJfF+)G(=O_ycTg-Z2hQ^SznEg!U>@dqAR!gK?+Qo%*_i#n|UsO(} z1;+zPUO8vt5O;FRGJvCSy}gJAMmA8-FkuEcfM=uykEJa9WSSDrRg{O}Po$EN11>Sf zEHdK-z>La=pAm4X^dl3N@<@VFSz*9zl`vOWU@Z0C3K>q%>I>9cMf#|(L!W>ERkJKO z%(*Tbd54=g)==BDSzs)6nhKcW$vE(hE>aa#z88AOqQ31@6yDEKwh>KpH*2p#Nlk3m>$AhE2%(??mTq=hHwq!oX2HO;J$gBn}K@Uq}^ltsUtN z7f8=WmVBhQAYGKPr1vs%Ft5>bAv(zcZgsJu3?({$Zr~98KhNMbYKKRGW9xnAw}WzP z)sv40<~@vepwf6hD!(c#7T+4ESRPPrT`(^&53c1^Rf>qXwfuo;VvZR z7d#qV^3ACgRaG+{owvj{eaf_w@~?|HU&(Fdi5w+?ywT<5^A5o@_=0u37Sd*x7}7=9$d0$$)dm__{=|5v7mhZ(q&JU&zoGFr1y^L6$>Y#K15te zUbzprW|WuYmzRt#pN>+1)Ti9~$o%=`70c&WEDMyQQ5IKRw4BG6R##9tB~>M$ZQkUP zDxZmYbU6x|o=WSqDd$x#?>3w%K@W{^5~PI86KNH<;fnH zdy|1uHZ3E34K)|oU6+hEu1{Ns1mL{N$ur7*m=J_BxbI=#?d9cku!@G`!;`6Z(9;A~9;lqRC{RUFf~#rBmK3CR zTOP76S`w&SO3vWriw5cyi;-q^>5Ff%{SWL=g{gf(g~*cHKBFIp9&oYpZ=-(gQC5<2 zLEHI)CMl6pCZh8}d#n5fr?1|!|Mxa&9tno|I9?E_5Y0&4ddL6fZbi>0WV8dVM?=Jkco`JB?N(~ zB44uhc|K?Lp@sIG-ef~2$LRUUOfBoejr?CT;BGgRDdI&>N~85QoKm#Yc_qEeCRss~ zQw*?6QNS+P4*%%Pg^7zM6Cy9ATvV$Z^YfAg7hSbLvq^~4gq8yVR^=1(2L|u-DYSm+ zQ!PoAld@@&eSe<*c;P<3gv`CkHJL3@2?J>U(#Po>m2xXiT2V@;!lstH*aG)tANT?mxTpGn zTVa8Fx(~QI3tVjT(+Au(3mnzy zLj1DR0!O@hA-E7m=mW0R0=KabxFZ(0AM^p&VSy92dJ{I4|BhSWcJzVo zlm+g$eZZZwz>y=uh1!qyY$U(@z7IIE`${<4>%R~_+Sib9yZeC4vcNU=0heQe`%@oq zw5KD>ZSDh(_C+P!-ag>QTHs#o18$-P?zKMPrdr^L7cbO)Gc0f|eZbAJz`fZA+yV<6 z@%DwvU2K7)i&`!O7qGy+(+3=FZOL{%+6P>n1ukZR!{PCT1GP?Xg!V}2WnSgHrnF${l%59Vv}%qTHG%ooAYGXj4Ee=)dGfD!b;j!w^9 z;KSBN;*s<{j2J6i1K@;jgb69(no{6KmBL1!z=k~!^E-^UwZ6mQ<3zNOjJyqhvc7{* zD3xoHr)&ehMwqbWBkN1!#!BDn2MzxS2`9@P4j^l}vn}O*9l)|&@`JGAQ|6ey6edE6 zkNC}sZv*g2exbd1iSOT1@XZCj-rD(xDfk+IkIJHU@mTPEoPw_b_`Zg8`AGU`i_uEo zCJR0?ez5u?jA>E2^s|DX($S3jDrQqwlKz&!I;0s&ueZzw9w<-9t z%S?X~A{LLV?<*c+$eA&Q9 zJ}dH(^vzDecMSM81Bm+9hd)Ul`AS&n+ceMgZ!r-{e9bBN8ak8wQe?q57Kp9*md!W! zms9YK0i3nIn}BaNV2HlS7JL;c_}mK=g?LCllD>H<__}~k)^~~pUnB)z@j}y=#Y8Ca z?MlJ7=|r+W{1$vSLPl8Y+W>rdk~q92KDrIrTHnnUeD_-LJ!s-1*+fqS`2KEuivOuB z`lBs6Yq{Y^aG@?mn2#*?v6OPRqTES|5;H>o> zhjNR7fXapFN|Z~!6V~=?0Y2epLrCz*`WC0)YxoR4c}ORG^5>F#aUI0EC^jzU@`mM@G7Q zB)(;Uv$o%IDEO2{_!i(#;(I*>pF5x^epI)^{O*CBD-s_=^=$#Z7}Dh<@#O=~THj{i8wVi5_Za>pzMU!f!a+sZ zfOPptd^=L`IscYyzr_HS_-0`*-%4L`wW9o3BEwtaD*>F9zD(eg^~F$0;9H%7PpL6{ zbtFoOk9;Al_{ISrwKLUsnFZg#{yphy2hdrG3~z}~1DqA#4&WPubi!AOKUv=isra5$ z6!HO*kHmL(3cgO@D+UnZLl-9SZA!s6?rF?hz2JKx1>d;O4L%`!Xz~QU4^!~1USawc z0frt)-}@=}HUnQa(g`26qpa^F==|3HZKzdnb36ddN8+0ZIBWYg179X!2%og)IPtwE z1>f9Nm{)qihpSwA;A;my*&nDy&i4QOMRbD!8Zx`mI05BzqJ;82UGBE z!r=V{(&Z!R`*RAu9l$5YTOEKUeQww>i5#hC7qi~+xd3OaZ@UHGIt#u$6W=J4ptHc2 zV}8?%%A&tJO*o39XUH?gTmCPbXqpL^W+r3?PpAn?&j zE&13LT4^O8yYh`>0AF@xd`h?=CG1NH7o~(Jr-Y}Zg#9UD(v*{rUAZqAz?WTUw8<#D zG9wuf=`&NpvlR_7(jPqSy#66gF!|V(2a^GO*`cuw!dv=cpPyfxib&+KD{~Xy^kEko zP%_FcIM5m<4J7&4g$7{_Kb8#O%dRX=2`@B(OESIvK#1y@$ny!gVR>B!QBT-SBo!MA(G{NCc4|Leuitg+xk5*n5n8 zD$hE?DNLh3`Pj+d)AHC8)-@y2u0Xl9Ja(~?N=DdwNLIpsc`^}ScEuv_L>QBq<*_Re z_Lj%4Ku}p8yWrkrggv1J7;*LlZhgHT}n7BC47BK_=c45kd$zCO8CZ<@X(a-O)24=l<=^W@XaaVTT;R_ z6DJ?LlA8?R%dUJSB|JirH6%Drw&yLlyPR5Y-~eeIr~Wp{0=irXTpXmMam7P$oQ_vKUulU z43o`js4_+Q7Q&rKqqAMqKYusV5hX@%RzLbO9-`-_lyH7ZxG*I=B_%w^4Aaa%RPie> zr=CJqErR$~$J5Y&%0?u^HinuR3th z*)D=#h_HO9K2N5E*QJEH8J+;xp|A*^MOdEmB7D+kpKubs3F-7@JQQAl@FwIT{gB|l zP3aJ`KR3f^rU)jR&`?-=@DeGQxAA{F3CR@TUmNb6*s`(K4kFzPk~Y=e{UCn3Deg^mZ=b zQI%&N{}{X%TR~K$u0jeFMPmj+AYQfz1i>Pggs#HUhL8-obV$ZrAgC-@p`w+QT2#ED zxM+*F;(|Wbm5PFkt0=G{TeYlOaI5IH+sZ1>*316>-+9kuGBX)NMS0-)@&E4k^UXQm zd(Jg!dTE+oo~EBo(_7Q@%jnRCO!;-UOPcOw<*~YzqeJ^J`CpC>?ZKpPLWlNW(ods9 zJ1^-zc1c`E-SXTFH_>!I-@h~6PSbhbzsmK~hL1l*{L6E*TnRd~$5MJ%nt!YJuW^r{ z`}7IytmMA~y%sIID(NF>)X;`XdN?|?nUcOljn1EU`IpBXn;oW?cpY~$>AUccyjGjO zm;dLvdbbH3+CC}0{b}KQ*d<+dPkH>ZyxsI)eEdeY(X{SmBFs(AFJikGQc1p_s2Mn~(CP{j}Z5ed$AdmgvgXqxSNd9}xKTNNuZ7FnbAdmfG z)Uw~EAEx(d znm)p|H2N){$Nsc9Ws9TsxD*}Q11Y_m(V^{+^wzZSe?*6NKk`4mmvRn%i|4W59f1yQ zd*nac{1ry|U4stodgOl(I<(`F-hdA6cBJ=N{0E4e=YH%CXX6ms@`} zoXjdZ?7~=c(olopz4zV|}Yn!OlsszE?k&Lw@C@v8EPI zu^mdABJ2!WE6Qias%z`ZG0Ul}QK`zB{GqzQuQAqK)7UWA1u8}{!f?4x^>aM0LyIG| zRoiLA(9|G{osq9-0q5*h0GS_EH`j2In-7D?3P}b1t8I_Ur`6A`^DQYOuONe&71&M4 zJjsu?9BF5qa!fY`%3ZXM4~C{0NM%bVY_4oU!?TfX=P}dHxPGydr{&YC;@tW7rTW~g zf)S)H$_$#>eg|oR(EdcM3e;3o(bUAt^mRzq&#bKZ9$IT7@=Y#Z?bn&i$|sMj9&{I^ zSQe#bm}?D;4jbQ4Q8j_ZBWd-NZ86mPICw~^ZB$uHB7r@MH$+rFC#yGnWcB6VJ`ux( zimH-Hm36MtPZd8Jl8qlu%T$LtHw(iKmJfd*7fYHSmd~oFjR(W%kQ+zMj?I=~5vd=% zX_UrMas^dlS>o zH?L|}-7joZ)#=I>YHS9VH$TpT1w|J{Mh~;M0+TF8OMz%Wb)PFnifMw^MHLCY2hok8WMNZ#i7nR1eA59yN zZP$phSnP)-tsRynJ-KMXC5_nE2PWCJ9E7b+6LA62XKviAxe7(9jL4)_7Dkkqp~>{4 zBMUG$YgW9asm9H!j5jnXdfQbkXL}cp#GGhMV*@{cs%snSOKNL5<)ML+afvv{%}bm4 zWcIRz>qeGg5v~DQe>Q1=B!4!wEv;FSIfSc2N^`WeYuc`p3NdN0`t+@r?7A<-pziZ+ zJ$)e#jlo&C%}X|M`p!NhK+X|YFiPu4>NH3WwYIiR&mw6#pChmA^EFpliWy6`5vi^1 z^qeWYsAYD7iPAxYRPQg_=C=a_)vsU#9-LXK-=`KQO_IacLGUZPF*dUzUcnc@X3A;K^UB8hk(*^`wjXMl4V`vzNt*4Z z4v1U>JsQ0@)>s|$uL5fF!Oo2OH z2lHEbv;}UP)ybQ6VHVl< z+Zn%O3R8FB<3{_YSA%7Zo;7fSJJAe1Zn1OWkNfA;kvivI<57&*hv!g{Mb15JtmfQ6 zWU+I4FQ433i9hB&g5ouN#g^x25gsnyA}(}prFbpR!+9njS?b(VBJo~?U3fP2zoyUT zIlj`pP{e7Msf8X3c6p8<-7yE)S?u5xal zNPY8p{v5dnyARmqRG#HY6Mwo${5c}|tu+3taSv3wAM?C9@=u(l=3!uDHSH$ei|ry* zd4@^fNBSc9jTht2#pF-B{#2TFc*=Mh&yOQ_V51}weynklNW5!#z8blo_mo1Vze<|) zpBFVQ&HZ=M4?4GBTtGQR(mRspsfyPFMjoPkrbkFW%=2yIiG-29!Kmk?()m2U6fZU| z;Q3_am(IN>;y!?bIpQD1wa$GcKEhdej*_W;dqK7D0FmYg`*5Qf9O6N+Ec79yMeS?}JxmQH$^`@9`?)Tzl&K(d*&oO2cuRx^VtBiX@{QoTe ziZ5yR3BoNE>F>Lt%6G3c?Xyi}Jt+DXT;kkqBJt1Y2bXa!TSS+N2N#qOC;U`5%>E< z@_Se$-h?wC?RxSc_#DsiMf!J*cpdXeB>rzj^8JIc=b7kT%yX!5G|)KMc%E^LaSe?8 zobhuOe95`_BJr<>>W>xD%!kz?>&^PmKOcX_%nB&~&8BynZa5qFom?lxmpBI^?w}nD z;O(sU;!ha=gW(#+y?7PtsfhbcL*Pn}Tuda~GIL)6Rld8WA7Z?VuX9e$+~1S_E$dNH;66rtfp^53&L0-Iml>ZE z=Wx9p9xzf2$+x%hbYqoBKED>9<$T~df!;2zbMAK{>3kp(f91J>|0ZMPeDoEJtM9-U zxekfXa4t{W%ysVqNc?M!CyWf-zc1d-_Y+0>_u^3jt4Bk|_a2dWCzS;5aS``dMBG0S z8TWn1K+07t{)%yHdWPwBre83<*YwAxyIx4Vxy~IcKEe4oaVPr~)0dfl-?6yY^W`9s z{PM*FHdrF@&k{OLH@xZfBIEaI(_P00;d>Z+LzQ=c^jox#_*3VK#5bJ#TX7fbthj~wBGQigMEWi7 zV#qof70LfR;}m0^NcgLbH;Tmjh3R!7@wORXGrleE;mn`70h>N^?>YhfHti?I*%ynX zKg3uo?!^|~^cvHTnEo%3dVFnS5U;mLc}hj}70=o3Wh(MO~ngUo%1NIlLKsmCOd^ec^<#X7D-;*Xdwli{n3Cy{)niG-gozRUal zMbf$1+!Ni=KWF~;gZGnvf4Gq|it4x5Sii(Kx!$Q=DaW5xZn#nL_XRdx%72PO*R$S> z9xMOvJ@vkRm>dP>8nNcpE4Zx)#+Pa6M2qdM^u13}c7lPvfc7YTo|NIGYTq@(wIs67TK-=75Uoe^>J*NX?B)~Uy& zsqA*~a`vxE|2iulyg-`t7MuHOk;;YXPFFnA{b!MS{$9KRdq0JPCt3U%BGS=dV|PnO@6%Ga z^NnMTF{9qgBmbqw6~;%68;!e-?-&oKO%?ArV^8Hvx!6kha-Lx2=x6S1m%Y1R--zcm z;ngonNByDtO)%}#qyFX6@M&?bbN?nX?{-+YT_T;jTV(#R#QSuj;xm@sW`5sDlTNir zJFDN7?;TL{Zk05J=q(bjRD90D5pS!s;;a6+-zZWJKmVx58fnV$h`H-4#7f`KFWfgt zQ~u{g$|<`X)z_~l=n5oLxn<`SC7ewNPdQ7`ecpDUt#H7B|h&QON6h-{UY^z%JiS0+U-MW+U--3{QP=F zy?a`Ez8s|APn!JB7Sa6I@5}EJY40aR`pMU86W33Lqds?tVLMXpDGEos`1tT1(_2Nt z?=|h)iFkh93**sFB<;h!W8sD>ecXNj5&tD=(mgf;sqeWW{;lH6T!+nlhq<5FHE{1Q zlHV|qc$bUwoV!b8&~6Z)=f0BhFCyWOISdm1G!b1d(ob_l+UW|B@-H@ho#|Ue`qkeT zCEP>O#Cuw#A9kAmyCRMCCy{U;o4Y>Tru=${^t-?Q-Nf${)gM+^J6$ERU*OW=y1XBJ z`$PM4vhwji6aSO_Ch;^Lj#GTbLobnXoGy}&PoI2br>FAx>nr7Hl_vg)mi{+I(jRH* z*I4@Z7&{xThti4JK94$%P<;Aqx{)He$PvN(m;2-9{svUM{nAJBdrtZ&tIyHwTPUxz zpHIhNC!z9xjrB|H#=cWLmVJ--b?2TFzrpv&#N!x`F>E))^8vVE<{(jS+Sh!vqXSfd+`_d1lV^Hbpds6aW zY+B!slD^lp-p3@pSIl$nzsz!Rg#5ktW<4^WQ9e2J5-$cccd~A5H7K zMUgYH$An6+K>9518<^Jjh$8unFOhWToBImWt4u#BeKz-%%>8Y1muYsSfO#NBojVIE zpRv-UH`#RDbc^X_rf)U9UV1R?WA3}n{ebik(qt|u-BX~_?QeR7=_=zwv5=6}jukkSEl=QJs{sX0lQf_mfZ0>Q>{|~EJ#=`&r literal 0 HcmV?d00001 diff --git a/BamWriter.cpp b/BamWriter.cpp index 2cd2742..9d18fae 100644 --- a/BamWriter.cpp +++ b/BamWriter.cpp @@ -35,12 +35,13 @@ struct BamWriter::BamWriterPrivate { // "public" interface void Close(void); - void Open(const std::string& filename, const std::string& samHeader, const BamTools::RefVector& referenceSequences); - void SaveAlignment(const BamTools::BamAlignment& al); + void Open(const string& filename, const string& samHeader, const RefVector& referenceSequences); + void SaveAlignment(const BamAlignment& al); + void SaveAlignment(const BamAlignment& al, const BamAlignmentSupportData& supportData); // internal methods - void CreatePackedCigar(const std::vector& cigarOperations, std::string& packedCigar); - void EncodeQuerySequence(const std::string& query, std::string& encodedQuery); + void CreatePackedCigar(const vector& cigarOperations, string& packedCigar); + void EncodeQuerySequence(const string& query, string& encodedQuery); }; // ----------------------------------------------------- @@ -59,8 +60,8 @@ BamWriter::~BamWriter(void) { } // closes the alignment archive -void BamWriter::Close(void) { - d->Close(); +void BamWriter::Close(void) { + d->Close(); } // opens the alignment archive @@ -69,10 +70,14 @@ void BamWriter::Open(const string& filename, const string& samHeader, const RefV } // saves the alignment to the alignment archive -void BamWriter::SaveAlignment(const BamAlignment& al) { +void BamWriter::SaveAlignment(const BamAlignment& al) { d->SaveAlignment(al); } +void BamWriter::SaveAlignment(const BamAlignment& al, const BamAlignmentSupportData& supportData) { + d->SaveAlignment(al, supportData); +} + // ----------------------------------------------------- // BamWriterPrivate implementation // ----------------------------------------------------- @@ -380,3 +385,34 @@ void BamWriter::BamWriterPrivate::SaveAlignment(const BamAlignment& al) { mBGZF.Write(al.TagData.data(), tagDataLength); } } + +void BamWriter::BamWriterPrivate::SaveAlignment(const BamAlignment& al, const BamAlignmentSupportData& supportData) { + + // assign the BAM core data + uint32_t buffer[8]; + buffer[0] = al.RefID; + buffer[1] = al.Position; + buffer[2] = (al.Bin << 16) | (al.MapQuality << 8) | supportData.QueryNameLength; + buffer[3] = (al.AlignmentFlag << 16) | supportData.NumCigarOperations; + buffer[4] = supportData.QuerySequenceLength; + buffer[5] = al.MateRefID; + buffer[6] = al.MatePosition; + buffer[7] = al.InsertSize; + + // write the block size + unsigned int blockSize = supportData.BlockLength; + if ( IsBigEndian ) { SwapEndian_32(blockSize); } + mBGZF.Write((char*)&blockSize, BT_SIZEOF_INT); + + // write the BAM core + if ( IsBigEndian ) { + for ( int i = 0; i < 8; ++i ) { + SwapEndian_32(buffer[i]); + } + } + mBGZF.Write((char*)&buffer, BAM_CORE_SIZE); + + // write the raw char data + mBGZF.Write((char*)supportData.AllCharData.data(), supportData.BlockLength-BAM_CORE_SIZE); +} + diff --git a/BamWriter.h b/BamWriter.h index 14de8b5..31c7d61 100644 --- a/BamWriter.h +++ b/BamWriter.h @@ -1,5 +1,5 @@ // *************************************************************************** -// BamWriter.h (c) 2009 Michael Strömberg, Derek Barnett +// BamWriter.h (c) 2009 Michael Str�mberg, Derek Barnett // Marth Lab, Department of Biology, Boston College // All rights reserved. // --------------------------------------------------------------------------- @@ -37,6 +37,8 @@ class BamWriter { void Open(const std::string& filename, const std::string& samHeader, const BamTools::RefVector& referenceSequences); // saves the alignment to the alignment archive void SaveAlignment(const BamTools::BamAlignment& al); + // saves the (partial) alignment, using support data, to the alignment archive + void SaveAlignment(const BamTools::BamAlignment& al, const BamTools::BamAlignmentSupportData& supportData); // private implementation private: diff --git a/BamWriter.o b/BamWriter.o new file mode 100644 index 0000000000000000000000000000000000000000..2cefceaa38da822e96a7674f7eee5b376eb5bc99 GIT binary patch literal 11092 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 literal 0 HcmV?d00001 -- 2.39.5