From 149f37e764dcbc3bde2cc55475bbddf1e44c3026 Mon Sep 17 00:00:00 2001 From: Oliver Henrich Date: Thu, 26 Jan 2017 19:08:59 +0000 Subject: [PATCH 1/3] Corrected reference to Fig.1 --- doc/src/PDF/USER-CGDNA-overview.pdf | Bin 3429852 -> 3429483 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/src/PDF/USER-CGDNA-overview.pdf b/doc/src/PDF/USER-CGDNA-overview.pdf index 092451b4612cae40a42664d0364a0f7575b5b240..c86943541b51786da393397a979cacd6163c8969 100644 GIT binary patch delta 26766 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 delta 27073 zcmZU&18`+gw}l(qR>!t&+qTs)JKV8tCmna#u{ySGchIrTm;b-_R=rnmSAA7;tToSB zW25S{#mvIs3LFPZA}U7u?lvneFsLJwygr24^{RCR zqZ!FOqpic!I+Vmfl}MV(POBxc1Pb9j5(mN_EW!GIdfQByMHZvRbHHl%$G@}lz-L@M zdyjJM&l{un-^bzC%dStJaV}c8TYZb{*Kmc*aFsmAs73^hpPY}Ahh|R8?4?2up0v?H z%dUKxbv3#S+s(7*z=+vvPdC#?ora3jFj4Zsww7nDQMX_ByW1xhFRNld`6MPGZn{ZU zO142#*em-X*>r@~DhY zJ_GzbeP}xRu+b8yY@amEu(NiDJ=R5odBbg-H)U;2Gc9}`7XS-_ayCFvE``$!6eyc$VFtCm@1-!{kFqF4XPR@#%N)3`gFzdM?I{XN0@ml|y*Z zy0!e&p4@bPPO+WGSoBMRPh!cok7$@2d> zy~yld(6FxeVO@0*U%KoqJjs~#_T3Xo)qPQ5rI#}n05e53^0IgxdYFDgChY!f+6iob z{Wq!C)ywLEH@(k>DT%A?LTCwQ2A$xip`=6)Ep?Z6sh$$5quE1@RHVM;53rWc=tBkz zuABU25!RRyTKSpWc4BOmnWdNoJu(S}OhjJKZ)kab8IUO>nE{*MR2`;r87Bt$*Dhm; zWafqy;EuB4ik4SW?jXSP$$)p<7=-1QW=G5pT{p-&xGL_QGUt62s49N!J>p*hY<`~^ zgVj;hbTz-WTW<(V!92w-#yFFxxUr z`Gq$5a!0uz2t-6U{XjeD{fP%9_9mmwoIv~>2%(?7B)?cJMKU$dZ+$5KjjieWVt$Pc z=wMVFv4mWUBix9yo|G!x>rYHfQ3{cGmc}j`*wtdo{b3&HqwSMoRl~w$KS=SnfH!zh z<6b7de25<;4Dw zEE>iR231IVQz5DA8)mkNfEOLc_>Y|)^yhl!XGUX>tw?*t$e+wun+h9=q>mW+e_NCTlU zEv+I>4-&C|ZO_H`93zc68PjP>SlY0=*o5MUZf>|q3l?N~!skPdPa+*bX7<(eV|WgL z|Ma}f`@EU&aFU5)c@4rK1Y@_$KNF+D{(H_CM=H(1oETD!AF4RL7jj4m)c1>~hFQG8 zBq!}dB`1kPQpFf?b6an+L3^<)3r7_kL+rxcrDtbWfKW4jRYG){F2+RC81!;Td zt!(Sf$8v%WTqQnQ*Q>1nAfvQJoUf44%x@(7aikxV?^72hgU|u<16@C2mH zdS$jlLE(|ArMHLue5n&4I1WNBL%Cv8w<5!sUk8C*k)I(7{0Y7eGRJ3nio*=a`>4GRwdbyLmuw*g=7AF9d%h=_g&LFq5b% zA?aXa{syDT)Dygt8UQ(x+m+|mjTWYDOi)cak}&c)w{ojMY<985MFteyjlc)M|4mh< zA?>}ixyTk_bDY=$z!s)Un>xT(dfQn0N0O*6@a2lWSrEl7WLV#k?I(g$;OZRD5bDGd zOvWLCM{s|~>yN?eWdMD>suPPGN|=(tLdcRca*x4{!VFuGz!N60>X}%>TcG{Q###XGcJ%BjFou@=&7O)GcxP6ZLZBccxucxwCs%Sv z->AzOLYj%8SeV`vLGE(+D}@E(j7>bq&GzFXX*7=qMm-vh@H@&(#XJUdTn-XX>W~O{ z8!L@UAlg0k*`HN5sA6=g?^Q#aYuWrvM8A_t=n>6jGr2Sd&$q^f+cpytw}}Q$wPV3Cw*D>P_-5sdd(dF1ech8egE|w1 zhW1qbB()GGR^|Dl5km?kr#vbqm`lCqphlJ+EIqXUN*xu294xo>96=%)1AxTvSPa?C z@5bpt;WmP6AZmHgPu{833O&TASRSL^M#2b{*E*-H0g4rRcFu6)a589_p&-lX76}j2 zXliL!?H>(!3w}Q#fg8WSe_ucGUOjM!EGflCWR&-p%l+MZ-xqL`7p3RB+dfUQ;JiuG z3l=4vhKj&@sr;lLAQp(}Cod=?b9Ull{4*y^PW6{UZRUGuy0Z>KW)0yR+C#QGNWC|A zcGtg|K0xEv%aCcBPSF~NvsHl{#gqb<-2GMNXTG-itO8EQIY$vDKcX8CYxVK;}K3G|CM7EqN`W7xgawV3QWqK2u7e}T?;R@v|Ewf_{R@EO9*@LCWOMtej~km+gt^MLH+ zdroBBa{NJFRSj-MpB!<{s@R_Vtxl>TZ5CK*!~Da8LMl?hIvG0~_rs)c`wrs9)K0q- zY0mEV?FyU_`_Iv^O(KW7z5i10%Vuzb=&YBCnq@M2rp zv*&TK*U+}=RrYZ8jiO05gUjZ*m%%Ib6~SHgxCjAfx{nFBBd2Ay=QD$K)gVmOWWH|T z@vhJjuehO>H=+KFe%lS_XzQA(^4F+4Mb2lDB$_o*6<{W&o$v@xgj}m_eeoC&i zR&U^y{%&?94abRm7}RG92a{74+0b%C}+Be5CLwimbVs7sL>z8zN_)jzOS2Hs)H&07mHmErko|dO4P*d0R?x(LZ*$xcd8jO?YKfcKR6KW$bx~dH&b4j6Ewc&;Od1vF9M>`5)IzGWKl5 zJUst%GBWnu#4OCr|0h_!1j~N}8QfPJ*Oy}bzbW=F@js@%W;nkDdyDlFSU$$r$%1Bq zql2+MY6!ZfM^lPf-FN#%lew6se**XN5=kEVka<{aDLWe@77lT3*wCKS=@8N^8w+N9#bHRN* z3I8$L62%Dp4H}fKrJMuW5FV7{e+KbHpjDv3*#GaQNJCqKGN(UELt7*M_i}t)aW-NW zPS$kgLPk7r7EZSCNEzraV7`F;0`3d=FA%;!`~v9<E*BDY$U`@W;SUm>s9Bm18>)78Y$)}_Glh9d7Cum%FG@5$jqMZ0VS57=#=#6NU>(B zvXqd?YfuXf1O^k!@_1OoI5OIHsqxXSp_WDsiFhSc(|C~$o=5rw~#(h{a{N=eFhISZgJh3(Ot{w3g}X(R9* zfrXK>z_OvF?PZ!{LoqCnAQp6}53zhNKvx12u?>P9Na9VL*j+W%C@0Q!n@Ie-1KmHs zFQX0g>BK`!AoLIru{~o35lM2-KKCOOL>yftLE}IqNpjo_ z0>p6IXet+eUP=_S90nHheC;PCVMhzhSQH{a`X~Y`j#*rmE^uxThU||g)@7Z15HzTg zHDNG~sTe%B2r(-=u3>;aU3si~lgn>}w1q78zNEFr2J|Ro>u>#=Sg4fLP9un5vqk8T zKw$9hZ$^3>>(YR_*xwnkJ8Udvt-{50;_1vkN@)Ch#>fZaNdx=CVMto_Q4mc@72U3Y z4}oY#?Yp`^^g4~x&9?a*UOFMB+3$C1zunc@HF$EG%+|k0T1feN?df>6e2xd?ricj{ zDiL|!`4pJGdTpvdr{i`S+pw7X9GGXt&ri}-#PwhA?C+lieN!kk6S|g|pE5mgry63L zw=yE+rq{@s!t+Roe}}(wWq6#Yv>(+2Y?yr6vg^m|HwtR<;IpyFfNX5O^hdSnsaqAn zja7#5M+C`-B3k>g3d89EH~A@FcLUAj#u0vejN_-SDK7c?TNw?n-1uA5#=JQOeO2>4 zo!G=OeIc@VXOF4E;6H7oCy$rG<%<-&a#Dg3%x!__wsxST2!*aj=?%2E90!$v$Nm8F zty{|pvJ^Kxhjm7q;4+1y6fpbmTa<&_#|gXG3ZjVtNj zX<{e_6J6}*x6X!dxZ)ia9CsRYL9J0pMMc)g$S5yS=2LhNxNQtE&WhB(L={Jwok<`x zoC$1AL^zEr(OIX5_j5Tidm3iqb6VnZE=eYUR zqf#0@uYvVZGBbSMeL@?|x3D6yW9A_enq0V4j?)9&vgFZ5e=(7e{yy%uR77;~@D$!g zwaW^!Z$YeyffSqi~MT4@(bQu&`a}{EOBaWazq(~ zBtn+b`_k;Qs~@1zjPC|OLzaxDYK}%F4U+N+zUszs#lW-4nQR|h?o66z?9snw&4TBF zBhvP&xxzfO<+D5qAM9B{q|AwYV8db-^?OAokR4+U;k6-+PYc#N6p92hL5%6tL_)@S zU|!aC?Iz!;<5r2Iqtl2Y5Q7OShDzItJ;MQ!^>Ts&kWcceMOXk!yS(giAY{5?#7m|+ z5)nwvk+p>EwwO^+@ac$aMOcil_iqvYdRz)@)j&)kefD2vB9ZpB@I`L<2B!xr_Vz9R zM)>pZoMj7mq03{f%aG1qGIEzKe8iE(S zhwNIIj5_X=GkW{_?7HrIvr;w`WXnm!*);Cuk1hFInJfU7uFpBM#O#5I_|_$9>1=o5 zb@}1JEZe{JyPzS6VE^wjD=K;Vt&7qo$4z7!s;(^_=zLR_NJEI(a8kPPo-}o`W=mjY zN}NJ-DHEOS?dJ5mlFWDuh>}$DpNvI0trp3jto3p+x&G=3j7!#HkriVeJH3wThRtN~ zuPT{s1lmArjO`So^dXWr&eQ7lXDEhp%c6D5)6UtG<8{HKD5L11t6O7>lq8;Mz{1rEX}}EgKAfn$8#A?>P$RS-l1yahPB&P z_WW!|D?|5d(%)m-hB{~Zx#+IW$49|85AUZM#5t+5F=2oMy22-dmrN>R;6s(_ z8n<Q^wf~{+{`o5{iXW||JOpNO&(<`mCVL!!+vtNxf6|{%LGKL*pcHQoLcXwoJ@`bS zg5}fUMAYDR{~HQ*V3i?lA9<_sNyXfc3sUbBU;8QSnbItgAr0A*D zYvPe?3CtZ=Xo;zeE{FXk8)L+%<0^SylRn#SoGBx?-)MsOD^_vDuGJNCu8jk_hdS@x z9T&R|G_f|naq2#=Y)@nRtAc&(0b;w4DdsxgkxJDF_U7AZ%KA^wwMdtnRt)V19^fZ% zJN9=o%a0xdx{RJCQH#}-W_*d3YfYchD}x|8CeLams&l4`mr(x#xhVOgLwG6ek)#Z>CSJ;-9%&Cq3i_dxf5hWg zT(;g!VS2%13Hj*ZwA4lsvM8ME3KPAnfV9rHR)*?L#r1S9Lp@PT!2JHVYe-aT(0$Z8 z)m5mlHuG_1rvD~-7)z)GJixcB>FSvimN^%w4S`B|eE=L6hnguK;YF}X>pE;*r#?aO zd4>G{U%3tae}fwf=YNvQeG0)Uof;Z3Ng~@fU>mg zWH9=|qzelXkf#UyWVHOsC;xsjT7M*0#DNQ2#eY&y%hwbe%>R5CGkqy?2#~3aIw9 zP}e_CV!VK8F^+}s41)IbglCN9i-q)j6o#qk-Ta?}aoh87BGdh1L&){tu;KUa5~W2o zNB2u6a=5X(prPh4VHQ1n6ahAHbS~kkjkTFkmC+^LsWiDTLo91Mq^E=i65nUiGZ1!= z%=NVhoPdB05cdKWVF+soW55KI+11&Z#1|B1eXWfrBReY)M7=`xWTCOq?KA1k0*u-1 zwd}Bees*I4O8ENvFG6E|Qv=jmfS~AG{I}FVVUQ677-p6hFtCsVOm>Qc0Z{e7E)^io z1&A}fJ#Ym(=GGPt5D6??U~Al9zd$LQkw7W|0uae&&Y?pf^>E}06_A@jH3o5N1jow+ zT0sqB13Z9VM<5=;(BEC9hT}a0+Q@nqdV8SmX2BB}dNzhe#zvo*K!{w>*SkSic~<Ui@V*4OavQ= z!CmpCKwysGUg*+E02E`p3u`NjorlC%vW(o|=WXU3f=PS%&(Hv*9T0X7C+21_US9u@ z=ZJSL&kqf%oo;nUV=JqJhnAM}ZOzZfUV?p?MphGHW6S3e8;F+?ds~O#o~Pw1>9vd% zu#C(P5-yMW*RmRYBH#oVV(tGV9Q}mH z_^d^F>lVHIBx?Jdng!YhKD!^Ex5c7)baX~>wE=`4ArFKdvr(KC5WxooVW_L+Lg)IA zZheHR$?A;{BgIdLYNR)4T@pRIJz!ZT2tiPn)Y|Mt1RfoHUMS=+&h)TG*bLG&ArZG{ zpy#B>2p9)6>|+9vG!Hp@kPSZ_Xae#wBagS;Xe|#V(>MXto(E*inW3lcT|oJs>xZNS zhlL0W%i5=9+lPJm6$=D0CRYct-KR=aRrNJM_yI>oZhi{qRAy!Q4`Qal-{PayhbW+R zC6oU%I|YC?{aDsn0@*jdfSY+K&yIY)Jo(&vUIt|TZTCg2;jH3)a&V3jgX8bT%e*S} z8rhOjL5Cv;eRjPOX?)(kJx+iJ)(De@4D#ra<$**Or)(F%<-~NMqE^=+S&noGcf8rA zZrJ6su6tY-Cm`0CzNg;^hh?!`v`DtBl65S9qsiI~M6#nBdl28z!3w0pb+_VNqm^KT zJ_l-uiW~%QF3s*?9&d3o-ODe}t| z-uEX=pi6m=%pVPGRWeAHTAOKfmWtg{hXB6Ny6k54U=!EoKW7(fx||}DN>rjFFBkC< zg=){e>LslL>V8Vo^d#Eu@~ko>cgeQ$!+z!rFtk6ME|E-vf+J(=z;vUUiVFj27aGCI z?oeX#a4Lk??!Qm$ARA&ehg|D#%Zf2^wqXnQ?{7L8pDO$#;cihzS*A&`yonEm-v&T2 z#4<|wV+$Rf(gzX?IVNuvTZ>Y*dS#9`STptIgvuG0pb%b@iP>gNARK;}?v+Dx6v}cT zv^hiFTu8ebF0r;Ak5eM0(eG@cI1NptA2I`%H59fR8EG@MUAKR`r(gG25QKuzC-xP_ zX7bRwBY(nxN9(-ZIb`NZc)>>7B?6e|VK%Mu>8l{RIZj8{?GJPJ%;@?}x!jwTE5|$8 zhZsEX-ASxU0L3@7NoF_GNUhm`Jd5tJ?CGCW<`+zrPi@b<*QJeUcVpp!SGVU>rAxN^ z-*#Zs`V}AOadm${;PJ0?LUwH|q+~pEn>4=kHI;=`b;6 z^7>9|hRAgk{wSSDw=O=aKiv*!%Wp^GM*AK{np0~gFU&9J)oUrVhI+N1-Wgf$OoTxW z7V{8tWE1y#t~SPBF-)xx@Yik!9{=%+Z;!0LmyV?|;@U-#y2IU~w!|1cKd6=E`Gde! z1iRqFWgJ-^i|Qbm3{21%mu!|AtG$JWJW zyq{pqfvuv{N?ExJy$}w@vGwa4mC<=cuJSYh7_(*Hn9Fr-%Y;(l% zE`K)-^8K`cO2Ql8ZjzwiKMgRrYI6#8fEN<)Mr35xCs$tiRb|iUiAe=ts%qj#xU~81`&2{LNqU&7wK(W7c2ZnZ@#3Tw@jw-%OV6jnS}_o6mWC3Whu^8bOsP* z=@KPkKD61?x-h`$HyqywU+v4EUI#SYB2$AeZqoZ!fq(gUi`S5`qhoN&d!&H zpS=@Sbw`XXXU}?@xhKQZ@T&?b>O+RsPipZr4=6wBe#XZG0Xf(iWxU+aZ9i6w9ej?i z2E4uvo+-$B1{qdmaL$!qcBGg*+at6H|;#t7e^jAsj*x2C=2aK+eFD+&?)gD4gZ7N z;z6e$6TwMRg!`3iMG&^sA0>Qc8+_%J#HAZrZtDbK(oMV`5dZmLla_1$`Fz2`>{`u6 z;*~y%i6vjn%GPi#Yw|{#%-(;8J$jUkVb-YB3`i*SVr#5i&kJ-%2hb=^IXYs?`V=GG zMiv?m(FzW+ZlUZ)lEVSUfoTM%g9V6EFR7aglXK$zTqF7Af;hianoiB1xhF8ZJMF^3 zyDNaF*UGdl#8oK+?cioar9XU^YHSRRN~v6Np|-7N18)lD>)Eyc^kCi=awSlbV;%<` zv~!6ZfSZlxTqD67bST^WW=QdA3w{??NX=uFP@;u6{3mM-sGo>)IzddP(7%~Rd7Un=ltzI~mQ&mlQ9BC~TJI;Pt zjdqGf%TaL>92DEn2mc%?)29wi!mt&D7NZe)YF_8PuZ z+R+sw)PxIpPH&idn9Cj_#x29~{UdNIrvaclX4@$uq^EN03Ha)GB>Eg|Wp-D}txQh~ zxbyVact}!eFvTLi{iXC-DW9G$7uX&DxkKUO&~(q6XnrukThs3;?evegaT@zpzNEG|x*Z57M-}It|72A1it+7!R?sY36@X_!)PvceVQ|8B zXo@pmJ8Os%R7?5<%XwYG_aHcnWHTxEBqoiBC@)Q>7X<3|G^AIcYns;LruojWGP~GI zxgorf`=J4#ZS%@Vd^8IQ8FK7yIoWIkxjDDOGWV~>tnE{x9m=kS{sB;5+w5@}KcU}} zKc2lQBiM07pmbx&Mo=)ifL4DT)0)!kyv5aV-)yc3(^! zvmp-5%Q#sTXDha~Q~^phHA@$lra|wq2{wzj!}gXVBOo?UEr_?osHlG$lsdGVsQO`%gDn#5sRE*#Ys;1aioHejOB)_DLJL`9eo03Oi}gd!AA9 z@y~-LGt~`uWc&mk%B144z3roIaunf=cLOuj%VvkfRC<6E0T{#OhqU9CQWnK*wXQ}h zTAah`D&$WmPB|^n!xm^g5l+*$!Q=QNFrjx-Tw0R# z^u~3WI)#@jLExjU+NMQwiN$s_39mAc9IrzwsWXL|-bi(I!zIvZL=BrBj*y%4539Ytso4fK;>>EeIwsg&K0y`9IoD^2at z&+{RyfOx_m4x#qf;FZTxisP_j<>oGKq!`J>1iEN8fD{!KtxZGS5!vrm+aYn1sroqxk7LnCNtIAO1KG-_uc)zJaieEh~7d`A0 zAP{mwmrN%tG&)u}E0JzAZ&?Fa*onU^H7W>FC(+(xCjblTVdmV2QRdHCIBC$R#H4#c^qq46{b zICmW~4Qr{d#g+^RCxR2X%9{gM*pI|flgVg95xUV^`SwBN7rO2HB#d-!uA7rl@DFi{ zfXu80GGTymS7^^|P9ct?>SW2wP>;{haC@+VZaa~)NbH)G{W^}@Vpon) zLife8O?n#ln)jBb+!7>Xthu0D{kNaeo(Q*hP72=smWG8(hH?Q{sh*W<4&T!ceDq`% zP-Eeswqk~6laInq&_O1ClHIFNpM;|l0_%JWl^&|MrI-@Rq9!FOTKQ?HR09NrcO225 z#@#(U00YOb$_(y~J2{gH3|F=)8*hzk-Eu}=NGQ#&+cfV!U%mJ@ZRYv7zWZnUOJ%`S z-G89eRX%h+a}T=NT)K{HxylClul0>7{X4R~5!4Z6WF$=-ox?Z{0qn`@-1deOfOh~D ztbljSoon@hAh)G9tLA%WS)Xh3F<0ptyt`{G^We)z(@+J)FzU_R(pE!%QsL+aI>fN#L}F@}gi;Enpa_VM1}yC+6FG5yf7x?H8&)yrKL(~7VsJ2!+c zhbGD0wDPl8$;7&q0L|~By*2L+(jNd4G6>8r-(O49{O|fReccHQxmWgr<8@gzqaO7| z+Ai#mV8O+f#9wd73oYjj3aW@9#(K#+%KybdK=z_-A8m%zW6$^Q-zvs=1HFTviKJLH zpP<3c|K@q;KAqAHw8aVZhOPU=hKuz*{k0ynK*`5nCPJOd-$#J%kFD(JRwR@?vdc zzv>=VIjS^@Jn~3v{oO{q0O`_4f(_NeEDOf7Y%cH$5x)19bIdM&vN#V=8+s3GP{|2h z6^S_OlF9|iUwG`RL=;$^y(84)c{FD$8+$P+Q^^ |-XJ8xg~nb9Ba!0(CTWo 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

f#GVJiU^Hl`9f00 zjElILR(*TCbgZ0Ig2Tf+F~jxwbc>C9&5dTK9m`zswy(dIE#59PeVy26+(i?Rovhq^ z_{&zhc!D?&PmEx=BV;ANPeh%sRd@X)RrlU((TX_A~=jF|2j$TkjT{PiCQrE<9jWzUXs0{V3@k!PEuK{%`po@+dbeH_3k#cc_NE(>e=c&#~6Y3Zk{?n2)x&O1^c&L}sgX+rn(Htz8@o zHL@wC_2;{cuvF}Mt9!)|*%5MmpJFj`|K^s_UQ z5#TY>{u7dvYc)ZTZ>Onb>C~3XlGyyWThMgw;i$hSxT3|+^)I}KO4Cp7b{kp82?%HX z#?=S+9}Gg2(bE+2LHg>;S;Vnd+6Q>(#7Xt6kvyqv3aT(vCL6)4D^YKq?eq&1I8KiN ziV~Zs9Wps>(fqD%fKDgZXv;hHM8=-0Sf{um)a^lI}?h8W8?cvdUox@?DPRm;_U=XmfE@|trmAVdfUvyBP z7kNAEQd9~}Owx0Z%=Q$8m9c`T+X@ z{W8|}5$))T6jSXHH7o)dEg_HxwB=m_A8!WJJ*u*C#>F$fN z7nun!2?5bI5Y1$8%x(}LwoLY;6?O}2Exf+hrh-IvhqJPl z{X6lXsz{<&0yM{|`UQz{$wC8PR}PyAxf}e5>(|Zh{HTJba#N?Rs2TpqSbEL_f|r;C zj7!gSQAj%@?&Y4Z)!wsbyeod*f3c2e6xYxf^_SBpfCmE<3|_g_%e$;s_s@V_`? zM@y%FyZ`cxB}nuHxVXeQc(|n`I9MgP#o5Jp**V1}CAdYo#ktsdrMS3Rg-HJYR}7H< zFXPzQ|C@0{i}Lm$7tE2H&kl!U#qD7HCC{qL%F@e?3au)Q`}e{nTNSz0NQsMT3C{@Q z-MP@AD~i+=ZJA7xPBevxVp7xo@!{^Y126Ld_kH}RuUK*ZvKqN4JmvuDIXx73a7&&w~be6Kl*+DKBsg%R3P)* zIMY&S$U1G1Hq*|Saf**eHW|whtU8>>K2U50R#F)eYfryN&=D@Bae@cbN6G`AoDlLw zbrz9ddl@Bb=+}rt6Z`>b0*8kN1PS7t?z*=|V$76}Q+Ce75=I zC!F`vA;qo3^5g!dz}8fgXA{gC)K3$XW|;%e1_j5^?pf%|dK5lmVZy-RSvZ4P#vTFJ zJ!xr&bm9}J0GDeP!tW+GRnqq3u+ErUKc0a|yX6s4@9Y>)aH=6E!}{-LZ%G%03~ITC zl5e^6aVR!gh1C)|jIC;Wo|vm(3HFB*smkdesfI(LeT-_w$ZiblBPW|x8#yHd01RF?H4yZrzY zHHKSreO}B%Nd*wqaa1qP$w@sT+lsR&IOHBM@DoI5Y z(z0>L5H~7&MMKh&@g8!w6H4nP@=5<%MKxz>`SlBx#BiB__7Z)6$+xOkiuSjq$^bY^ zglhZ*V^Wi){9>{iO_%Ky#M6}Gu(W4pkbF2|L?DXFXb8h-7~yEBz-ai7V(9D8NZiQI aPlmdx$8=G34ib1CZZ>#IN=YRt`2PX0&f(_( From 3626496c7c6a699d40bba8c7cd2c08a2f2245716 Mon Sep 17 00:00:00 2001 From: Oliver Henrich Date: Wed, 22 Feb 2017 20:06:49 +0000 Subject: [PATCH 2/3] Corrected comment in 3' to 5' directionality check --- src/USER-CGDNA/mf_oxdna.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/USER-CGDNA/mf_oxdna.h b/src/USER-CGDNA/mf_oxdna.h index b0d3bbe0d3..051cea83f8 100644 --- a/src/USER-CGDNA/mf_oxdna.h +++ b/src/USER-CGDNA/mf_oxdna.h @@ -253,8 +253,8 @@ inline double MFOxdna::DF5(double x, double a, double x_ast, } /* ---------------------------------------------------------------------- - test for directionality by projecting base normal n onto delr, - returns 1 if nucleotide a to nucleotide b is 3' to 5', otherwise -1 + test for directionality by projecting base normal n onto delr = a - b, + returns 1 if nucleotide b to nucleotide a is 3' to 5', otherwise -1 ------------------------------------------------------------------------- */ inline double MFOxdna::is_3pto5p(const double * delr, const double * n) { From 23b82879333398e96331b8ed8ef17b97d0e63e08 Mon Sep 17 00:00:00 2001 From: Oliver Henrich Date: Tue, 14 Mar 2017 11:36:44 +0000 Subject: [PATCH 3/3] Updated documentation and simple setup tool --- doc/src/PDF/USER-CGDNA-overview.pdf | Bin 3429483 -> 3429423 bytes examples/USER/cgdna/util/generate.py | 630 ++++++++++++++++++ .../{generate_input.py => generate_simple.py} | 18 +- examples/USER/cgdna/util/sequence.txt | 7 +- examples/USER/cgdna/util/sequence_simple.txt | 4 + 5 files changed, 646 insertions(+), 13 deletions(-) create mode 100644 examples/USER/cgdna/util/generate.py rename examples/USER/cgdna/util/{generate_input.py => generate_simple.py} (96%) create mode 100644 examples/USER/cgdna/util/sequence_simple.txt diff --git a/doc/src/PDF/USER-CGDNA-overview.pdf b/doc/src/PDF/USER-CGDNA-overview.pdf index c86943541b51786da393397a979cacd6163c8969..b0d257adafdb81bad8335a44c0d30413515d418b 100644 GIT binary patch delta 6208 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 z�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 sys.stderr, "numpy not found. Exiting." + sys.exit(1) + +""" +Check that the required arguments (box offset and size in simulation units +and the sequence file were provided +""" +try: + box_offset = float(sys.argv[1]) + box_length = float(sys.argv[2]) + infile = sys.argv[3] +except: + print >> sys.stderr, "Usage: %s <%s> <%s> <%s>" % (sys.argv[0], \ + "box offset", "box length", "file with sequences") + sys.exit(1) +box = np.array ([box_length, box_length, box_length]) + +""" +Try to open the file and fail gracefully if file cannot be opened +""" +try: + inp = open (infile, 'r') + inp.close() +except: + print >> sys.stderr, "Could not open file '%s' for reading. \ + Aborting." % infile + sys.exit(2) + +# return parts of a string +def partition(s, d): + if d in s: + sp = s.split(d, 1) + return sp[0], d, sp[1] + else: + return s, "", "" + +""" +Define the model constants +""" +# set model constants +PI = np.pi +POS_BASE = 0.4 +POS_BACK = -0.4 +EXCL_RC1 = 0.711879214356 +EXCL_RC2 = 0.335388426126 +EXCL_RC3 = 0.52329943261 + +""" +Define auxillary variables for the construction of a helix +""" +# center of the double strand +CM_CENTER_DS = POS_BASE + 0.2 + +# ideal distance between base sites of two nucleotides +# which are to be base paired in a duplex +BASE_BASE = 0.3897628551303122 + +# cutoff distance for overlap check +RC2 = 16 + +# squares of the excluded volume distances for overlap check +RC2_BACK = EXCL_RC1**2 +RC2_BASE = EXCL_RC2**2 +RC2_BACK_BASE = EXCL_RC3**2 + +# enumeration to translate from letters to numbers and vice versa +number_to_base = {1 : 'A', 2 : 'C', 3 : 'G', 4 : 'T'} +base_to_number = {'A' : 1, 'a' : 1, 'C' : 2, 'c' : 2, + 'G' : 3, 'g' : 3, 'T' : 4, 't' : 4} + +# auxillary arrays +positions = [] +a1s = [] +a3s = [] +quaternions = [] + +newpositions = [] +newa1s = [] +newa3s = [] + +basetype = [] +strandnum = [] + +bonds = [] + +""" +Convert local body frame to quaternion DOF +""" +def exyz_to_quat (mya1, mya3): + + mya2 = np.cross(mya3, mya1) + myquat = [1,0,0,0] + + q0sq = 0.25 * (mya1[0] + mya2[1] + mya3[2] + 1.0) + q1sq = q0sq - 0.5 * (mya2[1] + mya3[2]) + q2sq = q0sq - 0.5 * (mya1[0] + mya3[2]) + q3sq = q0sq - 0.5 * (mya1[0] + mya2[1]) + + # some component must be greater than 1/4 since they sum to 1 + # compute other components from it + + if q0sq >= 0.25: + myquat[0] = np.sqrt(q0sq) + myquat[1] = (mya2[2] - mya3[1]) / (4.0*myquat[0]) + myquat[2] = (mya3[0] - mya1[2]) / (4.0*myquat[0]) + myquat[3] = (mya1[1] - mya2[0]) / (4.0*myquat[0]) + elif q1sq >= 0.25: + myquat[1] = np.sqrt(q1sq) + myquat[0] = (mya2[2] - mya3[1]) / (4.0*myquat[1]) + myquat[2] = (mya2[0] + mya1[1]) / (4.0*myquat[1]) + myquat[3] = (mya1[2] + mya3[0]) / (4.0*myquat[1]) + elif q2sq >= 0.25: + myquat[2] = np.sqrt(q2sq) + myquat[0] = (mya3[0] - mya1[2]) / (4.0*myquat[2]) + myquat[1] = (mya2[0] + mya1[1]) / (4.0*myquat[2]) + myquat[3] = (mya3[1] + mya2[2]) / (4.0*myquat[2]) + elif q3sq >= 0.25: + myquat[3] = np.sqrt(q3sq) + myquat[0] = (mya1[1] - mya2[0]) / (4.0*myquat[3]) + myquat[1] = (mya3[0] + mya1[2]) / (4.0*myquat[3]) + myquat[2] = (mya3[1] + mya2[2]) / (4.0*myquat[3]) + + norm = 1.0/np.sqrt(myquat[0]*myquat[0] + myquat[1]*myquat[1] + \ + myquat[2]*myquat[2] + myquat[3]*myquat[3]) + myquat[0] *= norm + myquat[1] *= norm + myquat[2] *= norm + myquat[3] *= norm + + return np.array([myquat[0],myquat[1],myquat[2],myquat[3]]) + +""" +Adds a strand to the system by appending it to the array of previous strands +""" +def add_strands (mynewpositions, mynewa1s, mynewa3s): + overlap = False + + # This is a simple check for each of the particles where for previously + # placed particles i we check whether it overlaps with any of the + # newly created particles j + + print >> sys.stdout, "## Checking for overlaps" + + for i in xrange(len(positions)): + + p = positions[i] + pa1 = a1s[i] + + for j in xrange (len(mynewpositions)): + + q = mynewpositions[j] + qa1 = mynewa1s[j] + + # skip particles that are anyway too far away + dr = p - q + dr -= box * np.rint (dr / box) + if np.dot(dr, dr) > RC2: + continue + + # base site and backbone site of the two particles + p_pos_back = p + pa1 * POS_BACK + p_pos_base = p + pa1 * POS_BASE + q_pos_back = q + qa1 * POS_BACK + q_pos_base = q + qa1 * POS_BASE + + # check for no overlap between the two backbone sites + dr = p_pos_back - q_pos_back + dr -= box * np.rint (dr / box) + if np.dot(dr, dr) < RC2_BACK: + overlap = True + + # check for no overlap between the two base sites + dr = p_pos_base - q_pos_base + dr -= box * np.rint (dr / box) + if np.dot(dr, dr) < RC2_BASE: + overlap = True + + # check for no overlap between backbone site of particle p + # with base site of particle q + dr = p_pos_back - q_pos_base + dr -= box * np.rint (dr / box) + if np.dot(dr, dr) < RC2_BACK_BASE: + overlap = True + + # check for no overlap between base site of particle p and + # backbone site of particle q + dr = p_pos_base - q_pos_back + dr -= box * np.rint (dr / box) + if np.dot(dr, dr) < RC2_BACK_BASE: + overlap = True + + # exit if there is an overlap + if overlap: + return False + + # append to the existing list if no overlap is found + if not overlap: + + for p in mynewpositions: + positions.append(p) + for p in mynewa1s: + a1s.append (p) + for p in mynewa3s: + a3s.append (p) + # calculate quaternion from local body frame and append + for ia in xrange(len(mynewpositions)): + mynewquaternions = exyz_to_quat(mynewa1s[ia],mynewa3s[ia]) + quaternions.append(mynewquaternions) + + return True + + +""" +Returns the rotation matrix defined by an axis and angle +""" +def get_rotation_matrix(axis, anglest): + # The argument anglest can be either an angle in radiants + # (accepted types are float, int or np.float64 or np.float64) + # or a tuple [angle, units] where angle is a number and + # units is a string. It tells the routine whether to use degrees, + # radiants (the default) or base pairs turns. + if not isinstance (anglest, (np.float64, np.float32, float, int)): + if len(anglest) > 1: + if anglest[1] in ["degrees", "deg", "o"]: + #angle = np.deg2rad (anglest[0]) + angle = (np.pi / 180.) * (anglest[0]) + elif anglest[1] in ["bp"]: + angle = int(anglest[0]) * (np.pi / 180.) * (35.9) + else: + angle = float(anglest[0]) + else: + angle = float(anglest[0]) + else: + angle = float(anglest) # in degrees (?) + + axis = np.array(axis) + axis /= np.sqrt(np.dot(axis, axis)) + + ct = np.cos(angle) + st = np.sin(angle) + olc = 1. - ct + x, y, z = axis + + return np.array([[olc*x*x+ct, olc*x*y-st*z, olc*x*z+st*y], + [olc*x*y+st*z, olc*y*y+ct, olc*y*z-st*x], + [olc*x*z-st*y, olc*y*z+st*x, olc*z*z+ct]]) + +""" +Generates the position and orientation vectors of a +(single or double) strand from a sequence string +""" +def generate_strand(bp, sequence=None, start_pos=np.array([0, 0, 0]), \ + dir=np.array([0, 0, 1]), perp=False, double=True, rot=0.): + # generate empty arrays + mynewpositions, mynewa1s, mynewa3s = [], [], [] + + # cast the provided start_pos array into a numpy array + start_pos = np.array(start_pos, dtype=float) + + # overall direction of the helix + dir = np.array(dir, dtype=float) + if sequence == None: + sequence = np.random.randint(1, 5, bp) + + # the elseif here is most likely redundant + elif len(sequence) != bp: + n = bp - len(sequence) + sequence += np.random.randint(1, 5, n) + print >> sys.stderr, "sequence is too short, adding %d random bases" % n + + # normalize direction + dir_norm = np.sqrt(np.dot(dir,dir)) + if dir_norm < 1e-10: + print >> sys.stderr, "direction must be a valid vector, \ + defaulting to (0, 0, 1)" + dir = np.array([0, 0, 1]) + else: dir /= dir_norm + + # find a vector orthogonal to dir to act as helix direction, + # if not provided switch off random orientation + if perp is None or perp is False: + v1 = np.random.random_sample(3) + v1 -= dir * (np.dot(dir, v1)) + v1 /= np.sqrt(sum(v1*v1)) + else: + v1 = perp; + + # generate rotational matrix representing the overall rotation of the helix + R0 = get_rotation_matrix(dir, rot) + + # rotation matrix corresponding to one step along the helix + R = get_rotation_matrix(dir, [1, "bp"]) + + # set the vector a1 (backbone to base) to v1 + a1 = v1 + + # apply the global rotation to a1 + a1 = np.dot(R0, a1) + + # set the position of the fist backbone site to start_pos + rb = np.array(start_pos) + + # set a3 to the direction of the helix + a3 = dir + for i in range(bp): + # work out the position of the centre of mass of the nucleotide + rcdm = rb - CM_CENTER_DS * a1 + + # append to newpositions + mynewpositions.append(rcdm) + mynewa1s.append(a1) + mynewa3s.append(a3) + + # if we are not at the end of the helix, we work out a1 and rb for the + # next nucleotide along the helix + if i != bp - 1: + a1 = np.dot(R, a1) + rb += a3 * BASE_BASE + + # if we are working on a double strand, we do a cycle similar + # to the previous one but backwards + if double == True: + a1 = -a1 + a3 = -dir + R = R.transpose() + for i in range(bp): + rcdm = rb - CM_CENTER_DS * a1 + mynewpositions.append (rcdm) + mynewa1s.append (a1) + mynewa3s.append (a3) + a1 = np.dot(R, a1) + rb += a3 * BASE_BASE + + assert (len (mynewpositions) > 0) + + return [mynewpositions, mynewa1s, mynewa3s] + + +""" +Main function for this script. +Reads a text file with the following format: +- Each line contains the sequence for a single strand (A,C,G,T) +- Lines beginning with the keyword 'DOUBLE' produce double-stranded DNA + +Ex: Two ssDNA (single stranded DNA) +ATATATA +GCGCGCG + +Ex: Two strands, one double stranded, the other single stranded. +DOUBLE AGGGCT +CCTGTA + +""" + +def read_strands(filename): + try: + infile = open (filename) + except: + print >> sys.stderr, "Could not open file '%s'. Aborting." % filename + sys.exit(2) + + # This block works out the number of nucleotides and strands by reading + # the number of non-empty lines in the input file and the number of letters, + # taking the possible DOUBLE keyword into account. + nstrands, nnucl, nbonds = 0, 0, 0 + lines = infile.readlines() + for line in lines: + line = line.upper().strip() + if len(line) == 0: + continue + if line[:6] == 'DOUBLE': + line = line.split()[1] + length = len(line) + print >> sys.stdout, "## Found duplex of %i base pairs" % length + nnucl += 2*length + nstrands += 2 + nbonds += (2*length-2) + else: + line = line.split()[0] + length = len(line) + print >> sys.stdout, \ + "## Found single strand of %i bases" % length + nnucl += length + nstrands += 1 + nbonds += length-1 + # rewind the sequence input file + infile.seek(0) + + print >> sys.stdout, "## nstrands, nnucl = ", nstrands, nnucl + + # generate the data file in LAMMPS format + try: + out = open ("data.oxdna", "w") + except: + print >> sys.stderr, "Could not open data file for writing. Aborting." + sys.exit(2) + + lines = infile.readlines() + nlines = len(lines) + i = 1 + myns = 0 + noffset = 1 + + for line in lines: + line = line.upper().strip() + + # skip empty lines + if len(line) == 0: + i += 1 + continue + + # block for duplexes: last argument of the generate function + # is set to 'True' + if line[:6] == 'DOUBLE': + line = line.split()[1] + length = len(line) + seq = [(base_to_number[x]) for x in line] + + myns += 1 + for b in xrange(length): + basetype.append(seq[b]) + strandnum.append(myns) + + for b in xrange(length-1): + bondpair = [noffset + b, noffset + b + 1] + bonds.append(bondpair) + noffset += length + + # create the sequence of the second strand as made of + # complementary bases + seq2 = [5-s for s in seq] + seq2.reverse() + + myns += 1 + for b in xrange(length): + basetype.append(seq2[b]) + strandnum.append(myns) + + for b in xrange(length-1): + bondpair = [noffset + b, noffset + b + 1] + bonds.append(bondpair) + noffset += length + + print >> sys.stdout, "## Created duplex of %i bases" % (2*length) + + # generate random position of the first nucleotide + cdm = box_offset + np.random.random_sample(3) * box + + # generate the random direction of the helix + axis = np.random.random_sample(3) + axis /= np.sqrt(np.dot(axis, axis)) + + # use the generate function defined above to create + # the position and orientation vector of the strand + newpositions, newa1s, newa3s = generate_strand(len(line), \ + sequence=seq, dir=axis, start_pos=cdm, double=True) + + # generate a new position for the strand until it does not overlap + # with anything already present + start = timer() + while not add_strands(newpositions, newa1s, newa3s): + cdm = box_offset + np.random.random_sample(3) * box + axis = np.random.random_sample(3) + axis /= np.sqrt(np.dot(axis, axis)) + newpositions, newa1s, newa3s = generate_strand(len(line), \ + sequence=seq, dir=axis, start_pos=cdm, double=True) + print >> sys.stdout, "## Trying %i" % i + end = timer() + print >> sys.stdout, "## Added duplex of %i bases (line %i/%i) in %.2fs, now at %i/%i" % \ + (2*length, i, nlines, end-start, len(positions), nnucl) + + # block for single strands: last argument of the generate function + # is set to 'False' + else: + length = len(line) + seq = [(base_to_number[x]) for x in line] + + myns += 1 + for b in xrange(length): + basetype.append(seq[b]) + strandnum.append(myns) + + for b in xrange(length-1): + bondpair = [noffset + b, noffset + b + 1] + bonds.append(bondpair) + noffset += length + + # generate random position of the first nucleotide + cdm = box_offset + np.random.random_sample(3) * box + + # generate the random direction of the helix + axis = np.random.random_sample(3) + axis /= np.sqrt(np.dot(axis, axis)) + + print >> sys.stdout, \ + "## Created single strand of %i bases" % length + + newpositions, newa1s, newa3s = generate_strand(length, \ + sequence=seq, dir=axis, start_pos=cdm, double=False) + start = timer() + while not add_strands(newpositions, newa1s, newa3s): + cdm = box_offset + np.random.random_sample(3) * box + axis = np.random.random_sample(3) + axis /= np.sqrt(np.dot(axis, axis)) + newpositions, newa1s, newa3s = generate_strand(length, \ + sequence=seq, dir=axis, start_pos=cdm, double=False) + print >> sys.stdout, "## Trying %i" % (i) + end = timer() + print >> sys.stdout, "## Added single strand of %i bases (line %i/%i) in %.2fs, now at %i/%i" % \ + (length, i, nlines, end-start,len(positions), nnucl) + + i += 1 + + # sanity check + if not len(positions) == nnucl: + print len(positions), nnucl + raise AssertionError + + out.write('# LAMMPS data file\n') + out.write('%d atoms\n' % nnucl) + out.write('%d ellipsoids\n' % nnucl) + out.write('%d bonds\n' % nbonds) + out.write('\n') + out.write('4 atom types\n') + out.write('1 bond types\n') + out.write('\n') + out.write('# System size\n') + out.write('%f %f xlo xhi\n' % (box_offset,box_offset+box_length)) + out.write('%f %f ylo yhi\n' % (box_offset,box_offset+box_length)) + out.write('%f %f zlo zhi\n' % (box_offset,box_offset+box_length)) + + out.write('\n') + out.write('Masses\n') + out.write('\n') + out.write('1 3.1575\n') + out.write('2 3.1575\n') + out.write('3 3.1575\n') + out.write('4 3.1575\n') + + # for each nucleotide print a line under the headers + # Atoms, Velocities, Ellipsoids and Bonds + out.write('\n') + out.write(\ + '# Atom-ID, type, position, molecule-ID, ellipsoid flag, density\n') + out.write('Atoms\n') + out.write('\n') + + for i in xrange(nnucl): + out.write('%d %d %22.15le %22.15le %22.15le %d 1 1\n' \ + % (i+1, basetype[i], \ + positions[i][0], positions[i][1], positions[i][2], \ + strandnum[i])) + + out.write('\n') + out.write('# Atom-ID, translational, rotational velocity\n') + out.write('Velocities\n') + out.write('\n') + + for i in xrange(nnucl): + out.write("%d %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le\n" \ + % (i+1,0.0,0.0,0.0,0.0,0.0,0.0)) + + out.write('\n') + out.write('# Atom-ID, shape, quaternion\n') + out.write('Ellipsoids\n') + out.write('\n') + + for i in xrange(nnucl): + out.write(\ + "%d %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le %22.15le\n" \ + % (i+1,1.1739845031423408,1.1739845031423408,1.1739845031423408, \ + quaternions[i][0],quaternions[i][1], quaternions[i][2],quaternions[i][3])) + + out.write('\n') + out.write('# Bond topology\n') + out.write('Bonds\n') + out.write('\n') + + for i in xrange(nbonds): + out.write("%d %d %d %d\n" % (i+1,1,bonds[i][0],bonds[i][1])) + + out.close() + + print >> sys.stdout, "## Wrote data to 'data.oxdna'" + print >> sys.stdout, "## DONE" + +# call the above main() function, which executes the program +read_strands (infile) + +end_time=timer() +runtime = end_time-start_time +hours = runtime/3600 +minutes = (runtime-np.rint(hours)*3600)/60 +seconds = (runtime-np.rint(hours)*3600-np.rint(minutes)*60)%60 +print >> sys.stdout, "## Total runtime %ih:%im:%.2fs" % (hours,minutes,seconds) diff --git a/examples/USER/cgdna/util/generate_input.py b/examples/USER/cgdna/util/generate_simple.py similarity index 96% rename from examples/USER/cgdna/util/generate_input.py rename to examples/USER/cgdna/util/generate_simple.py index 25cfedaae2..33cf1ee7f5 100644 --- a/examples/USER/cgdna/util/generate_input.py +++ b/examples/USER/cgdna/util/generate_simple.py @@ -29,7 +29,7 @@ def single(): strandstart=len(nucleotide)+1 - for letter in strand[2]: + for letter in strand[1]: temp=[] temp.append(nt2num[letter]) @@ -58,7 +58,7 @@ def single_helix(): strand = inp[1].split(':') com_start=strand[0].split(',') - twist=float(strand[1]) + twist=0.6 posx = float(com_start[0]) posy = float(com_start[1]) @@ -79,7 +79,7 @@ def single_helix(): qrot2=0 qrot3=math.sin(0.5*twist) - for letter in strand[2]: + for letter in strand[1]: temp=[] temp.append(nt2num[letter]) @@ -114,7 +114,7 @@ def duplex(): strand = inp[1].split(':') com_start=strand[0].split(',') - twist=float(strand[1]) + twist=0.6 compstrand=[] comptopo=[] @@ -145,7 +145,7 @@ def duplex(): qrot2=0 qrot3=math.sin(0.5*twist) - for letter in strand[2]: + for letter in strand[1]: temp1=[] temp2=[] @@ -189,7 +189,7 @@ def duplex(): if (len(nucleotide)+1 > strandstart): topology.append([1,len(nucleotide),len(nucleotide)+1]) - comptopo.append([1,len(nucleotide)+len(strand[2]),len(nucleotide)+len(strand[2])+1]) + comptopo.append([1,len(nucleotide)+len(strand[1]),len(nucleotide)+len(strand[1])+1]) nucleotide.append(temp1) compstrand.append(temp2) @@ -208,7 +208,7 @@ def duplex_array(): strand = inp[1].split(':') number=strand[0].split(',') posz1_0 = float(strand[1]) - twist=float(strand[2]) + twist=0.6 nx = int(number[0]) ny = int(number[1]) @@ -249,7 +249,7 @@ def duplex_array(): qrot2=0 qrot3=math.sin(0.5*twist) - for letter in strand[3]: + for letter in strand[2]: temp1=[] temp2=[] @@ -293,7 +293,7 @@ def duplex_array(): if (len(nucleotide)+1 > strandstart): topology.append([1,len(nucleotide),len(nucleotide)+1]) - comptopo.append([1,len(nucleotide)+len(strand[3]),len(nucleotide)+len(strand[3])+1]) + comptopo.append([1,len(nucleotide)+len(strand[2]),len(nucleotide)+len(strand[2])+1]) nucleotide.append(temp1) compstrand.append(temp2) diff --git a/examples/USER/cgdna/util/sequence.txt b/examples/USER/cgdna/util/sequence.txt index fff469c8be..8f34319b82 100644 --- a/examples/USER/cgdna/util/sequence.txt +++ b/examples/USER/cgdna/util/sequence.txt @@ -1,4 +1,3 @@ -single 0,0,0:0.6:AAAAA -single_helix 0,0,0:0.6:AAAAA -duplex 0,0,0:0.6:AAAAA -duplex_array 10,10:-112.0:0.6:AAAAA +DOUBLE ACGTA + +ACGTA diff --git a/examples/USER/cgdna/util/sequence_simple.txt b/examples/USER/cgdna/util/sequence_simple.txt new file mode 100644 index 0000000000..81baac8470 --- /dev/null +++ b/examples/USER/cgdna/util/sequence_simple.txt @@ -0,0 +1,4 @@ +single 0,0,0:AAAAA +single_helix 0,0,0:AAAAA +duplex 0,0,0:AAAAA +duplex_array 10,10:-112.0:AAAAA